如何在 Django 中为相同的身份验证模型设置不同的登录页面?

How to have different login pages for same authentication model in Django?

我有一个 Django 用户模型(带有自定义用户管理器)但有两种不同的用户类型,即 StoreCustomer,用于处理身份验证:

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 个 mixins StoreUserOnlyMixin 和 CuustomerUserOnlyMixin 继承自 django TemplateView class。然后在每个 then 覆盖调度方法。

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 属性支持权限列表 class 。 创建 2 个权限 classes IsShopUserIsShopCustomer。 class 都是 IsAuthenticated class 的子代,它是在 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基于用户类型。

class ShopAPIView(APIView):
    permission_classes = [ISShopUser]

不建议输入错误的用户注销API。简单地显示一个错误。