Значение по умолчанию отсутствует в проверенных данных вложенного сериализатора во время обновления

#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 будет добавляться автоматически.