Как изменить значение HttpRequest.body в django?
Я получаю объект HttpRequest
в моей функции представления. Я хочу изменить определенное ключевое значение этого запроса.
В настоящее время я делаю следующее -
def myview(request):
request._body['key1'] = 'value1' # where 'key1' already exists in request body
...
Но это дает ошибку: TypeError: 'bytes' object does not support item assignment
Вы не можете изменить атрибут _body
с помощью _body['key1'] = 'value1'
, поскольку тело - это просто содержимое HTTP-запроса, это не объект, похожий на словарь. Это объект двоичного потока.
Если это тело имеет определенный формат, например JSON, вы можете сначала разобрать его в JSON, затем изменить этот JSON-объект, а затем сериализовать его и установить сериализованный JSON-объект в качестве ._body
. Таким образом, это выглядит следующим образом:
import json
myjson = json.loads(request.body)
myjson['key1'] = 'value1'
request._body = json.dumps(myjson)
Для пустого объекта JSON, таким образом, мы можем работать с:
>>> from django.http import HttpRequest
>>> request = HttpRequest()
>>> request._body = b'{}'
>>> hr.body
b'{}'
>>> import json
>>> myjson = json.loads(request.body)
>>> myjson['key1'] = 'value1'
>>> request._body = bytes(json.dumps(myjson), encoding='utf-8')
>>> request.body
b'{"key1": "value1"}'
но это будет работать (эффективно) только если тело действительно является JSON блобом. Если это другой формат, например, urlencoded, то вам понадобится другой "читатель" и "писатель".
Если вы работаете в ModelViewSet
, вы не можете применить этот "трюк" в методе типа create
, так как тогда будет уже поздно: в этот момент парсер уже выполнился и сохранил данные в request.data
.
Таким образом, вы должны переопределить initialize_request
, например, с помощью:
from rest_framework.viewsets import ModelViewSet
class MyModelViewSet(ModelViewSet):
def initialize_request(self, request, *args, **kwargs):
myjson = json.loads(request.body)
myjson['key1'] = 'value1'
request._body = bytes(json.dumps(myjson), encoding='utf-8')
return super().initialize_request(request, *args, **kwargs)