Stefan
Stefan

Reputation: 25

Integrity error owner_id DRF

I created a simple model API with Django Rest Framework.. For the most part i followed quick start tutorial on DRF site. I am accessing it from angular app using Authorization token. Everything works fine except when i wish to make a new post...

This is the error I get null value in column "owner_id" violates not-null constraint

This is my code: models.py

class Post(models.Model)
    title = models.CharField(max_length=100, blank=False)
    point = models.PointField(max_length=255, null=True)
    owner = models.ForeignKey('auth.User', related_name='posts')
    active = models.NullBooleanField()
    created = models.DateTimeField(auto_now_add=True)
    expires = models.DateTimeField(blank=True, null=True)

serializers.py

class PostSerializer(serializers.ModelSerializer):
    owner = serializers.ReadOnlyField(source='owner.username')

    class Meta:
        model = Post
        fields = ( 'owner', 'id', 'title', 'point', 'active', 'created', 'expires')

views.py

class PostList(APIView):
    permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

    def post(self, request, format=None):
        serializer = PostSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def perform_create(self, serializer):
        serializer.save(owner=self.request.user)

Thanks.

Upvotes: 1

Views: 1108

Answers (1)

Mad Wombat
Mad Wombat

Reputation: 15105

OK, lets take this one step at a time. First, perform_create() method is defined in the create mixin that is used by ModelViewSet. Overriding it in the APIView derived view class doesn't do anything. So your Post creation is all handled by the post() method. The easiest way to fix the error is to add owner=self.request.user to your serializer.save() call in post().

That said, you might want to consider redefining the whole thing as a ModelViewSet, since you will likely need a full set of CRUD APIs anyway.

class PostViewSet(viewsets.ModelViewSet):
    class Meta:
        queryset = Post.objects.all()
        serializer_class = PostSerializer
        permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

    def perform_create(self, serializer):
        serializer.save(user=self.request.user)

Upvotes: 3

Related Questions