如何在 Django 中为相同的身份验证模型设置不同的登录页面?
How to have different login pages for same authentication model in 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 个 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 IsShopUser
和 IsShopCustomer
。 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。简单地显示一个错误。
我有一个 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 个 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 IsShopUser
和 IsShopCustomer
。 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。简单地显示一个错误。