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

Django添加分类Slug过滤后使用文章Slug出现404错误

Django使用Slug后修改视图出现404错误

问题场景

使用Django开发网站,URL改用Slug后原本运行正常,修改show_post视图添加category__slug='fitness'过滤条件后,访问http://example.com/fitness/fitness-post-1/时出现404错误,错误提示路径匹配到最后一个URL规则django.views.static.serve。

相关代码

Post模型

class Post(models.Model):
    title = models.CharField(max_length=100)
    slug = models.SlugField(max_length=100, unique=True, default='')  
    content = models.TextField()
    category = models.ForeignKey(Category, on_delete=models.CASCADE, null=True, blank=True) 
    photo = models.ImageField(upload_to='post_photos/', blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)
    is_published = models.BooleanField(default=False)  

    def __str__(self):
        return self.title

    def save(self, *args, **kwargs):
        if not self.photo:
            random_image_path = get_random_image_path()
            self.photo = random_image_path
        super().save(*args, **kwargs)
        

    def get_absolute_url(self):
        return reverse('post', kwargs={'post_slug': self.slug})

URL配置

项目urls.py:

from django.contrib import admin 
from django.urls import path 
from immuno2you import views 
from django.conf import settings 
from django.conf.urls.static import static 

urlpatterns = [ 
    path('admin/', admin.site.urls),
    path('', views.index, name='index'),
    path('healthy-nutrition/', views.nutrition, name='nutrition'), 
    path('fitness/', views.fitness, name='fitness'), 
    path('fitness/<slug:post_slug>/', views.show_post, name='post'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

应用urls.py:

path('fitness/<slug:post_slug>/', views.show_post, name='post'),

视图代码

原视图(运行正常):

def show_post(request, post_slug):
    post = get_object_or_404(Post, slug=post_slug)
    return render(request, 'show_post.html', {'post': post})

修改后(出现404):

def show_post(request, post_slug): 
    post = get_object_or_404(Post, slug=post_slug, category__slug='fitness')     
    return  render(request, 'show_post.html', {'post': post})

问题原因

  1. 过滤条件不匹配:添加的category__slug='fitness'要求文章必须关联slug为'fitness'的Category,但目标文章的Category slug不符,或者文章未关联任何Category(模型中category允许null=True),导致get_object_or_404找不到对应记录,抛出404。
  2. URL匹配逻辑:视图抛出404后,Django会继续匹配后续URL规则,而项目urls.py末尾的static(...)规则被匹配,因此错误信息显示由django.views.static.serve触发。

解决方法

1. 检查文章与Category的关联

  • 登录Django Admin,找到fitness-post-1对应的Post对象:
    • 若关联的Category slug不是'fitness',修改Category的slug为'fitness',或者调整视图中的过滤值为实际的Category slug。
    • 若文章未关联Category,要么给文章绑定slug为'fitness'的Category,要么调整视图逻辑允许无分类的文章展示:
      def show_post(request, post_slug):
          post = get_object_or_404(Post, slug=post_slug)
          # 仅当文章有分类且分类slug不符时抛出404
          if post.category and post.category.slug != 'fitness':
              raise Http404("该文章不属于fitness分类")
          return render(request, 'show_post.html', {'post': post})
      

2. 清理重复的URL配置

项目urls.py和应用urls.py重复配置了fitness/<slug:post_slug>/,建议保留应用侧的配置,修改项目urls.py如下:

from django.contrib import admin 
from django.urls import path, include
from immuno2you import views 
from django.conf import settings 
from django.conf.urls.static import static 

urlpatterns = [ 
    path('admin/', admin.site.urls),
    path('', views.index, name='index'),
    path('healthy-nutrition/', views.nutrition, name='nutrition'), 
    path('fitness/', views.fitness, name='fitness'), 
    path('', include('your_app_name.urls')),  # 替换为你的应用名称
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

3. 调试验证

在视图中添加日志,确认数据匹配情况:

import logging
logger = logging.getLogger(__name__)

def show_post(request, post_slug):
    # 查看slug匹配的文章
    posts = Post.objects.filter(slug=post_slug)
    logger.info(f"Slug匹配的文章:{posts}")
    # 查看同时匹配分类的文章
    filtered_posts = Post.objects.filter(slug=post_slug, category__slug='fitness')
    logger.info(f"符合fitness分类的文章:{filtered_posts}")
    
    post = get_object_or_404(Post, slug=post_slug, category__slug='fitness')     
    return render(request, 'show_post.html', {'post': post})

查看日志输出,确认是否存在符合条件的记录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 00:24:53