动态嵌套序列化器:空的validated_data

时间:2019-04-19 09:43:11

标签: django django-models django-rest-framework django-views django-serializer

大家好!

因此,从这里开始,我正在研究端点之一上的行为:

# GET Request
{
  "id": 1,
  "name": "test",
  "created_date": "date",
  "completed_date": "date",
  "template": { "name" : "test" }, => nested serializers with only the field "name"
  "status": 1,
  "results": [ { __all__ }, ... ], => nested serializers with all the fields
  "groups": [ { "name" }, ... ], => nested serializers with only the field "name"
}

# POST Request
{ 
  "name": "test",
  "template": {"name":"test"}, => nested serializers with only the field "name"
  "groups": [ {"name":"test"} ], => nested serializers with only the field "name"
}

如您所见,POST和GET请求将某些字段设置为只读(状态,结果,事件),而嵌套字段仅需要“名称”字段,而并非全部。

以下是此端点的序列化器:

class CampaignsSerializer(serializers.ModelSerializer):
    template = TemplatesSerializer(fields=('name'))
    results = ResultsSerializer(many=True, read_only=True)
    groups = GroupsSerializer(many=True, fields=('name'))

    class Meta:
        model = Campaigns
        fields = ('id', 'user_id', 'name', 'created_date', 'completed_date', 'template', 'status', 'results', 'groups', )
        read_only_fields = ('status', 'results', )

    def create(self, validated_data):
        user = None
        request = self.context.get("request")
        if request and hasattr(request, "user"):
            user = request.user

        template = Templates.objects.filter(name=validated_data.pop('template')).first()
        groups = validated_data.pop('groups')
        campaign = Campaigns.objects.create(user_id=user.id, 
                                            template=template.id,
                                            **validated_data)

        for group in groups:
            obj = Groups.objects.filter(**group)
            campaign.groups.add(obj)

        return campaign

class TemplatesSerializer(serializers.ModelSerializer):
    class Meta:
        model = Templates
        fields = '__all__'

    def __init__(self, *args, **kwargs):
        fields = kwargs.pop('fields', None)
        super(TemplatesSerializer, self).__init__(*args, **kwargs)
        if fields is not None:
            allowed = set(fields)
            existing = set(self.fields)
            for field_name in existing - allowed:
                self.fields.pop(field_name)

Same thing for `GroupsSerializer`

因此,以下所有内容为我提供了0个结果template = Templates.objects.filter(name=validated_data.pop('template')).first() 确实存在模板。如果将validated_data.pop('template')替换为硬编码名称,它将返回一个对象。但是截至目前,它返回None。 因为validated_data.pop('template')为空...我不确定为什么,但是我认为这与我正在动态修改字段有关。我不想创建2个不同的序列化器(一个用于发布请求,一个用于获取请求)。将某些字段设置为read_only并动态修改字段是这里的好选择?你觉得呢?

模板和组是在这里引起麻烦的序列化程序。我没有将序列化器设置为ReadOnly。我不明白为什么它没有得到验证...对此有任何见解吗?

我认为这个问题也与此相关:Django Rest Framework : Nested Serializer Dynamic Model Fields

进度: 据我调试,此函数返回一个空列表... 这就是为什么它从未得到验证的原因...因此不在最后清单...

@cached_property
    def _writable_fields(self):
        return [
            field for field in self.fields.values() if not field.read_only
        ]

再次感谢!

此致

0 个答案:

没有答案