Теряет ли моя функция создания DRF данные перед сохранением?

У меня есть следующий набор представлений DRF:

class RecordViewSet(ModelViewSet):
    queryset = Record.objects.all()
    serializer_class = RecordSerializer
    filterset_fields = ['task', 'workday']
    
    def get_workday(self, request):
        date = get_date_from_calendar_string(request.data['date'])
        obj, _ = Workday.objects.get_or_create(user=request.user, date=date)
        return obj.id
    
    def create(self, request):
        request.data['workday'] = self.get_workday(request)
        print(request.data)
        return super().create(request)

Метод create() не работает на не нулевом ограничении:

django.db.utils.IntegrityError: null value in column "task_id" violates not-null constraint
DETAIL:  Failing row contains (159, Added via task panel., 0, 0, 0, null, t, f, null, 98).

Однако, оператор печати в create() показывает, что данные, присутствующие в представлении:

{'minutes_planned': 5, 'description': 'Added via task panel.', 'minutes_worked': 5, 'task': 148, 'workday': 98}

По какой-то причине я не вижу pk для task (148) в сообщении об ошибке, что указывает мне на то, что оно где-то обрывается. Я не использую никаких сигналов и не переопределяю save() в модели. Что еще может быть причиной этой проблемы? Я только начал использовать DRF, так что это может быть что-то очевидное.

=====

Это модель:

class Record(models.Model):
    task = models.ForeignKey(Task, on_delete=models.CASCADE, related_name='records')
    workday = models.ForeignKey(Workday, on_delete=models.CASCADE, related_name='records')
    description = models.CharField(max_length=128, blank=True, null=True)
    minutes_planned = models.IntegerField(default=0)
    minutes_worked = models.IntegerField(default=0)
    minutes_worked_store = models.IntegerField(default=0)
    user_generated = models.BooleanField(default=True)
    completed = models.BooleanField(default=False)

и сериализатор:

class RecordSerializer(serializers.ModelSerializer):
    task = TaskSerializer(read_only=True)

    class Meta:
        model = Record
        fields = ['id', 'workday', 'description', 'completed', 'task', 'minutes_worked', 'minutes_planned']

Поскольку вы не предоставили код TaskSerializer, трудно сказать, что там происходит под капотом.

Мне кажется, что вы пытаетесь присвоить где-то task=148 вместо task_id=148. Обычно модель ожидает, что поле задачи будет экземпляром класса Task, а task_id может быть pk этого экземпляра.

Ваш TaskSerializer является read_only для RecordSerializer, который не позволяет записать это поле и поэтому будет проигнорирован на create.

Измените ваш код на следующий, должно работать

class RecordSerializer(serializers.ModelSerializer):
    task = TaskSerializer(read_only=True)
    task_id = serializers.PrimaryKeyRelatedField(queryset=models.Task.objects.all(), write_only=True)

https://www.django-rest-framework.org/api-guide/relations/#primarykeyrelatedfield

Вернуться на верх