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.