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

Django序列化器设置IntegerField报错:'int'对象无'pk'属性

问题排查与解决思路

这个错误的根源在于嵌套序列化器处理外键字段时的类型不匹配,我们一步步拆解:

为什么会报错?

看你的栈追踪,错误来自rest_framework/relations.py里的to_representation方法,它尝试调用value.pk但传入的是整数。这是因为:

  1. 你的MarketActionClearingSerializer是ModelSerializer,而MarketAction模型里的marketSessionid、marketActorid等字段应该是外键(ForeignKey),所以ModelSerializer默认会把这些字段处理成PrimaryKeyRelatedField。
  2. 你先通过MarketActionSerializer(ma).data得到了序列化后的字典,里面的外键字段是整数ID;接着把这个字典传给PrioritisedMarketActionSerializer的marketaction字段。
  3. 当PrioritisedMarketActionSerializer序列化这个字典时,嵌套的MarketActionSerializer会对每个字段执行to_representation——对于PrimaryKeyRelatedField类型的字段,它期望接收的是模型实例,而不是整数ID,所以尝试访问整数的pk属性时就抛出了错误。

解决方法(按推荐程度排序)

方法1:直接传入模型实例(最简单)

不需要先序列化ma成字典,直接把MarketAction的模型实例传给prioritised_ma的marketaction字段:

# 替换你原来的逻辑
prioritised_ma = {
    "marketaction": ma,  # 直接传模型实例,不是序列化后的data
    "priority": 1
}
output.append(PrioritisedMarketActionSerializer(prioritised_ma).data)

这样嵌套的MarketActionSerializer会自动处理模型实例,正确序列化所有字段,包括外键对应的ID。

方法2:显式声明外键字段为IntegerField

如果你必须用字典传递数据,可以修改MarketActionClearingSerializer,把所有外键字段显式声明为IntegerField,覆盖ModelSerializer的默认行为:

class MarketActionClearingSerializer(serializers.ModelSerializer):
    id = serializers.IntegerField(required=True)
    # 显式声明外键字段为IntegerField
    marketSessionid = serializers.IntegerField()
    marketActorid = serializers.IntegerField()
    formid = serializers.IntegerField()
    actionTypeid = serializers.IntegerField()
    statusid = serializers.IntegerField()
    loadid = serializers.IntegerField()

    class Meta:
        model = MarketAction
        fields = ( 'id', 'date', 'actionStartTime', 'actionEndTime', 'value', 'uom', 'price', 'deliveryPoint', 'marketSessionid', 'marketActorid', 'formid', 'actionTypeid', 'statusid', 'loadid', 'cpu', 'ram', 'disk',)
        depth = 0
    # 保留你的error_status_codes

这样序列化器会把这些字段当成普通整数处理,不会尝试访问pk属性。

方法3:使用普通Serializer替代ModelSerializer(适合不需要模型绑定的场景)

如果MarketActionSerializer不需要和模型强绑定,可以改成普通的serializers.Serializer,手动声明所有字段:

class MarketActionSerializer(serializers.Serializer):
    id = serializers.IntegerField(required=True)
    date = serializers.DateTimeField()
    actionStartTime = serializers.DateTimeField()
    actionEndTime = serializers.DateTimeField()
    value = serializers.DecimalField(max_digits=10, decimal_places=2)  # 按你的模型字段类型调整
    uom = serializers.CharField()
    price = serializers.DecimalField(max_digits=10, decimal_places=2)
    deliveryPoint = serializers.CharField()
    marketSessionid = serializers.IntegerField()
    marketActorid = serializers.IntegerField()
    formid = serializers.IntegerField()
    actionTypeid = serializers.IntegerField()
    statusid = serializers.IntegerField()
    loadid = serializers.IntegerField()
    cpu = serializers.IntegerField()
    ram = serializers.IntegerField()
    disk = serializers.IntegerField()

然后在PrioritisedMarketActionSerializer里使用这个普通Serializer,就不会有外键字段的自动转换问题了。

另外注意你代码里的小笔误:PrioritisedMarketActionsSerializer应该是PrioritisedMarketActionSerializer(多了个s),如果是复制粘贴错误的话记得修正。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 23:12:32