Теряет ли моя функция создания 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