Как изменить значение 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)
Вернуться на верх