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})
问题原因
- 过滤条件不匹配:添加的
category__slug='fitness'要求文章必须关联slug为'fitness'的Category,但目标文章的Category slug不符,或者文章未关联任何Category(模型中category允许null=True),导致get_object_or_404找不到对应记录,抛出404。 - 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
相关产品推荐
相关产品推荐

