我正在使用DRF,如果尊重相同型号的条件,我需要禁用字段更新。
示例:
class Foo(models.Model):
text = models.CharField()
checkfield = models.BooleanField(default=False)
除非text
为checkfield
,否则可以修改 True
。
因此无法通过DRF API修改if Foo.checkfield is True
Foo.text
。
这样做的最佳方式是什么?
答案 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
行。这些是允许你做你需要的功能的那些。基本上是:
请注意,此代码仅考虑当前请求中传递的enable_text的值。您可能还希望如果当前请求中没有enable_text,则检查self.object
(数据库实例本身)中的enable_text值。