Как изменить псевдоним имени пользователя в rest_framework_simplejwt с помощью класса TokenObtainPairSerializer?
Я работаю над проектом, в котором пользователь может зарегистрироваться, используя свой мобильный номер и пароль (после проверки с помощью otp), что я делаю: внутри поля username я сохраняю номер телефона пользователя, так как username является обязательным полем. И я использую simple_jwt для получения токена доступа и токена обновления. Все работает нормально
urls.py
from rest_framework_simplejwt.views import (
TokenObtainPairView,
TokenRefreshView,
)
urlpatterns =[
path('register', RegisterView.as_view() ),
path('otp/send', SendOtpView.as_view() ),
path('otp/verify', VerifyOtpView.as_view() ),
path('token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
]
вместо создания loginSerializer я использую rest_framework_simplejwt inbuild class TokenObtainPairView
Но когда я перехожу по url
auth/api/token/
он запрашивает имя пользователя и пароль, что сбивает меня с толку как пользователя. как я могу изменить имя имя пользователя на телефон.
Я понятия не имею, как это сделать, поскольку я новичок в djangorestframework
serializers.py
from rest_framework_simplejwt.serializers import TokenObtainPairSerializer
class LoginSerializer(TokenObtainPairSerializer):
password = serializers.CharField(max_length=65, min_length=8, write_only=True)
**phone = serializers.CharField(max_length=20, source='username')**
class Meta:
model = User
fields = ['phone', 'password']
Я пытался сделать это, но тогда он добавляет еще одно поле с именем phone вместо замены имени пользователя. Я даже не знаю, будет ли это работать или нет .
Выполните следующие шаги, это может помочь вам.
- Вам следует настроить модель
User
в соответствии с вашими требованиями.
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
phone_number = models.CharField(max_length=25, unique=True, blank=True, null=True)
# token = models.TextField(_('token'), unique=True)
USERNAME_FIELD = 'phone_number'
REQUIRED_FIELDS = ['password']
# Remove below username from user model
username = None
- Добавьте
AUTH_USER_MODEL = 'yourapp.User'
вsettings.py
. makemigrations
иmigrate
Примечание Пожалуйста, убедитесь, что ваша база данных пуста и свежа, прежде чем делать это, потому что это может показать ошибку с текущими миграциями и данными.
Ок. Каким-то образом я нашел способ сделать это. Я создал сериализатор модели и использовал пользовательский метод генератора токенов
https://django-rest-framework-simplejwt.readthedocs.io/en/latest/creating_tokens_manually.html
serializers.py
# for creating token manually
def get_tokens_for_user(user):
refresh = RefreshToken.for_user(user)
return {
'refresh': str(refresh),
'access': str(refresh.access_token),
}
class LoginSerializer(serializers.ModelSerializer):
password = serializers.CharField(max_length=65, min_length=8, write_only=True)
phone = serializers.CharField(max_length=20, source='username')
tokens = serializers.SerializerMethodField(read_only=True)
def get_tokens(self, obj):
return obj['tokens']
class Meta:
model = User
fields = ['phone', 'password', 'tokens']
def validate(self, attrs):
param_phone = attrs.get('username', "")
param_password=attrs.get('password', '')
if not param_phone.isnumeric():
raise serializers.ValidationError(
{'phone': ("Only Phone Number is accepted")}
)
if not len(param_phone) == 10:
raise serializers.ValidationError(
{'phone': ("Phone Number length can only be of 10 digits")}
)
user = auth.authenticate(username=param_phone, password=param_password)
if User.objects.filter(username=param_phone, is_active=False).exists():
raise AuthenticationFailed("Account disabled. Contact admin")
if not user:
raise AuthenticationFailed("Invalid Credential. Try again")
tokens = get_tokens_for_user(user)
return {
'username':param_phone,
'tokens': tokens
}
return super().validate(attrs)
views.py
class LoginView(GenericAPIView):
serializer_class = LoginSerializer
def post(self, request):
serializer = LoginSerializer(data=request.data)
serializer.is_valid(raise_exception=True)
return Response(serializer.data, status=status.HTTP_200_OK)