使用Django Rest Framework在同一请求中对相同类型的资源执行的不同操作

时间:2018-10-24 11:57:44

标签: python django rest django-rest-framework

我想设计一个端点,该端点可以在一个请求中处理相同类型资源的多个操作。

我在阅读article

时想到了这个主意

此端点上的请求如下所示:

[
  {
    "id": "ID1",
    "method": "DELETE"
  },
  {
    "id": "ID2",
    "method": "PATCH",
    "body": {"resource's": "data"}
  },
    {
        "method": "POST",
        "body": {"resource's": "data"}
    }
]

让我带上序列化器

class ActionResourceSerializer(serializers.Serializer):

    HTTP_METHODS = ('POST', 'PUT', 'PATCH', 'DELETE')
    pk = serializers.IntegerField(min_value=1, required=False)
    method = serializers.ChoiceField(choices=HTTP_METHODS, required=False)
    body = ResourceSerializer()

    def validate(self, attrs):
        pk = attrs.get('id')
        method = attrs.get('method')

        if method in ('PATCH', 'PUT', 'DELETE') and not pk:
            raise serializers.ValidationError({'id': f'This field is required for {method} method.'})

        if method in ('POST', 'PUT'):
            raise serializers.ValidationError({'body': f'This field is required for {method} method.'})

在编写代码期间,我遇到了一些问题:

1)Django序列化程序中的部分标志。

默认情况下,ActionResourceSerializer的局部标志为False。 ActionResourceSerializer的子ResourceSerializer也将“继承”该标志,因此在验证期间它将引发有关required fields的异常。没有简单的方法可以改变这种行为。

由于这个问题,我想到编写一个自定义的Manager类,该类将在request.data上进行初始化,然后选择适合于请求项方法的适当的序列化器。因此,对于“ method = PATCH”,它将调用ActionResourceSerializer(data=data, partial=True),对于method=PUT或“ method = POST” ActionResourceSerializer(data=data, instance=instance),对于“ DELETE”,它将仅在db中找到该对象并将其删除。但是我不确定这是个好主意。

管理器的伪代码如下:

class Manager:

    def __int__(self, data, instance):
        self.data = data
        self._errors = []

    @property
    def errors(self):
        return self._errors

    def is_valid(self):
        return not bool(self.errors)

    def _manage_departments(self):

        for item in self.data:
            method = item.get('method')
            if not method:
                self._errors.append({"method": ["This field is required."]})
                continue

            if method == 'PATCH':

                serialzier = ActionResourceSerializer(data=item, partial=True)

            elif method in ('PUT', 'POST'):
                serialzier = ActionResourceSerializer(data=item, partial=False)

有人建议吗?

0 个答案:

没有答案