Creating a Django API and want to login the user, the login is working but the exceptions not so much. It was working until i wanted to return status
AttributeError at /login/
Got AttributeError when attempting to get a value for field email
on serializer LoginSerializer
.
The serializer field might be named incorrectly and not match any attribute or key on the Response
instance.
Original exception text was: 'Response' object has no attribute 'email'.
I saw a few answers but the context didnt match. What am i missing or doing wrong?
class LoginSerializer(serializers.ModelSerializer):
email = serializers.EmailField()
password = serializers.CharField(max_length=68, min_length=6, write_only = True)
username = serializers.CharField(
read_only=True
)
tokens = serializers.CharField(max_length=68, min_length=6, read_only=True)
class Meta:
model=User
fields = ['email', 'username', 'password', 'tokens']
def validate(self, attrs):
email = attrs.get('email', '')
password = attrs.get('password', '')
user = auth.authenticate(email=email, password=password)
if user is None:
return Response({'msg':'No such user'}, status=status.HTTP_401_UNAUTHORIZED)
# raise AuthenticationFailed({'status':False,'message': ' username is worng'}, status=status.HTTP_401_UNAUTHORIZED)
if not user.is_active:
raise AuthenticationFailed({'msg':'Account is disabled'})
if not user.is_verified:
raise AuthenticationFailed({'msg': 'Email is not verified'})
if not user:
return Response({'msg':'Invalid credentials, try again'}, status=status.HTTP_401_Unauthorized)
return{
'email':user.email,
'username':user.username,
'tokens':user.tokens()
}
return super.validate(attrs)
'views.py'
class LoginAPIView(APIView):
serializer_class = LoginSerializer
def post(self, request):
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception = True)
return Response(serializer.data, status=status.HTTP_200_OK)
custom user model
class UserManager(BaseUserManager):
def create_user(self, username, email, password):
if username is None:
raise TypeError("User should be provide username")
if email is None:
raise TypeError("User should be provide email")
if password is None:
raise TypeError("User should be provide password")
user = self.model(username=username, email=self.normalize_email(email))
user.set_password(password)
user.save()
return user
def create_superuser(self, username, email, password):
user = self.create_user(username, email, password)
user.is_superuser = True
user.is_staff = True
user.save()
return user
class User(AbstractBaseUser, PermissionsMixin):
username = models.CharField(max_length=255, db_index=True)
email = models.EmailField(max_length=255, unique=True, db_index=True)
is_verified = models.BooleanField(default=False)
# is_authenticated = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
objects = UserManager()
def __str__(self):
return self.email
def tokens(self):
refresh = RefreshToken.for_user(self)
return {
'refresh': str(refresh),
'access': str(refresh.access_token)
}
def validate(self, attrs):
email = attrs.get('email')
password = attrs.get('password')
user = auth.authenticate(email=email, password=password)
print (user)
if not user:
raise AuthenticationFailed({'msg': 'No such user'}, code=status.HTTP_401_UNAUTHORIZED)
if user is None:
raise AuthenticationFailed({'message': ' Your Email or Password is wrong'}, code=status.HTTP_401_UNAUTHORIZED)
# raise AuthenticationFailed({'message': ' username is wrong'})
if not user.is_active:
raise AuthenticationFailed({'msg':'Account is disabled'},code=status.HTTP_403_FORBIDDEN)
if not user.is_verified:
raise AuthenticationFailed({'msg': 'Email is not verified'}, code=status.HTTP_401_UNAUTHORIZED)
This did the job for me. I guess the error came because the 'auth' did not take 'Response'