如何在不使用嵌套序列化器创建模型的情况下通过Serializer创建模型实例?

时间:2016-07-19 10:40:45

标签: django django-rest-framework

我的模型中有很多链接:

class Travel(BaseAbstractModel):

    tags = models.ManyToManyField(
        Tag,
        related_name='travels',
        )
    owner = models.ForeignKey(
        'users.TravelUser',
        related_name='travel_owner'
        )
    payment = models.ForeignKey(
        Payment,
        related_name='travels',
        )
    country = models.ForeignKey(
        Country,
        related_name='travels,
        )
    ........

这些模型中的许多只有两个具有唯一名称和图像的字段。 我为每个模型创建了序列化程序,并将它们放在TravelSerializer

class TravelBaseSerializer(DynamicFieldsModelSerializer):

    owner = UserSerializer(required=False)
    tags = TagSerializer(many=True)
    payment = PaymentSerializer()
    country = CountrySerializer()  

根据文档,我覆盖了create()update 问题是,当我发送JSON数据时,Django从嵌套的序列化器创建每个模型。但我想只创建Travel个实例。此外,我希望不仅pk字段接收和响应序列化对象。

更新
我解决了这个问题,把代码放在答案中。现在我可以接收并响应Serializer数据而无需创建对象。 但我认为DRF提供了更优雅的方法。这是我与DRF的第一个项目,也许我会错过一些更容易的解决方案。

2 个答案:

答案 0 :(得分:2)

我决定覆盖to_internal_value()将其置于自定义选择器中并从中继承所有嵌套序列化器:

class NestedRelatedSerializer(serializers.ModelSerializer):

    def to_internal_value(self, data):
        try:
           pk = data['pk']
        except (TypeError, KeyError):
        # parse pk from request JSON
            raise serializers.ValidationError({'_error': 'object must provide pk!'})
        return pk

从中获取所有pk并保存在createupdated方法中:

    def update(self, instance, validated_data):
        # If don't get instance from db, m2m field won't update immediately
        # I don't understand why
        instance = Travel.objects.get(pk=instance.pk)
        instance.payment_id = validated_data.get('payment', instance.payment_id)
        instance.country_id = validated_data.get('country', instance.country_id)
        # update m2m links
        instance.tags.clear()
        instance.tags.add(*validated_data.get('tags'))
        instance.save()
        return instance

答案 1 :(得分:1)

我不确定我理解你想做什么,但可以设置read_only_fields Meta类是你需要的吗?

class TravelBaseSerializer(DynamicFieldsModelSerializer):

    owner = UserSerializer(required=False)
    tags = TagSerializer(many=True)
    payment = PaymentSerializer()
    country = CountrySerializer()  

    class Meta:
        read_only_fields = ('tags',)

请参阅文档中的this section