I am using jwt.io on my DRF project. As you know jwt.io has already a Login API view called 'TokenObtainPairView' and it requires 2 fields: username and password. But in our project, we want users to log in with their email instead of their username. I handle this with the following code:
class LoginAPIView(TokenObtainPairView):
def post(self, request, *args, **kwargs):
email=request.data['email']
request.POST._mutable = True
profile=ProfileModel.objects.get(email=email)
request.data['username']=profile.username
request.POST._mutable = False
return super().post(request, *args, **kwargs)
It works but on my swagger when front-end devs check the endpoint they see that the endpoint requires 2 fields: username and password. But I want them to see required fields such as email and password. here is the how my endpoint look like
Is there any way to change its required fields?
CodePudding user response:
I think if you don't need the username you can define your own user model like this.
The USERNAME_FIELD = 'email' on user model says to Django that use the email as username.
Don't forget change settings.py to use your own user model adding this const: AUTH_USER_MODEL = 'users.User' where users is the app name and User is the model name.
from django.contrib.auth.models import (
AbstractBaseUser,
BaseUserManager,
PermissionsMixin
)
class UserManager(BaseUserManager):
def create_user(self, email, password=None, **extra_fields):
"""Creates and saves a new user"""
if not email:
raise ValueError('Users must have an email address')
user = self.model(email=self.normalize_email(email), **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password):
if not email:
raise ValueError('Users must have an email address')
if not password:
raise ValueError('Users must have a password')
"""Creates and saves a new super user"""
user = self.create_user(email, password)
user.is_staff = True
user.is_superuser = True
user.save(using=self._db)
return user
class User(AbstractBaseUser, PermissionsMixin):
"""Custom user model that suppors using email instead of username"""
email = models.EmailField(max_length=255, unique=True)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
objects = UserManager()
USERNAME_FIELD = 'email'
CodePudding user response:
By default TokenObtainPairSerializer
uses the default username field defined by the model, but in case you need to change the behavior without changing the model you can override the token serializer to use the preferred field, i.e.:
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
class CustomTokenObtainPairSerializer(TokenObtainPairSerializer):
username_field = 'email'
class LoginAPIView(TokenObtainPairView):
_serializer_class = CustomTokenObtainPairSerializer