DRF :将附加信息注入 request.data 的通用方法
DRF : Generic way to inject additional info into request.data
我的情况是我有一个端点 samples
,它通过 ModelViewSet
表示模型 sample
。
我的目标是,当用户 POST 使用数据
攻击此端点时
喜欢
{
"a":1,
"b":2 ,
"c":3
}
我希望能够 override/add key:value 与 create
方法中存储在 request.data
中的传入有效载荷配对。
这不能通过简单地访问 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
)
在调用任何操作方法(如 create()
或 put()
之前,是否有通用的方法来编辑 request.data
?
如果不是1.);有不同的可能性吗?
提前致谢。
如果您不想每次都重写整个视图,您可以使用序列化程序的 .to_representation()
或 .to_internal_value()
方法。
并且由于您也想验证数据,.to_representation()
可能是解决此问题的方法。
来自文档:
If you need to alter the serialization or deserialization behavior of a serializer class, you can do so by overriding the .to_representation()
or .to_internal_value()
methods.
.to_representation(self, obj)
takes the object instance that requires serialization, and should return a primitive representation. Typically this means returning a structure of built-in Python datatypes. The exact types that can be handled will depend on the render classes you have configured for your API.
示例:
def to_representation(self, instance):
"""Convert `username` to lowercase."""
ret = super().to_representation(instance)
ret['username'] = ret['username'].lower()
return ret
见Advanced serializer usage: Overriding serialization and deserialization behavior
我的情况是我有一个端点 samples
,它通过 ModelViewSet
表示模型 sample
。
我的目标是,当用户 POST 使用数据
攻击此端点时喜欢
{
"a":1,
"b":2 ,
"c":3
}
我希望能够 override/add key:value 与 create
方法中存储在 request.data
中的传入有效载荷配对。
这不能通过简单地访问 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
)
在调用任何操作方法(如
create()
或put()
之前,是否有通用的方法来编辑request.data
?如果不是1.);有不同的可能性吗?
提前致谢。
如果您不想每次都重写整个视图,您可以使用序列化程序的 .to_representation()
或 .to_internal_value()
方法。
并且由于您也想验证数据,.to_representation()
可能是解决此问题的方法。
来自文档:
If you need to alter the serialization or deserialization behavior of a serializer class, you can do so by overriding the
.to_representation()
or.to_internal_value()
methods.
.to_representation(self, obj)
takes the object instance that requires serialization, and should return a primitive representation. Typically this means returning a structure of built-in Python datatypes. The exact types that can be handled will depend on the render classes you have configured for your API.
示例:
def to_representation(self, instance):
"""Convert `username` to lowercase."""
ret = super().to_representation(instance)
ret['username'] = ret['username'].lower()
return ret
见Advanced serializer usage: Overriding serialization and deserialization behavior