Skip to content
Advertisement

Django Rest Frame Work: passing User in djago rest frame work

I have a Django project as following code in model

class Report(models.Model):
    created_by_user=models.ForeignKey(User,on_delete=models.CASCADE)

following code in serializer

class ReportSerializer(serializers.ModelSerializer):
    class Meta:
        model=Report
        fields='__all__'

and following code in view

class ReportCreateView(APIView):
    def post(self,request, *args, **kwargs):
        received_data=ReportSerializer(data=request.data)
        if received_data.is_valid():
            received_data.save()
            return Response(received_data.data, status=status.HTTP_201_CREATED)
        return Response(received_data.errors,status.HTTP_400_BAD_REQUEST)

when I send a post request by postman and send username and password in Authorization tab it error:

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

but if I type username or password incorrect it will be

{
    "detail": "Invalid username/password."
}

can everybody help me?

Advertisement

Answer

Your serializer has no idea about the currently logged-in user.You to pass it as context from request. user or request.

I personally prefer CurrentUserDefault to be used in the serializer. To make it work we need to pass the request as context because CurrentUserDefault picks user from context request. We need to update our views and serializer code as follows

Views file: Add request as context context

class ReportCreateView(APIView):


def post(self,request, *args, **kwargs):
    received_data=ReportSerializer(data=request.data, context = {"request": request})
    if received_data.is_valid():
        received_data.save()
        return Response(received_data.data, status=status.HTTP_201_CREATED)
    return Response(received_data.errors,status.HTTP_400_BAD_REQUEST)

serializer.py: Update your serializer to auto-populate created_by_user

class ReportSerializer(serializers.ModelSerializer):
    created_by_user = serializers.HiddenField(default=serializers.CurrentUserDefault())
    
    class Meta:
        model=Report
        fields='__all__'

It will solve your user field required issue.

"created_by_user": ["This field is required."]

Now coming to your next part of the issue that is related to incorrect passwords.

By default, APIView picks the default authentication class from settings. Inside projects settings.py, we mostly write these lines while using DRF and they serve as default authentication for APIView:

From settings.py

REST_FRAMEWORK = {
    # Use Django's standard `django.contrib.auth` permissions,
    # or allow read-only access for unauthenticated users.
    "DEFAULT_PERMISSION_CLASSES": [
        "rest_framework.permissions.IsAuthenticated",
    ],
    # Authentication settings
    "DEFAULT_AUTHENTICATION_CLASSES": [
        "rest_framework.authentication.SessionAuthentication",
    ],
   ...
}

Inside APIView you can have a look at default permission_classes, and authentication_classes

From inside APIView:

    authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
    throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
    permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES

that is when you type an invalid password:

"detail": "Invalid username/password."

Provide the correct username and password to your APIView from postman so that it gets the requested logged-in user for auto-populates at DB level.

Advertisement