【发布时间】:2019-07-29 14:02:08
【问题描述】:
我是 django 的新手,我必须用它做一个后端。 我的问题:我有多个模型(客户、司机、公司),它们都应该登录并进行身份验证(每个都在不同的应用程序上,但它们都扩展了相同的用户模型),我见过很多这样的问题,但没有其中解决了我的问题,即 authenticate(username='username',password='password') 总是不返回任何内容。 用户记录存在于数据库中,我用 filter(username=(username). 所以这里有一些代码:
UserManager 类:
class UserManager(BaseUserManager):
def create_user(self, username, password, phone):
if not username:
raise ValueError("user must provide a username")
if not password:
raise ValueError("user must provide a password")
if not phone:
raise ValueError("user must povide a phone number")
user_obj = self.model(
user_name=username,
phone=phone
)
user_obj.set_password(password)
user_obj.save()
return user_obj
用户类:
class User(AbstractBaseUser):
user_name = models.CharField(max_length=32, unique=True)
email = models.EmailField(max_length=255, unique=True, null=True)
phone = PhoneNumberField()
access_token = models.CharField(max_length=255, unique=True, null=True)
notifications_token = models.CharField(max_length=255, unique=True, null=True)
photo = models.ImageField()
person_in_contact = models.CharField(max_length=32)
active = models.BooleanField(default=False)
confirmedEmail = models.BooleanField(default=False)
confirmedPhone = models.BooleanField(default=False)
completedProfile = models.BooleanField(default=False)
objects = UserManager()
@property
def is_active(self):
return self.active
def __str__(self):
return "Client : " + self.user_name + " Email:" + self.email
def get_email(self):
return self.email
USERNAME_FIELD = 'user_name'
REQUIRED_FIELDS = ['username', 'phone', 'password']
class Meta:
abstract = True
Person 类(客户端和驱动程序由此扩展):
class Person(User):
GENDER = (('F', 'FEMALE'), ('M', 'MALE'))
name = models.CharField(max_length=50, null=True)
surname = models.CharField(max_length=50, null=True)
adress = models.CharField(max_length=255, null=True)
birth_date = models.DateField(null=True)
gender = models.CharField(max_length=1, choices=GENDER, default='M')
def age(self):
today = date.today()
return today.year - self.birth_date.year
def __str__(self):
return super().__str__() + " Name : " + self.name
class Meta:
abstract = True
这是我正在测试的驱动程序模型(如果成功,我将对其他 2 个模型应用相同的方法):
class Driver(Person):
rating = models.DecimalField(default=0, decimal_places=1, max_digits=3)
driving_license = models.CharField(max_length=50, null=True)
insurance_number = models.CharField(max_length=50, null=True)
company = models.ForeignKey(TransportCompany, on_delete=models.DO_NOTHING, null=True)
我的 settings.py 文件夹已设置:
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
)
AUTH_USER_MODEL = 'drivers.Driver'
这是我在 python 控制台中的测试方式:
>>> from django.contrib.auth import authenticate
>>> print (authenticate(username='Simouchee',password='123456789'))
None
当我使用过滤器测试并存在时:
>>> driver = Driver.objects.filter(user_name = 'Simouchee')
>>> driver.exists()
True
感谢任何有关如何正确验证自定义模型的帮助/提示。 真的很抱歉,我觉得需要详细解释的长线程。
【问题讨论】:
-
如果检索实例,
driver.check_password('123456789')是否返回True? -
在运行身份验证之前如何在控制台中创建驱动程序?
-
@schwobaseggl 是的,它确实返回 true。
-
@Hanny 我没有在控制台中创建驱动程序,驱动程序已经在数据库中,我只是在尝试对其进行身份验证。
-
为什么不只创建一个测试(自动) - 然后创建用户并在测试中查找/诊断问题,而不是使用数据库中可能发生变化的数据?然后您可以创建用户并尝试进行身份验证以确保 100% 它与可能导致某些问题的数据无关?这是更安全的方式,自动化并确保您一直负责该过程 - 而且,它可以在未来为其他用户重现,可在任何地方进行测试,并允许您测试您的代码以应对未来的变化,所以你知道它不会坏。