问题描述
我刚刚使用 django-autoslug 为我的 Post 模型添加了 slug。但是当我尝试创建新帖子时遇到此错误:
Page not found (404)
Request Method: GET
Request URL: http://localhost:8000/post/new/
Raised by: blog.views.PostDetailView
No post found matching the query
发布模型
class Post(models.Model):
title = models.CharField(max_length=100)
author = models.ForeignKey(User,on_delete=models.CASCADE)
slug = AutoSlugField(populate_from='title',null=True)
def save(self,*args,**kwargs):
self.slug = self.slug or slugify(self.title)
super().save(*args,**kwargs)
def get_absolute_url(self):
return reverse('post-detail',kwargs={'slug': self.slug,'author': self.author})
views.py
class PostDetailView(DetailView):
model = Post
def get_queryset(self,**kwargs):
return super().get_queryset(*args,**kwargs).filter(author__username=self.kwargs['author'])
urls.py
urlpatterns = [
path('',views.home,name='blog-home'),path('<str:author>/<slug:slug>/',PostDetailView.as_view(),name='post-detail')
path('post/new/',PostCreateView.as_view(),name='post-create'),path('<str:author>/<slug:slug>/update/',PostUpdateView.as_view(),name='post-update'),path('<str:author>/<slug:slug>/delete/',PostDeleteView.as_view(),name='post-delete'),] + static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
解决方法
如果您请求 /post/new
URL,那么这将匹配 post-detail
视图,因为它可以将 post
与 author
匹配,而 new
与slug
。
您应该重新排列 url 模式,使其首先匹配 post-create
视图:
urlpatterns = [
path('',views.home,name='blog-home'),path('post/new/',PostCreateView.as_view(),name='post-create'),path('<str:author>/<slug:slug>/',PostDetailView.as_view(),name='post-detail')
path('<str:author>/<slug:slug>/update/',PostUpdateView.as_view(),name='post-update'),path('<str:author>/<slug:slug>/delete/',PostDeleteView.as_view(),name='post-delete'),] + static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
首先指定 post-create
视图,如果用户访问 /post/new/
,它将因此触发 post-create
视图。
因此,这也意味着名为 post
的作者不能写名为 new
的文章,因为它不会触发 post-detail
视图。
我有点作弊,但我放弃了 slug,我将我的网站转到 tachlis.herokuapp.com/item_id/title_slug(例如 http://tachlis.herokuapp.com/552/curb-your-veganism),然后我的 urls.py 是 'int:pk /str:pkv/',我使用物品 ID ('pk') 来获取正确的物品,而不是 slug。