#python #django #django-rest-framework
#python #django #django-rest-framework
Вопрос:
Я пытаюсь реализовать update
-метод для вложенных представлений в Django Rest Framework.
from django.db import models
from django.utils import timezone
from rest_framework import serializers
class Foo(models.Model):
pass
class Bar(models.Model):
foo = models.ForeignKey(Foo, on_delete=models.CASCADE, null=False, related_name='bars')
name = models.CharField(max_length=255)
create_date = models.DateField(null=False)
class BarSerializer(serializers.ModelSerializer):
create_date = serializers.DateField(default=timezone.now)
class Meta:
model = Bar
fields = ('name', 'create_date',)
class FooSerializer(serializers.ModelSerializer):
bars = BarSerializer(many=True, required=False)
def create(self, validate_data):
bars_data = validated_data.pop('bars', [])
foo = Foo.objects.create(**validated_data)
for bar_data in bars_data:
Bar.objects.create(foo=foo, **bar_data)
return foo
def update(self, instance, validated_data):
bars_data = validated_data.pop('bars', None)
if bars_data is not None:
Bar.objects.filter(foo=instance).delete()
for bar_data in bars_data:
Bar.objects.create(foo=instance, **bar_data)
return super().update(instance, validated_data)
class Meta:
model = Foo
fields = ('bars',)
При создании объекта я получаю ожидаемые результаты, но всякий раз, когда я хочу обновить список баров, не предоставляя create_date
, я получаю сообщение об ошибке, в котором говорится, что этого create_date
не может быть None
(что правильно):
django.db.utils.Ошибка целостности: сбой ограничения NOT NULL: myapp_bar.create_date
Если я печатаю bars_data
внутри update
, я вижу, что оно не получает значение по умолчанию из timezone.now
. Его вообще нет в словаре.
Как мне получить доступ к значению по умолчанию здесь? Оно должно было пройти проверку сериализатора, почему не добавляется значение по умолчанию?
Ответ №1:
Из документов:
default
Не применяется во время операций частичного обновления. В случае частичного обновления только поля, которые предоставлены во входящих данных, будут иметь возвращенное проверенное значение.
Итак, вам придется добавить значение вручную:
Bar.objects.create(foo=instance, **bar_data, create_date=timezone.now)
Ответ №2:
Вы получаете эту ошибку, потому что в вашей модели Bar атрибут create_date имеет значение null = False, если вы хотите значение по умолчанию, предпочтительнее использовать аргументы auto_now или auto_now_add в атрибуте created_date в вашей модели Bar следующим образом:
class Bar(models.Model):
...
created_date = models.DateField(auto_now_add=True)
При этом каждый раз, когда вы создаете новый экземпляр Bar, create_date будет добавляться автоматически.