Как использовать более двух полей в качестве имени пользователя в пользовательской модели пользователя Django?
У меня есть таблица сотрудников (унаследованная) с полями Employee_no, Company_name и Password. Как я могу использовать мою текущую таблицу в качестве модели пользователя Django? Employee_no дублируется, но в комбинации с Company_name оно будет уникальным.
Мне нужно использовать имя_сотрудника и имя_компании в качестве имени пользователя для входа в систему.
| Employee_no | Company_name | password |
|---|---|---|
| 1 | Apple | any password |
| 1 | Samsung | any password |
| 2 | Apple | any password |
| 3 | Samsung | any password |
| 3 | any password |
Вот пример. Он будет использоваться в случае или электронной почты или номера телефона
try:
user_obj = User.objects.get(Q(email=email_or_mobile) | Q(mobile_number=email_or_mobile))
except User.DoesNotExist:
raise Exception("Invalid email or mobile number")
if not user_obj.check_password(password):
raise Exception("Invalid password")
if user_obj.is_active:
login(request,user)
Django заставляет вас иметь уникальную USERNAME_FIELD в модели User, чтобы использовать все возможности, которые он предоставляет из коробки. Но вы всегда можете настроить ее, если вам это действительно нужно (с небольшой дополнительной работой).
В вашей ситуации вам нужна модель User с двумя полями, которые определяют их уникальность. Это подразумевает наличие пользовательской модели пользователя и реализацию пользовательского бэкенда аутентификации
Для модели User у вас должно быть что-то вроде этого:
class User(AbstractUser):
username = None
employee_no = models.IntergerField()
company_name = models.CharField(max_lenght=100)
USERNAME_FIELD = "employee_no" # Not really used, but required by Django
# Completes custom User subclassing ...
class Meta:
# This is required for your design in order to have database integrity
unique_together = ('employe_no', 'company_name')
Если вы попытаетесь запустить сервер с этой моделью пользователя, вы получите ошибки проверки системы
Вам следует добавить в настройки
SILENCED_SYSTEM_CHECKS = ["auth.E003", "auth.W004"]
Теперь вам нужно реализовать пользовательский бэкенд auth, чтобы аутентифицировать
пользователей по двум полям. Для этого просто подкласс django.contrib.auth.backends.BaseBackend и реализуйте свою логику аутентификации.
Что-то вроде этого:
class CustomBackend(BaseBackend):
def authenticate(self, request, employee_no=None, company_name=None, password=None, **kwargs):
if employee_no is None or company_name is None or password is None:
return
try:
user = UserModel._default_manager.get(employee_no=employee_no, company_name=company_name)
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
И добавьте этот бэкенд в ваши настройки в список AUTHENTICATION_BACKENDS (путь к точечной строке)
Наконец, вы должны обеспечить передачу правильных параметров в login view методу authenticate и быть очень осторожными с другими интеграциями, которые требуют стандартной модели Django User.