Отправка json

Последнее обновление: 19.08.2022

За отправку клиенту данных в формате JSON в Django отвечает специальный класс - JsonResponse, который по сути представляет подкласс HttpResponse. Основная особенность JsonResponse состоит в том, что при отправке данных он автоматически устанавливает для заголовка Content-Type (тип содержимого) значение application/json

Его конструктор принимает ряд параметров:

def __init__(data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None, **kwargs)
  • data: отправляемые данные

  • encoder: сериализатор, которые сериализует отправляемые данные в формат JSON. По умолчанию представляет тип django.core.serializers.json.DjangoJSONEncoder

  • safe: представляет булевое значение. Если равно False, то сериализации подлежит любой объект. Если же равно True, то отправляемые данные должны представлять тип dict - то есть словарь. По умолчанию равно True

  • json_dumps_params: словарь аргументов, который передается в функцию json.dumps() для генерации ответа

Например, отправим какие-нибудь данные в формате JSON. Для этого определим в файле views.py следующий код:

from django.http import JsonResponse

def index(request):
    return JsonResponse({"name": "Tom", "age": 38})

В данном случае отправляется словарь с двумя элементами name и age. И при обращении в браузере к функции index мы увидим эти данные:

Отправка json с помощью JsonResponse в веб-приложении на Django и python

Сериализация произвольных объектов

По умолчанию JsonResponse сериазует и отправляет только словари. Однако что, если мы хотим отправить объект какого-то своего типа? В этом случае неоьходимо определить класс-сериализатор, который будет содержать логику сериализации объекта в json. Например:

from django.http import JsonResponse
from django.core.serializers.json import DjangoJSONEncoder

def index(request):
    bob = Person("Bob", 41)
    return JsonResponse(bob, safe=False, encoder=PersonEncoder)

class Person:
 
    def __init__(self, name, age):
        self.name = name    # имя человека
        self.age = age        # возраст человека

class PersonEncoder(DjangoJSONEncoder):
    def default(self, obj):
        if isinstance(obj, Person):
            return {"name": obj.name, "age": obj.age}
            # return obj.__dict__
        return super().default(obj)

В данном случае JsonResponse отправляет объект типа Person, у которого определены два атрибута: name и age.

Объект Person не является словарем, поэтому параметр safe имеет значение False. Кроме того, параметр encoder указывает на сериализатор, который будет сериализовать данные в json. В данном случае это класс PersonEncoder.

Класс сериализатора наследуется от django.core.serializers.json.DjangoJSONEncoder. Он реализует метод default, который возвращает сериализованный объект. В частности, в этом методе сначала проверяем, представляет ли параметр объект Person. И если представляет, то возвращаем словарь из значений атрибутов объекта

return {"name": obj.name, "age": obj.age}

Стоит отметить, что в данном случае мы можем просто возвратить представление объекта в виде словаря

return obj.__dict__

Однако в отдельных ситуациях может потребоваться более тонкая настройка сериализации.

Если же объект не представляет тип Person, то передаем его в реализацию метода default родительского класса.

Результат при обращении в браузере:

Кастомная сериализация в json с помощью DjangoJSONEncoder в веб-приложении на Django и python
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850