Django访问分类页报Field 'id' expected a number错误排查
问题根因
该报错与sqlite3数据库文件、迁移文件、settings.py配置均无关系,核心是代码逻辑存在4处错误:
- 视图层查询逻辑错误:
Post.objects.filter()链式调用中写了.filter(category='published')。Post模型的category是关联Category模型的外键字段,直接向该字段传值时,Django默认会将传入值匹配关联表的主键id(整数类型),传入字符串'published'必然触发「Field 'id' expected a number but got 'published'」的ValueError。从现有模型结构看,Post表根本没有定义发布状态相关字段,该过滤条件属于错误编写的无效逻辑。 - 类视图方法返回值不符合规范:
ListView的get_queryset方法要求必须返回QuerySet查询集对象,原代码返回自定义字典,本身不符合类视图的运行逻辑。 - 路由参数未指定类型:原路由路径写为
<category>,未明确参数类型,容易出现异常匹配问题。 - 辅助函数缺失返回值:原代码中
category_list视图函数只定义了上下文字典,没有写返回响应的逻辑,访问对应路由会直接报错。
修复方案
- 修正views.py代码
from django.shortcuts import render from django.views.generic import ListView from .models import Post, Category class CatListView(ListView): template_name = "Blog/category.html" context_object_name = 'posts' def get_queryset(self): # 删除错误的category='published'过滤条件,仅按分类名筛选帖子 return Post.objects.filter(category__name=self.kwargs['category']) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) context['cat'] = self.kwargs['category'] return context def category_list(request): category_list = Category.objects.exclude(name='default') context = { "category_list": category_list, } # 补上缺失的响应返回逻辑 return render(request, "Blog/category_list.html", context)
- 修正urls.py路由,明确参数类型
from django.urls import path from . import views urlpatterns = [ path("category/<str:category>/", views.CatListView.as_view(), name="category"), ]
- 修正category.html模板循环逻辑,适配调整后的上下文变量
{% for post in posts %} <!-- 这里按需写帖子内容的渲染逻辑 --> <p>{{ post.werkstoffnummer }}</p> {% endfor %}
补充说明:如果后续需要实现「筛选已发布帖子」的功能,需要先在Post模型中添加对应状态字段,例如新增
is_published = models.BooleanField(default=False)字段,执行python manage.py makemigrations和python manage.py migrate完成迁移后,再将过滤条件写为.filter(is_published=True)即可,禁止向外键字段传入非关联主键/关联模型实例的无关值。
内容的提问来源于stack exchange,提问作者Zak Meshou
相关产品推荐
相关产品推荐

