DRF не будет отправлять необработанную строку JSON в браузер. он возвращает строку, которая является JSON, хотите обойти вызов json.load - PullRequest
0 голосов
/ 28 августа 2018

У нас есть большие BLOB-объекты JSON, хранящиеся в базе данных, которую мы хотим передать внешнему интерфейсу с помощью DRF.

Вместо того, чтобы анализировать эту строку JSON с последующим ее декодированием, можем ли мы просто вернуть саму строку JSON?

Например, есть ли способ отправить его на веб-интерфейс:

Response({ 'json': '{"example": "json-from-database"}' }, status=status.HTTP_200_OK)

Прямо сейчас это создаст нежелательный ответ JSON, который выглядит следующим образом:

{ 'json': '{"example": "json-from-database"}' }

Мы хотим, чтобы он создал ответ JSON, который выглядит следующим образом:

{ 'json': {"example": "json-from-database"} }

Есть ли способ отправить «сырой» ответ JSON внешнему интерфейсу без необходимости анализировать / декодировать нашу существующую строку JSON?

В данный момент мы используем json.load.

Редактировать, уточнять:

Клиент видит ответ JSON, но у него есть свойство, содержащее строку JSON. Поскольку JSON уже действителен, я просто хочу вернуть строку и заставить клиента потреблять вместо Python попытку разобрать / декодировать ее.

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

Использование JSONField сериализатора DRF

#serializer.py
from rest_framework import serializers


class Myserializer(serializers.Serializer):
    myjson = serializers.JSONField()


#views.py
class MyView(....):
    .....
    myjson = {"myjson":{some requeried json}}
    serializer = Myserializer(myjson)
    serializer.is_valid(True)
    return Response(data=serializer.data)
0 голосов
/ 28 августа 2018

Хорошо, ваш вопрос немного сбивает с толку, но остановлюсь на этом: «Я выполнил редактирование, которое, возможно, прояснит его. Я просто не хочу, чтобы Response запускал свой кодировщик для данных, переданных ему. Я хочу исключение, когда это позволяет мне возвращать «сырую» строку JSON. «Я думаю, вы просто хотите пропустить анализ синтаксического анализа на стороне сервера? Если так:

database_json = '{"from": ["the", "database"]}'
raw_json = '{"json": {"example": %s}}' % database_json
return HTTPResponse(raw_json, content_type='application/json')

Если вам нужна некоторая валидация / гибкость в частях JSON и JSON, то это немного сложнее, и вам придется создать собственный кодировщик и обезьянить патч для экранирующей строки (поскольку она будет экранирована двойные кавычки).:

from contextlib import contextmanager
import json

class RawJSON(str):
  def __init__(self, raw_json):
    return super(RawJSON, self).__init__(raw_json)


class JSONEncoderWithRawSupport(json.JSONEncoder):
  @contextmanager
  def patched_encoder(self):
    default_encoder = json.encoder.encode_basestring_ascii

    def _encode(o):
        if isinstance(o, RawJSON):
            return o
        return default_encoder(o)
    json.encoder.encode_basestring_ascii = _encode
    yield
    json.encoder.encode_basestring_ascii = default_encoder

  def iterencode(self, *args, **kwargs):
    with self.patched_encoder():
        return super(JSONEncoderWithRawSupport, self).iterencode(*args, **kwargs)     


database_json = RawJSON('{"from": ["the", "database"]}')
my_dict = {"json": {"example": database_json}}
my_json = json.dumps(my_dict, cls=JSONEncoderWithRawSupport)
return HTTPResponse(my_json, content_type='application/json')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...