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']
CodePudding user response:
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
CodePudding user response:
Since you didn't provide the code of the TaskSerializer, it's hard to say what happens there under the hood.
It looks to me that you are trying to assign somewhere task=148
instead of task_id=148
. Normally the model expects that the task field will be and instance of class Task
, while task_id
can be the pk
of this instance.