Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在扩展用户模型中通过电话字段登录_Python_Django_Django Models - Fatal编程技术网

Python 在扩展用户模型中通过电话字段登录

Python 在扩展用户模型中通过电话字段登录,python,django,django-models,Python,Django,Django Models,我使用了django用户模型,并对其进行了扩展,添加了一个电话字段。我可以使用用户名或电子邮件登录,但无法从扩展用户模型访问电话号码字段 models.py class Profile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) phonenumber = models.CharField(max_length=10) backends.py class Authentic

我使用了django用户模型,并对其进行了扩展,添加了一个电话字段。我可以使用用户名或电子邮件登录,但无法从扩展用户模型访问电话号码字段

models.py

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    phonenumber = models.CharField(max_length=10)
backends.py

class AuthenticationBackend(backends.ModelBackend):
    def authenticate(self, request,  username=None, password=None, **kwargs):
        usermodel = get_user_model()
        print(usermodel)

        try:
            user = usermodel.objects.get(Q(username__iexact=username) | Q(
                email__iexact=username))
            if user.check_password(password):
                return user
        except user.DoesNotExist:
            pass

backend.py是我用来实现通过用户名或电子邮件登录的工具,但在扩展用户模型中,我无法对phonenumber进行登录。

您可以扩展AbstractUser并在其上添加phonenumber

class User(AbstractUser):
    phonenumber = models.CharField(max_length=10)

    USERNAME_FIELD = 'phonenumber'
然后,应在settings.py中将自定义模型指定为默认用户模型 AUTH_USER_MODEL='app_name.USER'


有两种方法可以解决你的问题

通过子类化用户模型并更改默认用户模型来扩展用户模型。我建议你走这条路,因为电话号码是用来认证的。 在概要文件上设置相关的_名称,并从该名称查询用户模型。 对于第一个,我建议您查看 还有一个关于如何做到这一点的相当广泛的教程

如果你想走简易路线,你只需要在个人资料的phonenumber字段上设置一个反向访问器

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    phonenumber = models.CharField(max_length=10, related_name='profile')
然后,您可以按用户档案的电话号码搜索用户:

class AuthenticationBackend(backends.ModelBackend):
    def authenticate(self, request,  username=None, password=None, **kwargs):
        usermodel = get_user_model()
        print(usermodel)

        try:
            user = usermodel.objects.get(Q(username__iexact=username) | Q(
                email__iexact=username) | Q(profile__phonenumber__iexact=username)
            if user.check_password(password):
                return user
        except user.DoesNotExist:
            pass
虽然这不在您的问题范围内,但我认为您应该注意代码中的以下问题:

电话号码通常比10个字符的字符串更复杂+31 6 12345678是一个有效的电话号码,但超过10个字符。查看有关如何存储和验证电话号码的提示。 如果使用字段进行身份验证,请确保它是唯一的。phonenumber字段实际上应该是phonenumber=models.CharFieldmax_length=10,related_name='profile',unique=True 你的usermodel.objects.get。。。如果存在电话号码为“0123456789”的用户和用户名为“0123456789”的其他用户,则查询将返回多个用户。您应该将用户名约束为不包含电话号码,这只有通过扩展默认用户类才能实现。
当您试图通过电话号码获取用户时,能否显示代码?我还没有尝试通过电话号码获取用户。我被困在这里了。我不知道如何在扩展用户模型中访问电话号码您可以尝试usermodel.objects.getQprofile\uu phonenumber=some\u phone\u number。从用户到配置文件的关系就是配置文件。但是您应该使phonenumber在您的模型上唯一,否则可能会有多个用户使用相同的电话号码,并且例外情况不是usermodel.DoesNotExist,而是usermodel.MultipleObject返回。我认为如果您想使用phonenumber作为身份验证字段,然后理想情况下,您希望扩展AbstractBaseUser类,而不是像以前那样将概要文件映射到用户。更多信息请参见此处:@urbanespaceman提到,在本例中,最好创建自定义用户模型,如前所述。