Как использовать более двух полей в качестве имени пользователя в пользовательской модели пользователя 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 Google 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.

Вернуться на верх