Ответ
SerializerMethodField — это специальное поле в Django REST Framework (DRF), которое позволяет добавлять в сериализатор произвольные вычисляемые значения, не хранящиеся напрямую в модели. Оно вызывает метод, определённый в сериализаторе, и возвращает его результат.
Почему используется? Это поле идеально подходит для случаев, когда необходимо:
- Вычислить данные: Например, объединить
first_nameиlast_nameвfull_name. - Агрегировать данные: Подсчитать количество связанных объектов.
- Форматировать данные: Изменить формат даты или числа.
- Включить данные из несвязанных источников: Добавить информацию, полученную из другого API или сервиса.
Пример использования:
Предположим, у нас есть модель User с полями first_name и last_name, и мы хотим получить full_name в сериализованном ответе.
from rest_framework import serializers
from django.contrib.auth.models import User # Пример модели
class UserSerializer(serializers.ModelSerializer):
# Объявляем SerializerMethodField
full_name = serializers.SerializerMethodField()
is_staff_member = serializers.SerializerMethodField()
class Meta:
model = User
fields = ['id', 'username', 'full_name', 'is_staff_member']
# Метод для поля full_name. Должен начинаться с 'get_' и принимать объект модели.
def get_full_name(self, obj: User) -> str:
return f"{obj.first_name} {obj.last_name}"
# Метод для поля is_staff_member
def get_is_staff_member(self, obj: User) -> bool:
return obj.is_staff
# Пример использования (в представлении или тесте)
# user = User.objects.first()
# serializer = UserSerializer(user)
# print(serializer.data)
# # Вывод: {'id': 1, 'username': 'john_doe', 'full_name': 'John Doe', 'is_staff_member': False}
Ключевые особенности:
- Именование метода: Метод, который вычисляет значение для поля, должен быть назван
get_<field_name>(например,get_full_name). - Аргументы метода: Метод принимает один обязательный аргумент —
obj, который является экземпляром модели, сериализуемой в данный момент. - Доступ к контексту: Внутри метода можно получить доступ к контексту сериализатора через
self.context(например, для передачи данных из представления). - Только для чтения:
SerializerMethodFieldпо умолчанию является полем только для чтения (read_only=True), то есть его значение не используется при создании или обновлении объектов.