如何遍历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
额外补充几点优化建议:
- 你的JSON数据结构是完全正确的,
assigned_facilities是包含字典的列表,符合遍历需求。 - 可以增加空值判断,避免因数据缺失报错:
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') )
- 模型中
LeadFacilityAssign和Lead的related_name都用了leadfacility,虽然能正常工作,但建议改成不同名称(比如把Lead的related_name改为lead_facilities),避免逻辑混淆。
内容的提问来源于stack exchange,提问作者Matthias
相关产品推荐
相关产品推荐

