如何在带有验证的drf中创建嵌套对象?

时间:2019-08-03 17:54:52

标签: python django django-rest-framework

我想使用django-rest-framework序列化器(drf)创建嵌套对象。

最初,我创建了这样的序列化器:

# make a copy
temp = alist[:]
# shuffle
random.shuffle(alist)
# alist is now shuffled in-place
# restore from the copy
alist = temp

但是那没有用,因为在创建集合的验证发生之前,validate方法是从create方法调用的,而在create方法之前。问题在于,在第一种情况下,上下文包含“请求”和其他一些信息。在第二种情况下,上下文包含在create方法上下文中定义的内容。

因此,对使用不同上下文信息调用两次的每个公民验证方法。

然后我尝试从create方法中删除is_valid方法。然后发生下一个逻辑错误:

class CollectionCreateSerializer(ModelSerializer):
   citizens = CitizenSerializer(many=True)

   ## Some definition of serializer fields


    def create(self, validated_data):
        collection = Collection.objects.create()
        citizens = validated_data.pop('citizens')

        for citizen in citizens:
            citizen_serializer = CitizenSerializer(data=citizen,
                                                   context={'citizens': citizens)
            citizen_serializer.is_valid(raise_exception=True)
            citizen_serializer.save()

        return collection

class CitizenSerializer(serializers.ModelSerializer):


   ## Some defenition of serializer fields



    def validate(self, attrs):
        print('in validate citizen')
        citizens = self.context['citizens']

        ## Some validation logic with citizens context

        return super().validate(attrs)

然后,我试图让公民看重真实,以防止内部验证。但是,在create方法中,经过验证的数据中不包括“ citizens”字段。

所以我希望关闭内部嵌套对象验证的某些标志?也许存在更好的解决方案。

1 个答案:

答案 0 :(得分:1)

实施中的问题是,您正在CitizenSerializer的{​​{1}}方法中创建create实例。

您不应该这样做,因为CollectionCreateSerializer被定义为嵌套序列化器字段,因此在创建CitizenSerializer实例时已经对其进行了调用和验证。有关详情,请参见此Sitepoint article explaining the basics of DOM Manipulation

您需要更新CollectionCreateSerializer,例如:

CollectionCreateSerializer