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。
问题似乎出现在 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
]
似乎不太可能出现问题,因为“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
},
)
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 视图按预期显示。