I am making an app where assigner can assign tasks to assignee when i run the server and try to add a task i get this error:
NOT NULL constraint failed: tasks_tasks.assigner_id
here is my views:
from rest_framework import viewsets, permissions
from .models import Tasks
from .serializers import TasksSerializer, UserSerializer
from django.contrib.auth.models import User
class UserViewSet(viewsets.ReadOnlyModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer
class TasksViewSet(viewsets.ModelViewSet):
queryset = Tasks.objects.all()
serializer_class = TasksSerializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
def prefrom_create(self, serializer):
serializer.save(self, assigner=self.request.user)
here is my serializers.py
from rest_framework import serializers
from .models import Tasks
from django.contrib.auth.models import User
class TasksSerializer(serializers.ModelSerializer):
assigner = serializers.ReadOnlyField(source='assigner.username')
class Meta:
model = Tasks
fields = ('id', 'url', 'title', 'description', 'assigner', 'assignee')
class UserSerializer(serializers.ModelSerializer):
tasks = serializers.HyperlinkedIdentityField(many=True, view_name='tasks_details', read_only=True)
class Meta:
model = User
fields = ('id', 'url', 'username', 'tasks')
and finally my models.py:
from django.db import models
class Tasks(models.Model):
created = models.DateTimeField(auto_now_add=True)
title = models.CharField(max_length=100)
description = models.TextField()
assigner = models.ForeignKey('auth.User', related_name='tasks', on_delete=models.CASCADE)
assignee = models.ForeignKey('auth.User', related_name='assigned', on_delete=models.CASCADE)
class Meta:
ordering = ('created',)
You've made assigner
a read only field with source assigner.username
-this is your problem. I think you could get around this by defining two fields instead, one read_only and one write_only:
class TasksSerializer(serializers.ModelSerializer):
assigner_name = serializers.ReadOnlyField(source='assigner.username')
assigner = serializers.PrimaryKeyRelatedField(write_only=True, queryset=User.objects.all(), required=True)
class Meta:
model = Tasks
fields = ('id', 'url', 'title', 'description', 'assigner', 'assignee', 'assigner_name')
The effect of this code is that when your serializer is 'writing' (de-serializing) it will accept the assigner id which you pass into the save method as the keyword argument assigner
. When it then serializes the task to json, it will look for the assigner.name
and return it under the key assigner_name
and miss out assigner
.
In the view, you'd then pass in the primary key (rather than the whole object) to the serializer save method:
serializer.save(assigner=self.request.user.pk)