Search code examples
djangorestauthenticationforeign-keyssave

Django Rest FrameWork Add Model With User Foreign Key


I'm using Django version 3 and the Rest Framework, i have a model with a user foreignkey.
so every time a model is saved the user also need to be saved.
To be able to add or to edit a model via rest you need to be authenticated using token authentication.
I'm using ClassBasedViews, the problem is that i can't find a way to add a model because in my serializer the field user is excluded because i don't want it to be editable.

models.py:

class Chambre(models.Model):
    local_id=models.PositiveIntegerField(unique=True)
    nom=models.CharField(max_length=255)
    user=models.ForeignKey(User,on_delete=models.CASCADE,blank='true')

    class Meta:
        unique_together = ('local_id', 'user',)

serializers.py:

class ChambreSerializer(serializers.ModelSerializer):
    class Meta:
        model = Chambre
        exclude =['user',] 

views.py:

class ChambreListApi(APIView):
"""
List all chambres, or create a new chambre.
"""
    authentication_classes=(TokenAuthentication,)
    permission_classes=(IsAuthenticated,)


    def get(self, request, format=None):
        chambres = Chambre.objects.filter(user=request.user)
        serializer = ChambreSerializer(chambres, many=True)
        return Response(serializer.data)

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

Solution

  • Try moving the logic that sets the user to the serializer. By default GenericAPIView will pass the request to the serializer via the context.

    class ChambreSerializer(serializers.ModelSerializer):
        class Meta:
            model = Chambre
            exclude =['user',]
    
        def create(self, validated_data):
            validated_data["user"] = self.context["request"].user
            return super().create(validated_data)