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

时间:2019-09-05 08:44:50

标签: 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 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是我用来通过用户名或电子邮件实现登录的工具,但是我无法在扩展用户模型中对电话号码进行登录。

2 个答案:

答案 0 :(得分:1)

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

  1. 通过子类化User模型并更改默认User模型来扩展User模型。我建议您选择这条路线,因为电话号码用于身份验证。
  2. 在配置文件上设置related_name,然后从该名称中查询用户模型。

对于第一个,我建议您检查Django documentation on creating custom users. 还有一个相当详尽的教程,介绍如何进行here

如果您想走简单的路,只需在个人资料的电话号码字段中设置反向访问器即可。

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个字符。请查看this question,以获取有关如何存储和验证电话号码的指示。
  • 如果您使用字段进行身份验证,请确保其唯一。电话号码字段实际上应为phonenumber = models.CharField(max_length=10, related_name='profile', unique=True)
  • 如果有一个电话号码为“ 0123456789”的用户和另一个用户名为“ 0123456789”的用户,则您的usermodel.objects.get(...)查询将返回多个用户。您应该限制用户名不包含电话号码,这只能通过扩展默认User类来实现。

答案 1 :(得分:0)

您可以扩展AbstractUser并在其上添加电话号码。

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

    USERNAME_FIELD = 'phonenumber'

然后,您应该在settings.py中将自定义模型指定为默认用户模型。 AUTH_USER_MODEL = 'app_name.User'

Customizing authentication in Django

相关问题