【问题标题】:Way to use email as the authentication field?使用电子邮件作为身份验证字段的方式?
【发布时间】:2015-04-20 18:09:10
【问题描述】:

我正在使用 django 的内置身份验证系统。一切似乎都运行良好。注册时要求用户输入两个字段:usernameemail。登录时,他们需要输入usernamepassword

我想更改此行为,以便用户名字段消失。我想将电子邮件视为用户名。因此,在登录用户时需要输入email / password

在仍然使用 django 的内置身份验证系统的同时这是否可能?我在 django 1.7

更新

我需要添加额外的字段,所以我在 models.py 中添加了以下内容

从 django.db 导入模型 from django.contrib.auth.models 导入用户

class UserProfile(models.Model):
    user = models.OneToOneField(User)
    telephone_number = models.CharField(max_length=100)
    website_url = models.CharField(max_length=100)

User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])

【问题讨论】:

  • 这在documentation 中有专门解决。
  • @DanielRoseman 我浏览了文档,但我已经制作了一个额外的模型,因为我需要添加额外的字段。查看问题的更新部分

标签: python django django-models django-authentication


【解决方案1】:

这不是严格意义上的大炮,但为了避免创建新的 User 类或 Auth 后端,我倾向于让用户同时使用用户名或电子邮件登录。

无论如何,您都希望确保电子邮件是唯一的,因为 django 默认情况下不会检查这一点。

然后您必须覆盖默认登录视图以支持此功能。您可以按照以下方式创建一些东西:

class EmailUsernameLoginView(View):

    def post(self, request):
        next = request.POST.get('next', None)
        username = request.POST.get('username', None)
        password = request.POST.get('password', None)
        error = ''
        if username and password:
            try:
                usr = User.objects.get(email=username)
                username = usr.username
            except User.DoesNotExist:
                pass  # If the user doesn't exist, it's an username
            user = authenticate(username=username, password=password)
            if user is not None:
                if user.is_active:
                    login(request, user)
                    return redirect(next)
                else:
                    error = 'Your account is not active'
            else:
                error = 'The username / email - password comb is wrong'
        else:
            error = 'Please provide a username / email and password' 
        ctx = {'error': error}  # Fill with needed feedback
        return render(request, ctx, 'registration/login.html')

这只是一个草稿,您可能应该包含一个表单来帮助验证/清理

【讨论】:

  • 但这仍然需要用户在注册时输入用户名和电子邮件。
  • 当然。您将不得不以其他方式覆盖很多内容。
  • 您还可以在保存用户时创建一些用户名(随机或取决于电子邮件字段)。
【解决方案2】:

答案直接在django documentation,简而言之你应该继承AbstractBaseUserAbstractUser(第二种情况你不能完全删除用户名字段),基于BaseUserManager创建你自己的用户管理器或UserManager 如果您正在使用它(或您正在使用的任何应用程序正在使用它),则可以自定义内置的身份验证表单。

【讨论】:

  • 我浏览了文档,但我已经制作了一个额外的模型,因为我需要添加额外的字段。查看问题的更新部分
  • @birdy 你创建了一个 UserProfile 模型。您需要创建一个新的 User 模型和一个新的 UserManager 以使该字段完全消失。此外,您必须为注册和登录实现自定义视图
  • 创建额外模型和覆盖默认用户模型不是一回事。您可以同时执行这两种操作,但您必须在配置文件模型中将外键修复为用户模型。
  • @GwynBleidD 我正在使用这个带有 Angular 前端的应用程序。所以一切都结束了休息 API 我会改变前端..那不是问题。如果我将AbstractBaseUser 子类化,我还需要我创建的UserProfile 模型吗?或者,当我继承 AbstractBaseUser 时,我也可以在其中添加我的自定义字段...
  • 您可以将数据从 UserProfile 移动到您的新类中,或者保持这种方式,这完全取决于您。如果它是一个实时应用程序,请记住将适当的迁移放入依赖于用户模型的所有应用程序中,以及包含新用户模型的应用程序以将所有数据移动到新类。但是,如果任何第三方应用程序依赖于 User 类,仍然无法迁移。
猜你喜欢
  • 1970-01-01
  • 2020-01-10
  • 2018-02-10
  • 2023-03-18
  • 2012-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多