Django休息框架在条件之后禁用字段更新

时间:2014-11-24 09:38:40

标签: django django-rest-framework

我正在使用DRF,如果尊重相同型号的条件,我需要禁用字段更新。

示例:

class Foo(models.Model):
    text = models.CharField()
    checkfield = models.BooleanField(default=False)
除非textcheckfield,否则可以修改

True

因此无法通过DRF API修改if Foo.checkfield is True Foo.text。 这样做的最佳方式是什么?

1 个答案:

答案 0 :(得分:3)

我认为Advanced serializers会做你想做的事。

只需创建自定义序列化程序,然后在视图中查看checkfield的值。如果是,则传递text参数,以便启用序列化程序中的字段。

顺便说一句,因为您只需要删除或添加一个固定的额外字段,而不是像示例中那样传递fields参数,您可以传递类似enable_text=checkfield的内容,然后将文本字段添加到'根据'checkfield'的值,在序列化程序中使用fields'变量。

更新以澄清:

定义没有文本字段的序列化程序。然后在你的ModelViewSet中覆盖update方法,这样就可以这样获得序列化程序(我认为get_serializer()方法不允许传递额外的args):

YourSerializer(object,enable_text = True)

并且,在序列化程序 init 方法中,当'enable_text'为True时,您将文本字段添加到self.fields属性。

我没有测试过这是否有效,但我认为这是可行的方法。

使用代码段和修改进行编辑

我一直在挖掘我所解释的内容,结果发现它对于你想要做的简单修改有点麻烦。我想出的只是覆盖ViewSet中的更新方法。这是代码:

from rest_framework import viewsets, status
from rest_framework.response import Response
from models import Test, TestSerializer


class TestViewSet(viewsets.ModelViewSet):
    queryset = Test.objects.all()
    serializer_class = TestSerializer

    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        self.object = self.get_object_or_none()

        if 'enable_text' in request.DATA and request.DATA['enable_text'] == True:
            request.DATA['text'] = self.object.text
        serializer = self.get_serializer(self.object, data=request.DATA,
                                         files=request.FILES, partial=partial)

        if not serializer.is_valid():
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        try:
            self.pre_save(serializer.object)
        except ValidationError as err:
            # full_clean on model instance may be called in pre_save,
            # so we have to handle eventual errors.
            return Response(err.message_dict, status=status.HTTP_400_BAD_REQUEST)

        if self.object is None:
            self.object = serializer.save(force_insert=True)
            self.post_save(self.object, created=True)
            return Response(serializer.data, status=status.HTTP_201_CREATED)

        self.object = serializer.save(force_update=True)
        self.post_save(self.object, created=False)
        return Response(serializer.data, status=status.HTTP_200_OK)

此代码取自UpdateMixin的rest_framework源代码。请注意if 'enable_text' in request.DATA and...行和request.DATA['text'] = self.object.text行。这些是允许你做你需要的功能的那些。基本上是:

  • 如果您发送带有True的enable_text以及文本,则会修改文本。
  • 如果您发送带有False的enable_text以及文本,则会被忽略。

请注意,此代码仅考虑当前请求中传递的enable_text的值。您可能还希望如果当前请求中没有enable_text,则检查self.object(数据库实例本身)中的enable_text值。