如何在jsonfield序列化程序中循环



几周来,我一直在尝试循环处理来自json序列化程序的传入数据。尝试了几种不同的方法,但我似乎无法循环使用json并返回一个包含所有facility_id的列表。最终,我想使用它的facility_id和datetime为每个json项创建一个leadfilities对象。但在使用for循环时,我似乎甚至无法访问facility_id。正在分配的协作室已在数据库中。

有人知道我在这里错过了什么吗?我怎么能循环通过";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"
}
]
}

型号.py

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}"

我建议一种不同的、可以说更好的方法。使用嵌套的模型序列化程序代替JSONField

class AssignedFacilitySerializer(serializers.ModelSerializer):
fields = ('assigned_facilities_id', 'datetime')
model = Facility
class LeadUpdateSerializer(serializers.ModelSerializer):
assigned_facilities = AssignedFacilitySerializer(many=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(**item)

return instance

您还没有发布您的Facility模型,因此可能存在一些名称不正确的字段,可能还有related_name(leadfacility(。

您正在执行的操作:

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

但不在任何地方使用项目。

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

我在两个模型中都看到了一些问题,以及如何在循环中向潜在客户添加设施。

请看一下https://docs.djangoproject.com/en/4.1/topics/db/models/#extra-字段,并相应地编辑模型。

TL;博士

然后可以在中间模型上添加额外的字段。在您的情况下,这是LeadFacilityAssign

中间模型使用through参数与ManyToManyField相关联,以指向将充当中介的模型。你错过了这个部分。确保将ManyToManyField添加到Leads

如果您继续阅读文档,您还会发现可以使用add()create()set()来使用直通模型创建LeadFacility之间的关系。

你提到的设施已经存在,所以create()是错误的方法。请根据您的用例使用add()set(),并使用它们的id预取这些设施。

当您使用pop()时,它会获取并删除数据。这就是为什么你不能在for循环中处理它
使用get()而不是pop(),您的问题就会得到解决
更改此行:

assigned_facilities = validated_data.pop("assigned_facilities")

至:

assigned_facilities = validated_data.get("assigned_facilities")

最新更新