我正在使用Django为自己开发一个网站和博客。我使用的是Python 3.8和Django 3.0,并且在尝试在URL中包含帖子创建日期时遇到了很多麻烦。虽然我终于能够让我的 URL 看起来像:">mywebsite.com/blog/2020/mm/dd/.html",但如果我更改日期的任何部分,我不会得到 404。
例如,如果我手动将 URL 更改为:mywebsite.com/blog/2021/mm/dd/.html,网页仍然加载而不会显示错误。有人可以帮助我弄清楚我可以在哪里编辑代码来纠正此问题吗?如果 URL 不完全是从日期时间字段中提取的内容,我可以发出 404?我的 models.py、views.py 和 URLs.py 附在下面:
Models.py
class Blog(models.Model):
title = models.CharField(max_length=500, help_text='Title of the Blog Post')
author = models.ForeignKey(Author, on_delete=models.SET_NULL, null=True)
**created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
content = models.TextField(help_text='Content of the Blog Post')
topic = models.ManyToManyField(Topic, help_text='Topic of this Blog Post')
slug = models.SlugField(
null=False,
unique=True,
max_length=500,
editable=False,
)
class Meta:
ordering = ['-created_on']
def __str__(self):
return self.title
def get_absolute_url(self):
kwargs = {
'year': self.**created_on.strftime("%Y"),
'month': self.**created_on.strftime("%m"),
'day': self.**created_on.strftime("%d"),
'slug': self.slug,
}
return reverse('blog-detail', kwargs=kwargs)
def save(self, *args, **kwargs):
self.slug = slugify(self.title, allow_unicode=True)
super(Blog, self).save(*args, **kwargs)
Views.py
class BlogListView(ListView):
model = Blog
template_name = 'blog_list.html'
class BlogDetailView(DetailView):
model = Blog
context_name = 'blog-detail'
**year_url_kwarg = 'year'
slug_url_kwarg = 'slug'
**month_url_kwarg = 'month'
**day_url_kwarg = 'day'
URLs.py
urlpatterns = [
path('index/',views.index, name='index'),
**re_path(r'^blog/(?P<year>d{4})/(?P<month>d{2})/(?P<day>d{2})/(?P<slug>[-w]+)$', views.BlogDetailView.as_view(), name='blog-detail'),
re_path(r'^blog/$',views.BlogListView.as_view(), name='blog_main'),
]
我在代码中放入**以引起对相关字段的注意。感谢您抽出宝贵时间通读并试图帮助我解决这个问题!
你可以通过覆盖.get_queryset(…)
方法[Django-doc]来过滤:
class BlogDetailView(DetailView):
model = Blog
context_name = 'blog-detail'
defget_queryset(self, *args, **kwargs):
return super().get_queryset(*args, **kwargs).filter(
created_on__year=self.kwargs['year'],
created_on__month=self.kwargs['month'],
created_on__day=self.kwargs['day']
)
注意:我建议使用有效的Python 标识符
context_name
名称,而不是带有连字符的名称。虽然它可能在模板引擎中工作,但以后他们可能会稍微改变 Django 模板引擎的"语法"。