Есть ли возможность поставить условие на требуемый пароль в Django Custom Auth?

Я хочу, чтобы зарегистрированный пользователь сначала входил в систему с помощью Email или номера телефона и пароля. Если пользователь забыл пароль, то должна быть возможность войти в систему с помощью OTP, минуя пароль, который будет предоставлен через SMS на номер телефона пользователя. Есть ли возможность достичь этого?

Вот официальные документы, в которых поле пароля всегда является обязательным. https://docs.djangoproject.com/en/4.0/topics/auth/customizing/#a-full-example. Я знаю, что мы можем изменить имя пользователя на email или на номер телефона, если захотим, но как нам поставить условие для входа с паролем/случайным OTP. Как мы можем этого добиться? За предложение буду благодарен. Спасибо

Да, мы можем сделать это, используя принудительный вход, вот пример того, как я это сделал, пожалуйста, посмотрите. У меня есть профиль, который один к одному связан с пользователем

def login_otp(request):
    mobile = request.session['mobile']
    context = {'mobile':mobile}
    if request.method == 'POST':
        otp = request.POST.get('otp')
        profile = Profile.objects.filter(mobile=mobile).first()
        
        if otp == profile.otp:
            user = User.objects.get(id = profile.user.id)
            login(request , user)
            return redirect('cart')
        else:
            context = {'message' : 'Wrong OTP' , 'class' : 'danger','mobile':mobile }
            return render(request,'login_otp.html' , context)
    
    return render(request,'login_otp.html' , context)

Вы можете сделать свой собственный CustomLoginBackend как

from django.contrib.auth import get_user_model

class CustomLoginBackend(object):

    def authenticate(self, request, email, password, otp):
        User = get_user_model()
        try:
            user = User.objects.using(db_name).get(email=email)
        except User.DoesNotExist:
            return None
        else:
            if password is not None:
                if getattr(user, 'is_active', False) and  user.check_password(password):
                    return user
            else:
                if getattr(user, 'is_active', False) and  user.otp == otp: #<-- otp included in user table
                   return user
        return None

Тогда в ваших login представлениях.

from django.contrib.auth import authenticate, login
from django.contrib import messages

def login_view(request):
    if request.method == 'POST':
        email = request.POST.get('email', None)
        password = request.POST.get('password', None)
        otp = request.POST.get('otp', None)

        user = authenticate(request, email=email, password=password, otp=otp)
        
        if user is not None:
            login(request, user)
            # redirect to a success page
            return redirect('dashboard')
        else:
            if password is not None:
                # return either email or password incorrect
                messages.error(request, "Invalid Email or Password")
                return redirect('login')
            else:
                # return invalid otp
                messages.error(request, "Invalid OTP")
                return redirect('login')

        return render(request, 'login.html')

И, наконец, не забудьте добавить AUTHENTICATION_BACKENDS в свой settings.py в качестве

AUTHENTICATION_BACKENDS = ['path_to_your.CustomLoginBackend ',]
Вернуться на верх