You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django保存模型报错:'id'期望数字却得到ForeignKey对象

Django保存Item实例时出现TypeError错误

错误信息:

Exception Type: TypeError
Exception Value: Field 'id' expected a number but got <django.db.models.fields.related.ForeignKey: owner>.

模型代码

class User(AbstractUser):
    pass

""" ... """

class Item(TimeStampMixin):
    title = models.CharField(max_length=40)
    owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name="Items")
    last_bidder = models.ForeignKey(User, on_delete=models.DO_NOTHING, related_name="bidded_objects", default=owner)
    etc=etc...

视图代码

class Form_New_Item(ModelForm):
    class Meta:
        model = Item
        fields = ['title', 'description', 'price', 'category', 'image_url']

def create_new_item(request):
    if request.user.is_authenticated and request.method == "POST":
        form = Form_New_Item(request.POST)
        user = request.user
        if form.is_valid():
            new_item = Item(
                owner=user,
                title=form.cleaned_data['title'],
                etc=etc...,
            )
            new_item.save()
            return HttpResponseRedirect(reverse("index"))
问题原因与修复方法

错误根源在last_bidder字段的default设置:你直接把owner字段对象作为默认值,而不是一个有效的用户实例或用户ID。Django尝试将这个字段对象转换为用户ID时,就会抛出"Field 'id' expected a number but got..."的错误。

修复方法有两种:

  • 如果允许last_bidder为空,设置default=None并添加null=True:
last_bidder = models.ForeignKey(User, on_delete=models.DO_NOTHING, related_name="bidded_objects", default=None, null=True)
  • 如果希望默认值和owner保持一致,有两种实现方式:
    1. 在创建实例时显式赋值:
    new_item = Item(
        owner=user,
        last_bidder=user,
        title=form.cleaned_data['title'],
        etc=etc...,
    )
    
    1. 使用可调用函数动态获取默认值:
    def get_default_last_bidder(instance):
        return instance.owner
    
    class Item(TimeStampMixin):
        title = models.CharField(max_length=40)
        owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name="Items")
        last_bidder = models.ForeignKey(User, on_delete=models.DO_NOTHING, related_name="bidded_objects", default=get_default_last_bidder)
    
    注意:第二种方式需要确保创建Item实例时owner已被正确设置,否则可能引发错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 06:54:46