Reputation: 9194
I'm trying understand why this error occurs even though I know how to resolve. Just trying to understand DRF and Django better.
JSON in this format comes from the FE:
{
"username": "username_here",
"password": "password_here"
}
I have this view:
class UserSigninTokenAPIView(APIView):
permission_classes = [AllowAny]
serializer_class = UserSigninTokenSerializer
def post(self, request):
data = request.data
serializer = UserSigninTokenSerializer(data=data)
if serializer.is_valid(raise_exception=True):
new_data = serializer.data
return Response(new_data, status=HTTP_200_OK)
return Response(serializer.errors, status=HTTP_400_BAD_REQUEST)
Which uses this serializers:
class UserSigninTokenSerializer(ModelSerializer):
username = CharField()
class Meta:
model = USERS
fields = [
'username',
'password',
'id'
]
def validate(self, data):
username = data['username']
password = data['password']
user_qs = USERS.objects.filter(username__iexact=username)
if user_qs.exists() and user_qs.count() == 1:
user_obj = user_qs.first()
password_passes = user_obj.check_password(password)
if password_passes:
"""
A number of checks here I removed to keep this clean,
otherwise would just use /api/token/ to get a token.
I want user checks to pass before issuing a token,
because having the token is what indicates they are
logged in successfully.
"""
token = RefreshToken.for_user(user_obj)
return {
'refresh': str(token),
'access': str(token.access_token)
}
else:
Services.user_attempts(user_obj)
raise ValidationError({'error': '''
The credentials provided are invalid.
<br>Please verify the username and password are correct.
'''})
The username = CharField()
seems redundant to me. The documentation says:
The
ModelSerializer
class provides a shortcut that lets you automatically create aSerializer
class with fields that correspond to the Model fields.
I interpret this as saying just specifying the field = []
in the class Meta:
is sufficient for deserializing the JSON.
However, when I remove the username = CharField()
, I get a:
{
"username": [
"user with this username already exists."
]
}
The documentation for explicit specifications says:
You can add extra fields to a
ModelSerializer
or override the default fields by declaring fields on the class, just as you would for aSerializer
class.
This makes it sound optional, but apparently it is mandatory to specify it.
What am I missing here if someone wouldn't mind explaining?
Upvotes: 5
Views: 3720
Reputation: 1330
You are using a ModelSerializer
with your model and the request is POST
, there is no wonder why you are getting this.
ModelSerializer
is used to provide a quick standard serialization for CRUD operations, so when your request is POST
your serializer will assume that you are creating a new user with the request data for Users model so creation validators will be applied and as the username is unique..., you now the rest of the story.
Try to use a basic Serializer as you only want to read data it will be simpler
Upvotes: 10