Search code examples
djangoswaggerpyjwt

Sending foreign key as argument resulting in This Field is Required Error


I am trying to create an app where Users can login and create tasks. The code for my django app is hosted here

I am using JWT authentication and drf-yasg to generate swagger. So the TaskSerializer takes 3 arguments

  • taskname which is a string
  • completion which is a boolean
  • username which should point to the user model

My TaskModel is as follows

class Tasks(models.Model):
    taskname=models.CharField(max_length=10)
    completion=models.BooleanField(default=False)
    username = models.ForeignKey(User, on_delete=models.CASCADE)

My TaskSerializer is

class TaskSerializer(serializers.ModelSerializer):
    class Meta:
        model = Tasks
        fields = ['taskname', 'completion', 'username']

My TaskView is as follows:

class TaskView(APIView):
    def get(self, request):
        token = request.COOKIES.get('jwt')
        if not token:
            raise AuthenticationFailed('Unauthenticated!')

        try:
            payload = jwt.decode(token, 'secret', algorithms=['HS256'])
        except jwt.ExpiredSignatureError:
            raise AuthenticationFailed('Unauthenticated!')

        tasks = Tasks.objects.filter(username=payload['username']).all()
        return Response(tasks)

    @swagger_auto_schema(
        request_body=openapi.Schema(
            type=openapi.TYPE_OBJECT,
            properties={
                'taskname': openapi.Schema(type=openapi.TYPE_STRING, description='Add taskname'),
                'completion': openapi.Schema(type=openapi.TYPE_BOOLEAN, description='completion'),
            }
        )
    )
    def post(self, request):
        token = request.COOKIES.get('jwt')
        if not token:
            raise AuthenticationFailed('Unauthenticated!')

        try:
            payload = jwt.decode(token, 'secret', algorithms=['HS256'])
        except jwt.ExpiredSignatureError:
            raise AuthenticationFailed('Unauthenticated!')
        req_data = {
            "username": User.objects.filter(username=payload['username']).first(),
            "taskname": request.data['taskname'],
            "completion": request.data['completion'],
        }
        print(5*'*', req_data)
        serializer = TaskSerializer(
            data=request.data
        )
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)

However, when I create a task I can retrieve the user from the token and I send the post request via swagger to /task, I get the following error:

{
  "username": [
    "This field is required."
  ]
}

Solution

  • you are sending wrong data to serializer. it should be like:

    serializer = TaskSerializer(data=req_data)