Django分类路径报错:Field 'id'预期数字却得到'economy'
解决Django中Category路径的ValueError问题
错误原因
你的Post模型里,category是关联到Category模型的外键,执行Post.objects.filter(category=cats)时,Django默认会把传入的cats字符串(比如'economy')当作Category的主键id(整数类型)去匹配,类型不匹配就触发了报错:Field 'id' expected a number but got 'economy'。
解决方案
方案一:直接匹配Category的title字段
修改views.py中的查询语句,明确指定匹配Category的title字段:
def CategoryView(request, cats): # 匹配Category的title字段,要忽略大小写就用category__title__iexact category_posts = Post.objects.filter(category__title=cats) return render(request, 'categories.html', {'cats':cats.title(), 'category_posts':category_posts})
如果数据库里的Category标题和URL传入的字符串存在大小写差异(比如库中是'Economy',URL里是'economy'),可以用category__title__iexact=cats实现忽略大小写的匹配。
方案二:使用Slug字段(推荐)
这是更规范的做法,能避免标题含特殊字符导致的路径问题:
给Category模型添加slug字段
修改models.py的Category类:from django.utils.text import slugify class Category(models.Model): created_at = models.DateTimeField(auto_now_add=True, verbose_name="Created at") title = models.CharField(max_length=255, verbose_name="Title") slug = models.SlugField(unique=True, max_length=255, verbose_name="Slug") # 添加该行 parent = models.ForeignKey('self', related_name='children', on_delete=models.CASCADE, blank=True, null=True) class Meta: verbose_name = "Category" verbose_name_plural = "Categories" ordering = ['title'] def __str__(self): return self.title # 自动从title生成slug def save(self, *args, **kwargs): if not self.slug: self.slug = slugify(self.title) super().save(*args, **kwargs)执行数据库迁移命令:
python manage.py makemigrations python manage.py migrate修改URL配置
将urls.py中的动态路径改为<slug:cats>:path('category/<slug:cats>/', views.CategoryView, name ="category"),更新视图查询逻辑
修改views.py的查询语句匹配slug字段:def CategoryView(request, cats): category_posts = Post.objects.filter(category__slug=cats) # 获取Category对象,传递正确的标题到模板 category = Category.objects.get(slug=cats) return render(request, 'categories.html', {'cats':category.title, 'category_posts':category_posts})
额外修复:模板语法错误
你的categories.html里有{% else %}但没有对应的{% if %},需要在{% for post in category_posts %}前添加{% if category_posts %}:
{% extends 'base.html' %} {%block content%} <h1> Category: {{ cats }} </h1> {% if category_posts %} {% for post in category_posts %} <!-- 卡片内容部分 --> {% endfor %} {% else %} <h2>Sorry this page does not exist....</h2> {% endif %} {%endblock%}
内容的提问来源于stack exchange,提问作者Singh Pannu
相关产品推荐
相关产品推荐

