Ответ
Метод create() в сериализаторе Django REST Framework (DRF) вызывается, когда вы сохраняете новый объект через serializer.save() и сериализатор был инициализирован без существующего экземпляра (instance=None или не передан).
Назначение: Этот метод предназначен для реализации пользовательской логики создания объекта, которая выходит за рамки простого сохранения полей модели. Например:
- Создание связанных объектов.
- Выполнение дополнительных действий после создания (отправка уведомлений).
- Хеширование паролей или другая обработка данных перед сохранением.
Метод create() принимает один аргумент: validated_data (словарь проверенных данных) и должен вернуть созданный экземпляр модели.
Пример:
Предположим, нам нужно создать пользователя с хешированным паролем, используя метод create_user модели User.
from rest_framework import serializers
from django.contrib.auth.models import User # Пример модели пользователя
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['username', 'email', 'password']
extra_kwargs = {'password': {'write_only': True}} # Пароль только для записи
def create(self, validated_data):
# Извлекаем пароль, чтобы передать его в create_user
password = validated_data.pop('password', None)
user = User.objects.create_user(**validated_data)
if password:
user.set_password(password) # Хешируем и устанавливаем пароль
user.save()
return user
# Использование в представлении (например, для POST-запроса):
# from rest_framework.response import Response
# from rest_framework import status
# serializer = UserSerializer(data=request.data)
# if serializer.is_valid():
# user = serializer.save() # Здесь будет вызван метод create()
# return Response(user.username, status=status.HTTP_201_CREATED)
Важно: Если сериализатор инициализирован с существующим объектом (serializer = UserSerializer(instance=user, data=...)), то при вызове serializer.save() вместо create() будет вызван метод update().
Ответ 18+ 🔞
А, ну это про метод create() в DRF, да? Так, слушай, это ж та самая штука, которая выстреливает, когда ты через serializer.save() новый объект в базу пихаешь, и сериализатору не подсунули старый экземпляр, чтобы обновить. То есть, чистый, девственный POST-запрос, понимаешь?
Зачем он вообще, этот create()?
Ну, блядь, иногда же мало просто взять данные и запихнуть их в модель как есть, как дурак. Бывает же логика какая-то, ёпта! Например:
- Надо ещё кучу связанных объектов налепить.
- Или после создания письмо какое-нибудь отправить, типа «добро пожаловать, лох».
- Или, там, пароль хешировать, а не хранить как есть, чтобы потом не охуеть от стыда.
Метод этот принимает один аргумент — validated_data. Это такой уже проверенный, чистый словарь с данными, которые можно в рот брать. И он обязан вернуть тебе готовый, сохранённый в базе экземпляр модели. Не хухры-мухры, а конкретный объект.
Смотри, как это выглядит на практике, ёбана: Допустим, нам надо пользователя создать, но пароль хешировать, а не в открытом виде хранить, как какой-то распиздяй.
from rest_framework import serializers
from django.contrib.auth.models import User # Ну, стандартная модель пользователя
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['username', 'email', 'password']
extra_kwargs = {'password': {'write_only': True}} # Пароль, сука, только для записи, чтоб не светить
def create(self, validated_data):
# Вытаскиваем пароль из словаря, чтобы его отдельно обработать
password = validated_data.pop('password', None)
# Создаём юзера, но пока без пароля
user = User.objects.create_user(**validated_data)
if password:
user.set_password(password) # Вот тут магия хеширования, блядь!
user.save()
return user # Возвращаем готового пользователя, как и положено
# А в каком-нибудь View это будет использоваться так:
# serializer = UserSerializer(data=request.data)
# if serializer.is_valid():
# user = serializer.save() # БАМ! Вот тут-то и вызывается наш кастомный create()
# return Response(user.username, status=status.HTTP_201_CREATED)
Важный момент, на котором все обжигаются, как дураки: Если ты сериализатору скормил уже существующий объект (типа serializer = UserSerializer(instance=user, data=...)), то при save() вызовется уже не create(), а update(). DRF сам соображает, что ты тут делаешь — рожаешь нового или старика переделываешь. В общем, не тупи.