You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django博客点击文章跳404错误求助:No Post matches the given query

解决Django博客文章404的问题

看起来你遇到的是典型的查询参数不匹配导致的404错误,我帮你梳理几个最可能的原因和解决办法:

1. URL捕获的日期参数是字符串,而数据库查询需要整数

你的URL规则里用\d{4}和\d{2}捕获的year、month、day都是字符串类型(比如'01'而不是整数1),但Django对DateField的__month、__day查询要求传入整数。当你直接把字符串参数传给get_object_or_404时,数据库找不到匹配的记录,自然返回404。

解决办法:在post_detail视图里先把这些参数转成整数:

def post_detail(request, year, month, day, post):
    # 转换为整数
    year = int(year)
    month = int(month)
    day = int(day)
    post = get_object_or_404(Post, slug=post, status='published', 
                             publish__year=year, 
                             publish__month=month, 
                             publish__day=day)
    return render(request, 'blog/post/detail.html', {'post': post})

2. Slug字段不匹配

检查两个关键点:

  • 你的Post模型里是否正确定义了slug字段?应该是类似这样的:
    from django.db import models
    from django.utils.text import slugify
    
    class Post(models.Model):
        title = models.CharField(max_length=250)
        slug = models.SlugField(max_length=250, unique_for_date='publish')
        publish = models.DateTimeField()
        status = models.CharField(max_length=10, choices=[('published', 'Published'), ('draft', 'Draft')])
    
        def save(self, *args, **kwargs):
            if not self.slug:
                self.slug = slugify(self.title)
            super().save(*args, **kwargs)
    
    确保slug是基于标题生成的,且保存到数据库时是正确的。
  • URL里的post参数(也就是slug)和数据库里的slug是否完全一致?比如URL里是Django,但数据库里是django(大小写不同),默认数据库查询是区分大小写的,这时候也会找不到记录。你可以改成不区分大小写的查询:
    post = get_object_or_404(Post, slug__iexact=post, status='published', ...)
    
    或者确保生成URL时使用的是post.slug的原始值(不要手动修改大小写)。

3. 文章状态不是published

你的视图里查询条件包含status='published',所以要确认数据库里的目标文章的status字段确实是'published',而不是'draft'或者其他值。可以通过Django admin查看文章的状态是否正确。

额外检查:模板里的URL生成是否正确

确保你在列表页模板(list.html)里生成文章链接时,传递的参数是正确的:

{% for post in posts %}
  <a href="{% url 'post_detail' post.publish.year post.publish.month post.publish.day post.slug %}">
    {{ post.title }}
  </a>
{% endfor %}

如果月份/日期是个位数(比如1月),Django的post.publish.month返回的是整数1,这时候生成的URL会是/2018/1/07/...,但你的URL规则要求\d{2}(两位数字),这时候会匹配失败。解决这个问题的话,你可以在模板里格式化日期为两位:

{% url 'post_detail' post.publish.year post.publish|date:'m' post.publish|date:'d' post.slug %}

这样月份和日期会被格式化为两位数字(比如01、07),和URL规则匹配。

内容的提问来源于stack exchange,提问作者maro584

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:46:29