注销时找不到页面,知道为什么注销不起作用吗?

Page not found when I log out, any idea why the logging out doesn't work?

使用 django 开发社交应用程序并单击注销不再有效,出于某种原因我得到:找不到页面 (404)

找不到与查询匹配的配置文件 请求方式:GET 请求 URL:http://127.0.0.1:8000/logout 提出者:network.views.

使用 project4.urls 中定义的 URLconf,Django 按以下顺序尝试了这些 URL 模式: 行政/ [姓名='all-profiles-view'] [姓名='profile-view'] 当前路径,注销,匹配上一个。

还有一种简单的方法可以使用户的名字可以从指向他们的个人资料(ProfileDetailView)的任何页面上点击吗? URLs:

from django.urls import path
from django.conf import settings
from django.conf.urls.static import static
from . import views
from .views import (
    posts_of_following_profiles,
    like_unlike_post,
    invites_received_view,
    invite_profiles_list_view,
    send_invitation,
    remove_friends,
    accept_invitation,
    reject_invitation,

    ProfileDetailView,
    PostDeleteView,
    PostUpdateView,
    ProfileListView,
)

urlpatterns = [
    path("", ProfileListView.as_view(), name="all-profiles-view"),
    path("<slug>", ProfileDetailView.as_view(), name="profile-view"),
    path("posts/", views.post_comment_create_view, name="posts"),
    path("posts-follow/", posts_of_following_profiles, name="posts-follow"),
    path("login", views.login_view, name="login"),
    path("logout", views.logout_view, name="logout"),
    path("register", views.register, name="register"),
    path("liked/", like_unlike_post, name="like-post-view"),
    path("<pk>/delete", PostDeleteView.as_view(), name="post-delete"),
    path("<pk>/update", PostUpdateView.as_view(), name="post-update"),
    path("invites/", invites_received_view, name="invites-view"),
    path("send-invite/", send_invitation, name="send-invite"),
    path("remove-friend/", remove_friends, name="remove-friend"),
    path("invites/accept/", accept_invitation, name="accept-invite"),
    path("invites/reject/", reject_invitation, name="reject-invite"),
    path("to-invite/", invite_profiles_list_view, name='invite-profiles-view')

]

urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

观看次数:

from django.contrib.auth import authenticate, login, logout
from django.db import IntegrityError
from django.http import HttpResponse, HttpResponseRedirect
from django.http.response import JsonResponse
from django.shortcuts import render, redirect, resolve_url, get_object_or_404
from django.urls import reverse, reverse_lazy
from django.core import serializers
from django.core.paginator import Paginator
from django.contrib import messages
from django.contrib.auth.models import User
from django.db.models import Q
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin
from itertools import chain


from .models import Relationship, Post, Profile, Like
from django.views.generic import TemplateView, View, UpdateView, DeleteView, ListView, DetailView
from .forms import ProfileModelForm, PostModelForm, CommentModelForm

class ProfileDetailView(LoginRequiredMixin, DetailView):
    model = Profile
    template_name = 'network/profile.html'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        user = User.objects.get(username__iexact=self.request.user)
        profile = Profile.objects.get(user=user)
        rel_r = Relationship.objects.filter(sender=profile)
        rel_s = Relationship.objects.filter(receiver=profile)
        rel_receiver = []
        rel_sender = []
        for item in rel_r:
            rel_receiver.append(item.receiver.user)
        for item in rel_s:
            rel_sender.append(item.sender.user)
        context["rel_receiver"] = rel_receiver
        context["rel_sender"] = rel_sender
        context["posts"] = self.get_object().get_all_authors_posts()
        context["len_posts"] = True if len(self.get_object().get_all_authors_posts()) > 0 else False

        return context



@login_required
def profile_view(request):
    profile = Profile.objects.get(user=request.user)
    form = ProfileModelForm(request.POST or None, request.FILES or None, instance=profile)
    confirm = False

    if request.method == 'POST':
        if form.is_valid():
            form.save()
            confirm = True

    context = {
        'profile': profile,
        'form': form,
        'confirm': confirm,
    }
    return render(request, 'network/profile.html', context)

@login_required
def invites_received_view(request):
    profile = Profile.objects.get(user=request.user)
    qs = Relationship.objects.invitations_received(profile)
    results = list(map(lambda x: x.sender, qs))
    is_empty = False
    if len(results) == 0:
        is_empty = True

    context = {
        'qs':results,
        'is_empty': is_empty,
    }

    return render(request, 'network/invites.html', context)

@login_required
def accept_invitation(request):
    if request.method =='POST':
        pk = request.POST.get('profile_pk')
        sender = Profile.objects.get(pk=pk)
        receiver = Profile.objects.get(user=request.user)
        rel = get_object_or_404(Relationship, sender=sender, receiver=receiver)
        if rel.status == 'send':
            rel.status = 'accepted'
            rel.save()

    return redirect('invites-view')

@login_required
def reject_invitation(request):
    if request.method=="POST":
        pk = request.POST.get('profile_pk')
        receiver = Profile.objects.get(user=request.user)
        sender = Profile.objects.get(pk=pk)
        rel = get_object_or_404(Relationship, sender=sender, receiver=receiver)
        rel.delete()
    return redirect('invites-view')

@login_required
def invite_profiles_list_view(request):
    user = request.user
    qs = Profile.objects.get_all_profiles_to_invite(user)

    context = {'qs': qs}

    return render(request, 'network/to_invite_list.html', context)

@login_required
def profiles_list_view(request):
    user = request.user
    qs = Profile.objects.get_all_profiles(user)

    context = {'qs': qs}

    return render(request, 'network/profile_list.html', context)

class ProfileListView(LoginRequiredMixin, ListView):
    model = Profile
    template_name = 'network/profile_list.html'
    #context_object_name = 'qs'

    def get_queryset(self):
        qs = Profile.objects.get_all_profiles(self.request.user)
        return qs

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        user = User.objects.get(username__iexact=self.request.user)
        profile = Profile.objects.get(user=user)
        rel_r = Relationship.objects.filter(sender=profile)
        rel_s = Relationship.objects.filter(receiver=profile)
        rel_receiver = []
        rel_sender = []
        for item in rel_r:
            rel_receiver.append(item.receiver.user)
        for item in rel_s:
            rel_sender.append(item.sender.user)
        context["rel_receiver"] = rel_receiver
        context["rel_sender"] = rel_sender
        context["is_empty"] = False
        if len(self.get_queryset()) == 0:
            context["is_empty"] = True

        return context

@login_required
def send_invitation(request):
    if request.method == 'POST':
        pk = request.POST.get('profile_pk')
        user = request.user
        sender = Profile.objects.get(user=user)
        receiver = Profile.objects.get(pk=pk)

        rel = Relationship.objects.create(sender=sender, receiver=receiver, status='send')

        return redirect(request.META.get('HTTP_REFERER'))
    return redirect('profile')

@login_required
def remove_friends(request):
    if request.method == 'POST':
        pk = request.POST.get('profile_pk')
        user = request.user
        sender = Profile.objects.get(user=user)
        receiver = Profile.objects.get(pk=pk)

        rel = Relationship.objects.get(
            (Q(sender=sender) & Q(receiver=receiver)) | (Q(sender=receiver) & Q(receiver=sender))
        )
        rel.delete()
        return redirect(request.META.get('HTTP_REFERER'))
    return redirect('profile')

@login_required
def like_unlike_post(request):
    user = request.user
    if request.method == 'POST':
        post_id = request.POST.get('post_id')
        post_obj = Post.objects.get(id=post_id)
        profile = Profile.objects.get(user=user)

        if profile in post_obj.liked.all():
            post_obj.liked.remove(profile)
        else:
            post_obj.liked.add(profile)

        like, created = Like.objects.get_or_create(user=profile, post_id=post_id)

        if not created:
            if like.value=='Like':
                like.value='Unlike'
            else:
                like.value='Like'
        else:
            like.value='Unlike'

            post_obj.save()
            like.save()

        data = {
            'value': like.value,
            'likes': post_obj.liked.all().count()
        }
        return JsonResponse(data, safe=False)
    return redirect('posts')

@login_required
def post_comment_create_view(request):
    qs = Post.objects.all()
    profile = Profile.objects.get(user=request.user)

    #Setting up pagination
    p = Paginator(qs, 5)
    page = request.GET.get('page')
    post_list = p.get_page(page)

    #Post form, comment form
    p_form = PostModelForm()
    c_form = CommentModelForm()
    post_added = False

    profile = Profile.objects.get(user=request.user)

    if 'submit_pForm' in request.POST:
        print(request.POST)
        p_form = PostModelForm(request.POST, request.FILES)
        if p_form.is_valid():
            instance = p_form.save(commit=False)
            instance.author = profile
            instance.save()
            p_form = PostModelForm()
            post_added = True

    if 'submit_cForm' in request.POST:
        c_form = CommentModelForm(request.POST)
        if c_form.is_valid():
            instance = c_form.save(commit=False)
            instance.user = profile
            instance.post = Post.objects.get(id=request.POST.get('post_id'))
            instance.save()
            c_form = CommentModelForm()

    context = {
        'qs': qs,
        'profile': profile,
        'p_form': p_form,
        'c_form': c_form,
        'post_added': post_added,
        'post_list': post_list,
    }

    return render(request, 'network/posts.html', context)

@login_required
def posts_of_following_profiles(request):

    profile = Profile.objects.get(user=request.user)
    users = [user for user in profile.following.all()]
    posts = []
    qs = None

    for u in users:
        p = Profile.objects.get(user=u)
        p_posts = p.post_set.all()
        posts.append(p_posts)

    my_posts = profile.get_my_posts()
    posts.append(my_posts)
    if len(posts) > 0:
            qs = sorted(chain(*posts), reverse=True, key=lambda obj: obj.created)

    #Setting up pagination
    p = Paginator(posts, 5)
    page = request.GET.get('page')
    post_list = p.get_page(page)

    #Post form, comment form
    p_form = PostModelForm()
    c_form = CommentModelForm()
    post_added = False

    if 'submit_pForm' in request.POST:
        print(request.POST)
        p_form = PostModelForm(request.POST, request.FILES)
        if p_form.is_valid():
            instance = p_form.save(commit=False)
            instance.author = profile
            instance.save()
            p_form = PostModelForm()
            post_added = True

    if 'submit_cForm' in request.POST:
        c_form = CommentModelForm(request.POST)
        if c_form.is_valid():
            instance = c_form.save(commit=False)
            instance.user = profile
            instance.post = Post.objects.get(id=request.POST.get('post_id'))
            instance.save()
            c_form = CommentModelForm()

    context = {
        'posts': qs,
        'profile': profile,
        'p_form': p_form,
        'c_form': c_form,
        'post_added': post_added,
        'post_list': post_list,
    }

    return render(request, 'network/followers_posts.html', context)

class PostDeleteView(LoginRequiredMixin, DeleteView):
    model = Post
    template_name = 'network/confirmDelete.html'
    success_url = reverse_lazy('posts')

    def get_object(self, *args, **kwargs):
        pk = self.kwargs.get('pk')
        obj = Post.objects.get(pk=pk)
        if not obj.author.user == self.request.user:
            messages.warning(self.request, 'You need to be the owner of the post in order to delete it!')
        return obj

class PostUpdateView(LoginRequiredMixin, UpdateView):
    form_class = PostModelForm
    model = Post
    template_name = 'network/update.html'
    success_url = reverse_lazy('posts')

    def form_valid(self, form):
        profile = Profile.objects.get(user=self.request.user)
        if form.instance.author == profile:
            return super().form_valid(form)
        else:
            form.add_error(None, "You need to be the owner of the post in order to update it!")
            return super().form_invalid(form)


def login_view(request):
    if request.method == "POST":

        # Attempt to sign user in
        username = request.POST["username"]
        password = request.POST["password"]
        user = authenticate(request, username=username, password=password)

        # Check if authentication successful
        if user is not None:
            login(request, user)
            return HttpResponseRedirect(reverse("index"))
        else:
            return render(request, "network/login.html", {
                "message": "Invalid username and/or password."
            })
    else:
        return render(request, "network/login.html")


def logout_view(request):
    logout(request)
    return HttpResponseRedirect(reverse("index"))


def register(request):
    if request.method == "POST":
        username = request.POST["username"]
        email = request.POST["email"]

        # Ensure password matches confirmation
        password = request.POST["password"]
        confirmation = request.POST["confirmation"]
        if password != confirmation:
            return render(request, "network/register.html", {
                "message": "Passwords must match."
            })

        # Attempt to create new user
        try:
            user = User.objects.create_user(username, email, password)
            user.save()
        except IntegrityError:
            return render(request, "network/register.html", {
                "message": "Username already taken."
            })
        login(request, user)
        return HttpResponseRedirect(reverse("index"))
    else:
        return render(request, "network/register.html")

布局:

{% load static %}

<!DOCTYPE html>
<html lang="en">
    <head>
        <title>{% block title %}Social Network{% endblock %}</title>
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
        <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css">
        <link href="{% static 'network/styles.css' %}" rel="stylesheet">
        <link rel="icon" href="{% static 'network/icon.jpg' %}">
        <link href="https://fonts.googleapis.com/css?family=Archivo+Black&display=swap" rel="stylesheet">
        <link href="https://fonts.googleapis.com/css?family=Archivo:700&display=swap" rel="stylesheet">
        <!-- jquery -->
        {% block scripts %}
        <script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
        <script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.1/dist/js/bootstrap.bundle.min.js"></script>
        <script src="{% static 'network/script.js' %}" defer></script>
        {% endblock scripts %}
    </head>
    <body>

        <nav class="navbar navbar-expand-lg navbar-light bg-light">
            <a class="navbar-brand" href="{% url 'all-profiles-view' %}">Network</a>
            <ul class="navbar-nav mr-auto">
                {% if user.is_authenticated %}
                    <li class="nav-item">
                        <a class="nav-link" href="#"><strong>{{ user.username }}</strong></a>
                    </li>
                {% endif %}
                <li class="nav-item">
                    <a class="nav-link" href="{% url 'posts' %}">All Posts</a>
                </li>
                {% if user.is_authenticated %}
                    <li class="nav-item">
                        <a class="nav-link" href="{% url 'posts-follow' %}">Following</a>
                    </li>
                    <form class="form-inline my-2 my-lg-0">
                        <input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
                        <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
                    </form>
                    <li class="nav-item">
                        <a class="nav-link" href="{% url 'logout' %}">Log Out</a>
                    </li>
                {% else %}
                    <li class="nav-item">
                        <a class="nav-link" href="{% url 'login' %}">Log In</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="{% url 'register' %}">Register</a>
                    </li>
                {% endif %}
                </ul>
            </div>
          </nav>

        <div class="container-fluid mt-3">
            {% block body %}
            {% endblock %}
        </div>
    </body>
</html>

看着你的urlpatterns。在 logout.

之前你有 profile-view
path("<slug>", ProfileDetailView.as_view(), name="profile-view")
.
.
.
path("logout", views.logout_view, name="logout")

并且当您的注销 URL 与 slug 匹配并且您的 ProfileDetailView 被调用时,因为您的 ProfileDetailViewlogout_view 之前被评估。因此,请更改网址的顺序,因为 http://127.0.0.1:8000/ 之后的每个 value 都匹配该模式并将被调用。因此,请重新订购您的 urls.py 并检查。

所以通过查看 urls.py 不会影响将此 ProfileDetailView 放在 urls 的底部。

对于第二部分,点击 username 调用 ProfileDetailView 将您的 html 更改为

    <li class="nav-item">
              <a class="nav-link" href="{% url 'profile-view' user.username %}"><strong>{{ user.username }}</strong>. 
              </a>
    </li>