0

我的情况是,我有一个端点samples,它sample通过ModelViewSet.

我的目标是,当用户 POST 向这个端点发送数据时

喜欢

{
    "a":1,
    "b":2 ,
    "c":3
}

我希望能够覆盖/添加键:值对到存储在方法中的这个传入有效request.data负载create

这不能通过简单的访问来完成,request.data因为它QueryDict是不可变的。

此外,我无法在该perform_create()方法中实现这一点,因为我可能注入的数据对验证至关重要。

目前我坚持使用以下解决方案,这需要我重写完整的create()方法:

class MyViewSet(viewsets.ModelViewSet):
    queryset = Sample.objects.all()
    serializer_class = MSampleSerializer
    name = "samples"

    def add_info(self, request):
        ...
        <acquire_info>
        ...
        data = request.data.dict()
        data["s"] = <info1>
        data["r"] = <info1>
        data["t"] = <info1>
        return data


    def create(self, request, *args, **kwargs):
        data = self.add_info(request)
        serializer = self.get_serializer(data=data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        headers = self.get_success_headers(serializer.data)
        return Response(
            serializer.data, status=status.HTTP_201_CREATED, headers=headers
        )
  1. request.data在调用任何操作方法(如create()or )之前是否有一种通用的方法来编辑put()

  2. 如果不是 1.); 有不同的可能性吗?

提前致谢。

4

1 回答 1

2

如果您不想每次都重写整个视图,可以使用序列化程序的.to_representation()or方法。.to_internal_value()

而且由于您也想验证数据,.to_representation()这可能是解决问题的方法。

从文档:

如果您需要更改序列化程序类的序列化或反序列化行为,可以通过覆盖.to_representation()or.to_internal_value()方法来实现。

.to_representation(self, obj)接受需要序列化的对象实例,并应返回原始表示。通常这意味着返回一个内置 Python 数据类型的结构。可以处理的确切类型取决于您为 API 配置的渲染类。

例子:

def to_representation(self, instance):
    """Convert `username` to lowercase."""
    ret = super().to_representation(instance)
    ret['username'] = ret['username'].lower()
    return ret

请参阅高级序列化程序用法:覆盖序列化和反序列化行为

于 2019-02-16T19:51:52.407 回答