Как изменить псевдоним имени пользователя в 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']

Image Я пытался сделать это, но тогда он добавляет еще одно поле с именем phone вместо замены имени пользователя. Я даже не знаю, будет ли это работать или нет .

Выполните следующие шаги, это может помочь вам.

  1. Вам следует настроить модель 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

  1. Добавьте AUTH_USER_MODEL = 'yourapp.User' в settings.py.
  2. 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)
Вернуться на верх