Здравствуйте, в моей кастомной модели в качестве поля username выступает email. Соответственно для того, чтобы пользователь мог благополучно войти нужно и переписать логику входа посредствам email.
Это можно сделать двумя способами, но каким будет правильнее?
1. Можно переписать AuthenticationForm из django.contrib.auth.forms следующим образом:
def clean(self):
username = self.cleaned_data.get('username')
password = self.cleaned_data.get('password')
if username is not None and password:
self.user_cache = authenticate(self.request, password=password, **{'email': username})
if self.user_cache is None:
raise self.get_invalid_login_error()
else:
self.confirm_login_allowed(self.user_cache)
return self.cleaned_data
Так как внутри функции authenticate мы обращаемся к бэкенду, логика которого выглядит так:
def authenticate(self, request, username=None, password=None, **kwargs):
if username is None:
username = kwargs.get(UserModel.USERNAME_FIELD)
if username is None or password is None:
return
try:
user = UserModel._default_manager.get_by_natural_key(username)
except UserModel.DoesNotExist:
# Run the default password hasher once to reduce the timing
# difference between an existing and a nonexistent user (#20760).
UserModel().set_password(password)
else:
if user.check_password(password) and self.user_can_authenticate(user):
return user
Здесь стоит внимание обратить на вторую строку. В ней из словаря именованных аргументов мы вытягиваем USERNAME_FIELD, значением которого как раз является строка 'email.'
2. Можно написать кастомный бэкенд, что я и сделал:
class ConsumerAuthenticationBackend(ModelBackend):
def authenticate(self, request, username=None, password=None, **kwargs):
kwargs['email'] = username
return super().authenticate(request, password=password, **kwargs)
Здесь мы обращаемся к родительскому методу и делаем так, чтобы сбратала проверка на отсутствие имени пользователя и его метод попытался достать из kwargs, куда мы и засунули наш емейл.
Подскажите, пожалуйста, как правильнее поступить? Не нужно писать, что поступай так, как тебе удобно. Меня интересует best practice.