Ответ
В Django REST Framework для создания или обновления экземпляра модели из данных сериализатора используется метод .save().
Этот метод можно вызывать только после успешной валидации данных с помощью serializer.is_valid().
Как работает .save():
В зависимости от того, как был инициализирован сериализатор, .save() вызывает один из двух методов:
.create(validated_data)— если сериализатор был создан только сdata(создание нового объекта)..update(instance, validated_data)— если сериализатор был создан сinstanceиdata(обновление существующего объекта).
Пример создания (Create):
# request.data = {'name': 'New Product', 'price': 150.0}
serializer = ProductSerializer(data=request.data)
if serializer.is_valid():
# Вызывает ProductSerializer.create()
new_product = serializer.save()
# new_product - это созданный экземпляр модели Product
Пример обновления (Update):
product_instance = Product.objects.get(pk=1)
# request.data = {'price': 200.0}
serializer = ProductSerializer(instance=product_instance, data=request.data, partial=True)
if serializer.is_valid():
# Вызывает ProductSerializer.update()
updated_product = serializer.save()
# updated_product - это обновленный экземпляр
Метод .save() также может принимать дополнительные аргументы, которые будут переданы в .create() или .update(). Это полезно для установки полей, которые не приходят от клиента, например, owner:
serializer.save(owner=request.user) Ответ 18+ 🔞
А, слушай, ну вот смотри, тут про Django REST Framework речь. Есть у них такой магический метод .save(). Ну, не то чтобы магический, но без него нихуя не работает, когда нужно записать данные из сериализатора в базу — либо создать новую запись, либо обновить старую.
Но, внимание, ёпта, важный момент! Эту штуку можно вызывать только после того, как данные прошли валидацию. То есть ты сначала делаешь serializer.is_valid(), и если он не сказал, что всё хуёво, только тогда уже можно .save() пинать. Иначе — пиздец, исключение полети́т, и всё накроется медным тазом.
Как эта хрень работает внутри:
Всё зависит от того, как ты сериализатор инициализировал. Метод .save() сам догадается, что ему делать:
.create(validated_data)— вызовется, если ты передал в сериализатор толькоdata. Это значит «создай мне новый объект, блядь»..update(instance, validated_data)— вызовется, если ты передал иinstance(существующий объект), иdata. Это уже «обнови эту старую хуйню».
Пример, когда мы создаём что-то новое (Create):
# Допустим, пришло request.data = {'name': 'Новый Продукт', 'price': 150.0}
serializer = ProductSerializer(data=request.data)
if serializer.is_valid(): # Проверили, что данные не бредовые
# Тут вызывается внутренний метод ProductSerializer.create()
new_product = serializer.save()
# И вот new_product — это уже свежеиспечённый экземпляр модели Product, лежит в базе!
А вот пример, когда мы старую запись обновляем (Update):
# Нашли в базе старый продукт
product_instance = Product.objects.get(pk=1)
# Пришло request.data = {'price': 200.0} (только цену поменять хотим)
serializer = ProductSerializer(instance=product_instance, data=request.data, partial=True) # partial=True — чтобы можно было не все поля слать
if serializer.is_valid():
# А тут уже вызовется ProductSerializer.update()
updated_product = serializer.save()
# И updated_product — это тот же самый объект, но уже с новой ценой, охуенно!
И ещё фишка, блядь! В .save() можно передать дополнительные аргументы, которые просочатся прямо в .create() или .update(). Зачем? Ну, например, чтобы проставить поле owner, которое от клиента не приходит, а берётся из запроса:
serializer.save(owner=request.user) # Типа «вот хозяин объекта, запоминай»
Вот и вся магия, не так страшен чёрт, как его малюют. Главное — валидируй перед сохранением, а то будет тебе волнение ебать и терпения ноль ебать.