Как мне убедить JsonResponse сериализовать настраиваемый класс? - PullRequest
0 голосов
/ 27 мая 2020

Я использую Django 3.0.6 с Python 3.7.

Мои представления / контроллеры возвращают JsonResponse, вот так:

    return JsonResponse({
        'My IP string': champion.ip_string,
        'Chiefdom full name': chiefdom.FullName(),
        'Chiefdom': chiefdom, # This will raise an exception
    })

Я бы хотел до обновить класс Chiefdom , чтобы он вел себя хорошо с JsonResponse.

Самый очевидный способ сделать это для меня - переопределить метод , который JsonResponse собирается позвонить, чтобы сериализовать это (я думаю? Это должно, давай ...), но ... я не смог найти никакой информации по этому поводу.

Весь смысл этот вопрос НЕ изменяет ВИД . Измените только сам класс Chiefdom таким образом, чтобы затем JsonResponse внезапно решил, что «ну ладно, теперь он действительно сериализуемый».

Я мог найти только информацию, которая включает изменение самого представления, или фигня еще более запутанная. Там тонны и тонны не относящейся к делу информации, и если то, что я ищу, есть где-то там, значит, это было похоронено под грудой всякой всячины.

Ответы [ 2 ]

1 голос
/ 27 мая 2020

передать пользовательский кодировщик , указав параметр encoder.

По умолчанию JsonResponse использует django.core.serializers.json.DjangoJSONEncoder класс.

Пример:

from django.core.serializers.json import DjangoJSONEncoder


class <b>MyCustomEncoder</b>(DjangoJSONEncoder):
    ...


def sample_view(request):
    return JsonResponse({
        'My IP string': champion.ip_string,
        'Chiefdom full name': chiefdom.FullName(),
        'Chiefdom': chiefdom,  # This will raise an exception
    }, <b>encoder=MyCustomEncoder</b>)
0 голосов
/ 27 мая 2020

Спасибо Араккалу Абу за его ответ .

Решение, которое вообще не требует изменения взглядов (за исключением для изменения импорта), это один:

from django.http import JsonResponse as JsonResponseSuper

class JsonEncoder (DjangoJSONEncoder):
    def default (self, obj):
        if callable(getattr(obj, "toJSON", None)):
            return obj.toJSON()

        return super(obj)

def JsonResponse (obj):
    return JsonResponseSuper(obj,encoder=JsonEncoder)

А затем создайте метод toJSON в классе Chiefdom:

    def toJSON (self):
        return {
            'IP': self.ip_string,
            'Name': self.dbObject.name,
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...