Django项目使用slug后出现NoReverseMatch错误求助
Django NoReverseMatch 错误排查与修复
核心问题分析
从错误提示来看,反向解析lesson_detail路由时,slug和standard参数为空值,这是导致失败的直接原因,以下是具体错误点及修复方案:
1. Lesson 模型字段名与赋值不匹配
在Lesson模型中,你定义的slug字段是slugs,但save方法里却错误地给self.slug赋值,导致实际没有生成有效的slug:
# 模型中定义的字段 slugs = models.SlugField(null=True, blank=True) # save方法的错误赋值 def save(self, *args, **kwargs): self.slug = slugify(self.name) # 此处应为self.slugs return super().save(*args, **kwargs)
这会导致lesson.slug不存在,反向解析时传入空值。
2. 模板中外键引用大小写错误
模板里的lesson.Standard.slug写法错误,Django中外键字段是小写的模型类名,应改为lesson.standard.slug,同时要对应模型里的字段名slugs:
{% url 'appname:lesson_detail' slug=lesson.slugs subject=subjects.slug standard=lesson.standard.slug %}
3. 路由参数类型优化(可选)
当前lesson_detail路由的参数类型用<str:>不够严谨,建议统一改为<slug:>更符合slug的使用场景:
# 修改appname/urls.py中的lesson_detail路由 path('<slug:standard>/<slug:subject>/<slug:slug>/', views.LessonDetailView.as_view(), name='lesson_detail'),
同时,为了让LessonDetailView正确通过slug获取对象,可以重写get_object方法:
class LessonDetailView(DetailView): context_object_name ='lessons' model = Lesson template_name = "appname/lesson_detail_view.html" def get_object(self): return Lesson.objects.get( slugs=self.kwargs['slug'], subject__slug=self.kwargs['subject'], standard__slug=self.kwargs['standard'] )
4. 数据迁移与数据更新
修改模型字段后,需要执行迁移命令更新数据库:
python manage.py makemigrations python manage.py migrate
同时重新保存所有Lesson对象,确保slugs字段被正确生成。
修复后的关键代码片段
修正后的Lesson模型
class Lesson(models.Model): lesson_id = models.CharField(max_length=250, unique=True) standard = models.ForeignKey(Standard, on_delete=models.CASCADE) created_by = models.ForeignKey(User, on_delete=models.CASCADE) created_at = models.DateTimeField(auto_now_add=True) subject = models.ForeignKey(Subject, on_delete=models.CASCADE, related_name="lessons") name = models.CharField(max_length=250) position = models.PositiveSmallIntegerField(verbose_name="chapter no.") slugs = models.SlugField(null=True, blank=True) class Meta: ordering = ['position'] def __str__(self): return self.name def save(self, *args, **kwargs): self.slugs = slugify(self.name) # 修正字段名匹配 return super().save(*args, **kwargs)
修正后的模板代码
{% extends 'base.html' %} {% block content %} {% for lesson in subjects.lessons.all %} <a href="{% url 'appname:lesson_detail' slug=lesson.slugs subject=subjects.slug standard=lesson.standard.slug %}">Chapter--{{lesson.position}}: {{lesson.name}}</a> {% endfor %} {% endblock content %}
内容的提问来源于stack exchange,提问作者Zenji
相关产品推荐
相关产品推荐

