django 如何循环通过jsonfield序列化程序

wgx48brx  于 2022-11-18  发布在  Go
关注(0)|答案(5)|浏览(171)

几周来,我一直在尝试循环处理来自json序列化程序的传入数据,尝试了几种不同的方法,但是我似乎不能循环遍历json并返回一个包含所有facility_id的列表。最终我想为每个json项创建一个leadfacility对象,使用它的facility_id和它的datetime。但是我似乎甚至不能访问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"
        }
    ]
}

models.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}"
gpfsuwkq

gpfsuwkq1#

我建议使用一种不同的、可以说是更好的方法,使用嵌套模型序列化器代替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_nameleadfacility)。

gupuwyp2

gupuwyp22#

您正在执行:

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

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

bkkx9g8r

bkkx9g8r3#

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

nwlqm0z14#

我发现您的两个模型以及您如何将设施添加到循环中的潜在客户中存在一些问题。
请访问https://docs.djangoproject.com/en/4.1/topics/db/models/#extra-fields-on-many-to-many-relationships并相应地编辑您的模型。
TL;DR
然后,您可以在中间模型上添加额外的字段,在您的示例中为LeadFacilityAssign
中间模型与ManyToManyField关联,使用through参数指向将充当中间模型的模型。您缺少此部分。请确保将ManyToManyField添加到Leads
如果您继续阅读这些文档,您还会发现,您可以使用add()create()set(),通过through模型在LeadFacility之间创建关系。
您提到的设施已经存在,因此create()是错误的方法。请根据您的用例使用add()set(),并使用它们的ID预取这些设施。

8cdiaqws

8cdiaqws5#

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

assigned_facilities = validated_data.pop("assigned_facilities")

至:

assigned_facilities = validated_data.get("assigned_facilities")

相关问题