You need to enable JavaScript to run this app. Django博客分类Slugify失效,点击提示Field 'id' expected a number报错
优惠活动
大模型
产品
解决方案
定价
更多

Django博客分类Slugify失效,点击提示Field 'id' expected a number报错

问题修复方案

错误根源

你在过滤外键字段时直接传入了分类名字符串,Django默认会将外键字段的过滤值当做关联表的主键(数字id)处理,因此抛出「需要数字但得到了字符串」的错误。

分步修改

1. 调整分类模型(可选但推荐)

给分类表加专属slug字段,更符合URL路由的使用规范,避免中文名称等特殊字符导致的路由异常:

from django.utils.text import slugify

class Categories(models.Model):
    name = models.CharField(max_length=200)
    # 新增分类slug字段,保证唯一性
    slug = models.SlugField(null=False, unique=True, max_length=200)

    class Meta:
        verbose_name_plural = 'Categories'

    def __str__(self):
        return self.name
    
    # 自动根据分类名生成slug
    def save(self, *args, **kwargs):
        if not self.slug:
            self.slug = slugify(self.name)
        super().save(*args, **kwargs)

修改完成后执行命令生成并执行迁移:

python manage.py makemigrations
python manage.py migrate

执行迁移时如果已经有存量分类,按照提示给历史分类补填slug值即可。

2. 修改视图过滤逻辑

使用Django跨表查询语法,指定要匹配的分类字段,不要直接给外键字段传字符串:
如果用上面新增的slug字段匹配,写法如下(无需额外处理横杠):

def CategoryView(request, cats):
    category_posts = Item.objects.filter(item_category__slug=cats)
    return render(request, 'waqart/categories.html', {'cats':cats.title(), 'category_posts':category_posts })

如果你不想新增slug字段,也可以直接匹配分类名称:

def CategoryView(request, cats):
    category_name = cats.replace('-','')
    category_posts = Item.objects.filter(item_category__name=category_name)
    return render(request, 'waqart/categories.html', {'cats':cats.title(), 'category_posts':category_posts })

3. 修复外键默认值问题(附加)

你当前Item模型里的外键默认值写的是字符串'Coding',不符合外键字段规则,也会触发同类型报错,可修改为:

# 先定义获取默认分类的方法
def get_default_category():
    return Categories.objects.get_or_create(name='Coding')[0]

class Item(models.Model):
    # 其他字段保持不变
    item_category = models.ForeignKey(Categories, default=get_default_category, on_delete=models.SET_DEFAULT)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.13 16:06:02