我认为Advanced serializers 会做你想做的事。
只需创建您的自定义序列化程序,然后在您的视图中检查校验字段的值。如果为真,则将文本参数传递给它,以便在序列化程序中启用该字段。
顺便说一句,由于您只需要删除或添加一个固定的额外字段,而不是像示例中那样传递 fields 参数,您可以传递类似 enable_text=checkfield 的内容,然后将文本字段添加到“字段”根据'checkfield'的值在你的序列化器中变量。
更新澄清:
定义没有文本字段的序列化程序。然后在您的 ModelViewSet 中,覆盖更新方法,以便您以这种方式获取序列化程序(我认为 get_serializer() 方法不允许传递额外的参数):
YourSerializer(object, enable_text=True)
并且,在您的序列化器 init 方法中,当 'enable_text' 为 True 时,您将文本字段添加到 self.fields 属性。
我没有测试这是否有效,但我认为这是要走的路。
使用 sn-p 编辑和修改
我一直在挖掘我所解释的内容,结果发现对于您尝试进行的简单修改来说有点混乱。我想出的只是覆盖 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 的值。