超链接导致 404 错误消息,没有 Post 与给定查询匹配,期望导致 `views.PostList.as_view()`

问题描述 投票:0回答:1

期望index.html中的超链接会导致
views.PostList.as_view()

超链接位于 templates/base.html 第 46 行:

<a class="nav-link" href="{% url 'questions' %}">Top Questions</a>

按预期导致

http://localhost:8000/questions/
,但出现此错误消息:

Page not found (404)
No Post matches the given query.
Request Method: GET
Request URL:    http://localhost:8000/questions/
Raised by:  blog.views.PostDetail
Using the URLconf defined in classroommatrix.urls, Django tried these URL patterns, in this order:

admin/
index/ [name='index']
<slug:slug>/ [name='post_detail']
The current path, questions/, matched the last one.

采取的调试步骤

到目前为止,我已经查看了错误消息所示的 urlpatterns 和views.py。

1:查看 urlpatterns

问题似乎出现在 blog/urls.py 中的 urlpatterns 中。错误信息表明

views.PostDetail.as_view()
有问题:

# blog/urls.py (called through classroommatrix/urls.py)

from . import views
from django.urls import path


urlpatterns = [ # url patterns for the blog app here.
    path('index/', views.PostList.as_view(), name='index'), # home page
    path('<slug:slug>/', views.PostDetail.as_view(), name='post_detail'), # post detail page - !!The error message indicates that PostDetail is problematic: 
    path('like/<slug:slug>', views.PostLike.as_view(), name='post_like'), # post like
    path('questions/', views.PostList.as_view(), name='questions'), # questions page
]

2:查看 urlpatterns

似乎不太可能出现问题,因为“PostDetail 类”中没有提及“questions/”。

# blog/views.py

from django.shortcuts import render, get_object_or_404, reverse
from django.views import generic, View
from django.http import HttpResponseRedirect
from .models import Post
from .forms import CommentForm


class PostList(generic.ListView): # this class will list all the posts
    model = Post
    queryset = Post.objects.filter(status=1).order_by("-created_on")
    template_name = "questions.html"
    paginate_by = 6


class PostDetail(View): # this class will show the details of a post. The error message indicates that PostDetail is problematic: 

    def get(self, request, slug, *args, **kwargs):
        queryset = Post.objects.filter(status=1)
        post = get_object_or_404(queryset, slug=slug)
        comments = post.comments.filter(approved=True).order_by("-created_on")
        liked = False
        if post.likes.filter(id=self.request.user.id).exists():
            liked = True

        return render(
            request,
            "post_detail.html",
            {
                "post": post,
                "comments": comments,
                "commented": False,
                "liked": liked,
                "comment_form": CommentForm()
            },
        )
    
    def post(self, request, slug, *args, **kwargs):

        queryset = Post.objects.filter(status=1)
        post = get_object_or_404(queryset, slug=slug)
        comments = post.comments.filter(approved=True).order_by("-created_on")
        liked = False
        if post.likes.filter(id=self.request.user.id).exists():
            liked = True

        comment_form = CommentForm(data=request.POST)
        if comment_form.is_valid():
            comment_form.instance.email = request.user.email
            comment_form.instance.name = request.user.username
            comment = comment_form.save(commit=False)
            comment.post = post
            comment.save()
        else:
            comment_form = CommentForm()

        return render(
            request,
            "post_detail.html",
            {
                "post": post,
                "comments": comments,
                "commented": True,
                "comment_form": comment_form,
                "liked": liked
            },
        )
python django django-urls url-pattern
1个回答
0
投票

Django 按照 urlpatterns 中列出的顺序匹配 URL。如果“slug:slug/”出现在“questions/”之前,它将捕获任何应该转到“questions/”的 URL。因此,最好的做法是确保更具体的路径出现在更一般的 slug 模式之前。

# blog/urls.py 
# (called through classroommatrix/urls.py)

[...]

urlpatterns = [
    path('index/', views.PostList.as_view(), name='index'),
    path('questions/', views.PostList.as_view(), name='questions'), # questions page moved up from 2 lines below.
    path('<slug:slug>/', views.PostDetail.as_view(), name='post_detail'), 
    path('like/<slug:slug>', views.PostLike.as_view(), name='post_like'),
]

像这样重新排序代码后,404 错误消息消失,并且 PostDetail 视图按预期显示。

© www.soinside.com 2019 - 2024. All rights reserved.