【问题标题】:Django Rest Framework Nested Serializer Existing InstanceDjango Rest Framework 嵌套序列化程序现有实例
【发布时间】:2015-12-16 01:43:34
【问题描述】:

我有一个嵌套的 ModelSerializer,但无法验证。

我遇到的问题是,在创建父序列化程序时,我可能需要也可能不需要创建嵌套的序列化程序/模型,因为它可能已经存在于数据库中,我只想链接到它。

代码设置:

models.py

class ModelA(models.Model):
    modelb = ForeignKey(ModelB, null=true, blank=true)
    ...

class ModelB(models.Model):
    ...

serializers.py

class ModelASerializer(serializers.ModelSerializer):
    modelb = ModelBSerializer(required=False)

    class Meta:
        model = ModelA
        depth = 1

class ModelBSerializer(serializers.ModelSerializer):
    class Meta:
        model = ModelB

因此,给定 3 个数据场景,我在所有 3 个数据场景中都遇到了验证错误。

首先,如果我像这样将 NestedModel 作为数据传递

data = {
    'nestedmodel': NestedModel(**args),
    ...
}

我收到验证错误,说有一个 non_field_error,它需要一个字典,但得到了一个 NestedModel 实例。

其次,如果我传递的是 NestedModel 的数据(而不是对象):

data = {
    'nestedmodel': {'id': 'this', ... },
}

由于嵌套模型具有唯一键 ('id') 并且已存在于数据库中,因此我得到了等效于重复键的验证错误。

第三,如果我只是将嵌套模型的 id 传递给它,我会收到与第一种情况类似的错误,只是它说它得到的是 Unicode 而不是 NestedModel 实例。

data = {
    'nestedmodel': 'this',
}

我理解为什么所有这三种情况都会发生并且验证失败,但这无助于我尝试链接已经存在的 NestedModel 的目标。

我该怎么做呢?我做错了什么?

【问题讨论】:

    标签: python django django-rest-framework django-1.8


    【解决方案1】:

    你能试试这个吗:

    serializers.py

    class ModelASerializer(serializers.ModelSerializer):
        modelb = ModelBSerializer(required=False)
    
        class Meta:
            model = ModelA
            depth = 1
            fields = ('id', 'modelb', )
    
        def create(self, validated_data):
            modelb_id = self.validated_data.pop("nestedmodel")
            modelb = ModelB.objects.get(id=modelb_id["id"])
            modela = ModelA.objects.create(modelb=modelb, **validated_data)
            return modela
    

    按如下方式传递数据:

    输入

    data = {"nestedmodel": {"id": 1 # add nestedmodel fields here}, }
    
    
              
    

    【讨论】:

    • 我可以,但这似乎是一种 hack,它绕过了验证步骤——我想这意味着我必须编写自己的验证器。我有点认为会有一种更正式的方式来处理使用序列化程序链接已经存在的对象
    • @Seaux 更改代码以接受经过验证的数据。对于嵌套的序列化器,我们有两种方法,要么在序列化器级别创建实例,要么使用 create 和 update 方法在视图级别创建实例。
    猜你喜欢
    • 2018-06-23
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-09
    • 2018-07-06
    • 1970-01-01
    • 2017-03-03
    相关资源
    最近更新 更多