Django authenticate()对于自定义模型始终返回None

时间:2019-07-29 14:02:08

标签: python django

我是django的新手,我必须为此做一个后端。 我的问题:我有多个模型(客户端,驱动程序,公司),所有这些模型都应该登录并进行身份验证(每个模型都在不同的应用程序上,但是它们都扩展了相同的用户模型),我看到了很多这样的问题,但是没有一个他们解决了我的身份验证问题(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

人员类(客户端和驱动程序从此扩展):

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

这是我正在测试的驱动程序模型(如果成功,我将对其他两个模型应用相同的方法):

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

任何有关如何正确认证自定义模型的帮助/提示均应得到赞赏。 非常抱歉,我觉得需要详细解释。

1 个答案:

答案 0 :(得分:0)

您在这里authenticate(username='Simouchee',password='123456789')有误

您的模型中有user_name,但在username通话中有authenticate

我想说的是,最好以与django框架本身相同的方式让模型中的username不带有下划线-https://github.com/django/django/blob/master/django/contrib/auth/models.py#L299

也请按此处所述检查密码-Django authenticate() always return None for a custom model

已编辑:问题可以采用User模式。您在字段default=False中有active,因此还要检查您的用户是否处于活动状态。由于ModelBackend在方法is_active-https://github.com/django/django/blob/master/django/contrib/auth/backends.py#L51

中检查user_can_authenticate