Как иметь разные страницы входа для одной модели аутентификации в Django?

У меня одна модель пользователя Django (с пользовательским менеджером пользователей), но два разных типа пользователей, а именно Store и Customer, для обработки аутентификации:

authentication/models.py

class User(AbstractBaseUser, PermissionsMixin):
    ...

    # checks if user is associated with a store object
    def is_store(self):
        return hasattr(self, 'store')

    # checks if user is associated with a customer object
    def is_customer(self):
        return hasattr(self, 'customer')

stores/models.py

class Store(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, verbose_name=_('user'), on_delete=models.RESTRICT, primary_key=True)
    ...

    def clean(self):
        # validates that the selected user doesn't belong to a customer object
        if self.user.is_customer():
            raise ValidationError({'user': _('This user is already associated with a customer.')})

customers/models.py

class Customer(models.Model):
    user = models.OneToOneField(settings.AUTH_USER_MODEL, verbose_name=_('user'), on_delete=models.CASCADE, primary_key=True)
    ...

    def clean(self):
        # validates that the selected user doesn't belong to a store object
        if self.user.is_store():
            raise ValidationError({'user': _('This user is already associated with a store.')})

Теперь магазины и клиенты должны использовать два разных сайта для входа в систему, т.е. магазины будут использовать admin.domain.com, а клиенты будут просто использовать domain.com. Если магазин вошел в admin.domain.com, будет ли он также показывать, что он вошел в систему, когда он посещает domain.com? Если да, то как я могу предотвратить это и изолировать эти две модели для конкретных сайтов, используя при этом одну и ту же модель и методы аутентификации?

Создайте 2 миксина StoreUserOnlyMixin и CuustomerUserOnlyMixin, наследующих от класса django TemplateView. Затем в каждом из них переопределите метод dispatch.

from django.views.generic import TemplateView
from django.contrib import auth
from django.http import HttpResponseRedirect
from django.urls import reverse

class CustomerUserOnlyMixin(TemplateView) 
    def dispatch(self, *args, **kwargs):
        if not self.request.user.is_customer():
            auth.logout(self.request)
            return HttpResponseRedirect(reverse('customer_login_view'))
        return super(CustomerUserOnlyMixin, self).dispatch(*args, **kwargs)

И нечто подобное с StoreUserOnlyMixin. После этого вы можете наследоваться от одного из них, основываясь на том, должно ли представление быть доступно для Store или Customer

Для решения вышеуказанной задачи можно использовать permission_classes.

DRF имеет атрибут permission_classes, который поддерживает список классов разрешений. Создайте 2 класса разрешений IsShopUser и IsShopCustomer. Оба класса будут дочерними для класса IsAuthenticated, который создан в DRF.

from rest_framework.permissions import IsAuthenticated
class ISShopUser(IsAuthenticated):
    def has_permission(self, request, view):
        """
        if user is a shop user return true
        else return false
        """

в каждом представлении применяются эти классы разрешений, основанные на типе пользователя.

class ShopAPIView(APIView):
    permission_classes = [ISShopUser]

Не рекомендуется выводить пользователей из системы, если они вводят неправильный API. Достаточно просто показать ошибку.

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