如何使用URL正则表达式匹配Django中帖子的确切日期?

我正在使用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不完全是从datetime字段中提取的,我可以在其中发出404消息吗?我的models.py,views.py和URLs.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'),

]

我在代码中加上了**,以引起对相关领域的关注。感谢您抽出宝贵的时间阅读并尝试帮助我!

评论
id_cum
id_cum

You can filter by overriding the .get_queryset(…) method [Django-doc]:

class BlogDetailView(DetailView):
    model = Blog
    context_name = 'blog-detail'

    def get_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']
        )

Note: I would advise using an name for context_name that is a valid Python identifier, so not something with a hyphen. While it might work in the template engine, it is possible that later they slightly change the "grammar" of the Django template engine.

点赞
评论