I have the following DRF viewset:
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)
The create() method is failing on a not-null constraint:
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).
However, the print statement in create() shows that the data present in the submission:
{'minutes_planned': 5, 'description': 'Added via task panel.', 'minutes_worked': 5, 'task': 148, 'workday': 98}
I am not seeing the pk for task (148) in the error statement for some reason, indicating to me that it is getting dropped somewhere. I am not using any signals, or overriding save() in the model. What else could be causing this problem? I’ve just started using DRF, so it might be something obvious.
=====
This is the model:
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)
and the serializer:
class RecordSerializer(serializers.ModelSerializer):
task = TaskSerializer(read_only=True)
class Meta:
model = Record
fields = ['id', 'workday', 'description', 'completed', 'task', 'minutes_worked', 'minutes_planned']
>Solution :
Your TaskSerializer is read_only for the RecordSerializer which does not allow writing that field and therefor will be ignored on create.
Change your code to the following should work
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