Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is my DRF create function losing data before saving?

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

{'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

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading