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

Я пытаюсь реализовать метод 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.IntegrityError: Сбой ограничения NOT NULL: myapp_bar.create_date

Если я напечатаю bars_data внутри update, я вижу, что он не получает значение по умолчанию от timezone.now. Его нет в словаре вообще.

Как мне получить доступ к значению по умолчанию здесь? Он должен был пройти проверку сериализатора, почему не добавлено значение по умолчанию?

Ответы [ 2 ]

1 голос
/ 05 марта 2019

Из документов :

default не применяется во время операций частичного обновления. В случае частичного обновления только поля, предоставленные во входящих данных, будут иметь возвращенное проверенное значение.

Итак, вам нужно будет добавить значение вручную:

Bar.objects.create(foo=instance, **bar_data, create_date=timezone.now)
0 голосов
/ 05 марта 2019

Вы получаете эту ошибку, потому что в вашей модели Bar атрибут create_date имеет значение null = False, если вы хотите использовать значение по умолчанию, предпочтите использовать auto_now или auto_now_add аргументы в атрибуте selected_date вашей модели Bar, например:

class Bar(models.Model):
    ...
    created_date = models.DateField(auto_now_add=True)

При этом каждый раз, когда вы создаете новый экземпляр Bar, автоматически добавляется дата создания.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...