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

如何遍历JSONField序列化器数据并创建关联对象?

问题描述

我已经尝试数周遍历JSON序列化器传入的数据,试了多种方法还是没法遍历JSON获取facility_id列表。最终目标是为每个JSON项创建LeadFacilityAssign对象,用到其中的facility_id和datetime,但现在连循环里访问facility_id都做不到。需要分配的Facility已经存在数据库里。

请问我遗漏了什么?该怎么遍历"assigned_facilities"?目前只能通过print()一次性输出完整JSON数据,是不是我的JSON数据结构有问题?


序列化器代码

class LeadUpdateSerializer(serializers.ModelSerializer):
    assigned_facilities = serializers.JSONField(required=False, allow_null=True, write_only=True)

    def create(self, validated_data):
        
        assigned_facilities = validated_data.pop("assigned_facilities")
        instance = Lead.objects.create(**validated_data)

        for item in assigned_facilities:
            instance.leadfacility.create(assigned_facilities_id=assigned_facilities.get('facility_id'), datetime=assigned_facilities.get('datetime'))
            
        return instance

传入的JSON数据

{
    "assigned_facilities": [{
            "facility_id": "1",
            "datetime": "2018-12-19 09:26:03.478039"
        },
        {
            "facility_id": "1",
            "datetime": "2019-12-19 08:26:03.478039"
        }
    ]
}

模型代码

class LeadFacilityAssign(models.Model):
    assigned_facilities = models.ForeignKey(Facility, on_delete=models.CASCADE, related_name='leadfacility')
    lead = models.ForeignKey(Lead, on_delete=models.CASCADE, related_name='leadfacility')
    datetime = models.DateTimeField(null=True, blank=True)

class Facility(models.Model):
    name = models.CharField(max_length=150, null=True, blank=False)

    def __str__(self):
        return self.name

class Lead(models.Model):
    first_name = models.CharField(max_length=40, null=True, blank=True)
    last_name = models.CharField(max_length=40, null=True, blank=True)

    def __str__(self):
        return f"{self.first_name} {self.last_name}"

解决方案

你的核心问题是循环内的变量引用错误:

  • 遍历assigned_facilities列表时,每个元素是item,但你却对整个列表调用get('facility_id'),这显然拿不到单个元素里的值。
  • 另外facility_id是字符串类型,需要转成整数才能匹配数据库中Facility的主键(默认是整数类型)。

修改后的create方法如下:

def create(self, validated_data):
    assigned_facilities = validated_data.pop("assigned_facilities")
    instance = Lead.objects.create(**validated_data)

    for item in assigned_facilities:
        # 从当前遍历的item中取值,而非整个列表
        instance.leadfacility.create(
            assigned_facilities_id=int(item.get('facility_id')),
            datetime=item.get('datetime')
        )
            
    return instance

额外补充几点优化建议:

  1. 你的JSON数据结构是完全正确的,assigned_facilities是包含字典的列表,符合遍历需求。
  2. 可以增加空值判断,避免因数据缺失报错:
for item in assigned_facilities:
    facility_id = item.get('facility_id')
    if facility_id:
        instance.leadfacility.create(
            assigned_facilities_id=int(facility_id),
            datetime=item.get('datetime')
        )
  1. 模型中LeadFacilityAssign和Lead的related_name都用了leadfacility,虽然能正常工作,但建议改成不同名称(比如把Lead的related_name改为lead_facilities),避免逻辑混淆。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 10:55:24