问题描述
class User(AbstractBaseUser):
class Types(models.TextChoices):
CUSTOMER = 'CUSTOMER','Customer'
supplier = 'supplier','supplier'
OPERATOR = 'OPERATOR','Operator'
base_type = Types.CUSTOMER
objects = UserManager()
phone = models.IntegerField(unique=True)
code = models.IntegerField(blank=True,null=True)
type = models.CharField(max_length=20,choices=Types.choices,default=base_type)
date_joined = models.DateTimeField(auto_Now_add=True)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
USERNAME_FIELD = 'phone'
required_FIELDS = []
class Meta:
verbose_name = 'user'
verbose_name_plural = 'users'
def __str__(self):
return str(self.phone)
def has_perm(self,perm,obj=None):
return True
def has_module_perms(self,app_label):
return True
@property
def is_staff(self):
return self.is_admin
以及 User 模型的经理:
class UserManager(BaseUserManager):
def create_user(self,phone,code=663322,password=None):
if not phone:
raise ValueError('Users must have a phone number')
user = self.model(
phone=phone,code=code,)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self,password=None):
user = self.create_user(
phone=phone,password=password,)
user.is_admin = True
user.save(using=self._db)
return user
我希望拥有 3 种不同的用户类型(客户、供应商、运营商),因此我创建了 3 个配置文件模型,并为每个配置文件模型的基本用户模型设置了一个 OnetoOneField(具有一些与用户类型相关的特定字段)。 我还创建了 3 个代理模型,如下所示:
class Customer(User):
objects = CustomerManager()
base_type = User.Types.CUSTOMER
class Meta:
proxy = True
class supplier(User):
objects = supplierManager()
base_type = User.Types.supplier
class Meta:
proxy = True
class Operator(User):
objects = OperatorManager()
base_type = User.Types.OPERATOR
class Meta:
proxy = True
他们的经理都是这样的(只有get_queryset方法不同):
class supplierManager(models.Manager):
def create(self,code=223322,password=None):
if not phone:
raise ValueError('Users must have a phone number')
user = self.model(
phone=phone,type='supplier',)
user.set_password(password)
user.save(using=self._db)
return user
def get_queryset(self,*args,**kwargs):
return super().get_queryset(*args,**kwargs).filter(type='supplier')
每种用户类型都有自己的注册方式,所以我制作了 3 个不同的身份验证后端(OperatorBackend 与其他两个相同):
class CustomerBackend(BaseBackend):
def authenticate(self,request,phone=None,code=None):
if phone and code:
try:
user = Customer.objects.get(phone=phone)
if user.code == code:
return user
return None
except Customer.DoesNotExist:
return None
def get_user(self,user_id):
try:
return Customer.objects.get(pk=user_id)
except Customer.DoesNotExist:
return None
class supplierBackend(BaseBackend):
def authenticate(self,first_name=None):
if phone and first_name:
try:
user = supplier.objects.get(phone=phone)
if user.sprofile.first_name == first_name:
return user
return None
except User.DoesNotExist:
return None
def get_user(self,user_id):
try:
supplier.objects.get(pk=user_id)
except supplier.DoesNotExist:
return None
以下是我对用户登录的看法(authenticate 是 django 的身份验证方法):
def customer_login(request):
if request.method == 'POST':
form = CustomerLoginForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
user = authenticate(request,phone=cd['phone'],code=cd['code'])
if user is not None:
login(request,user,backend='accounts.backends.CustomerBackend')
messages.success(request,'Logged in','success')
return redirect('accounts:home')
else:
messages.error(request,'User is None','danger')
else:
form = CustomerLoginForm()
context = {
'form': form,}
return render(request,'accounts/customer_login.html',context)
def supplier_login(request):
if request.method == 'POST':
form = supplierLoginForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
user = authenticate(request,first_name=cd['first_name'])
if user is not None:
login(request,backend='accounts.backends.supplierBackend')
messages.success(request,'danger')
else:
form = supplierLoginForm()
context = {
'form': form,'accounts/supplier_login.html',context)
我的问题是当我想使用 CUSTOMER 用户类型登录时,它可以工作并让用户登录。但是当我尝试使用其他用户类型登录时,它不起作用并且 request.user 返回 AnonymousUser . 我已经注册了自定义身份验证后端(django 的默认 ModelBackend 仍然存在)并且 settings.py 文件和身份验证后端中的 AUTH_USER_MODEL 似乎不是问题,因为它们在提供正确凭据时返回用户。我尝试从管理面板和通过经理创建新用户,但没有任何区别。也许我在这种实现上走错了方向,我还是编程新手。任何帮助表示赞赏。
编辑: 我尝试在登录后访问用户的 session_key 和后端,结果登录功能确实有效。但是 request.user.is_authenticated 在使用 supplierBackend 时由于某种原因返回 False。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)