【问题标题】:override User model in Django or not?是否覆盖 Django 中的用户模型?
【发布时间】:2012-09-18 05:57:33
【问题描述】:

我目前正在使用 Django,我必须让用户能够注册和登录。 我已经阅读了许多文档,并且每个文档都建议扩展用户模型。 扩展用户模型有限制吗? 我是否必须构建自己的应用程序或扩展用户模型?

【问题讨论】:

标签: django


【解决方案1】:

如果您需要存储在用户模型中的更多信息,请查看this answer

对于用户注册,有一个名为django-registration的应用程序。

【讨论】:

  • 我已经做过了,但我只是问有没有限制或缺点:)
【解决方案2】:

django-registration 的好处在于,它区分了收集足够的信息来注册用户(这将允许他们登录到您的系统)和收集有关该用户的其他信息,这些信息将构成他们的个人资料,例如性别、出生日期等。 这第二点可以通过很多不同的方式完成,django-registration 的作者 James Bennet 还创作了 django-profiles,这是一个单独的应用程序,允许您灵活地构建构成用户配置文件的必填字段。

如果您想推出自己的配置文件解决方案,那么我不建议您实际扩展(在对象继承意义上)Django User 模型,而是简单地在一个额外的模型中指定一个外键关系,该模型将包含您的所有配置文件字段,然后您可以从任何 User 实例遵循与此配置文件模型的反向关系。

例如:

class Profile(models.Model):
    user = models.ForeignKey(User)
    nickname = models.CharField(max_length=255)

>>> user = User.objects.create_user(username='a_user', email='me@home.com', password='password')
>>> profile = Profile.objects.create(user=user, nickname='example')
>>> user.profile_set.all()[0].nickname #follow the reverse relationship from the fk in Profile
example

【讨论】:

    【解决方案3】:

    此时我建议通过开发版使用 Django 1.5 功能。 1.5 应该会在 11 月底发布(如果我没记错的话)。

    有了它,您就有了修改默认用户模型和周围所有东西的新的特定方法,因此您在自定义模型时保留了很多默认优点(如果这是您需要做的):

    https://docs.djangoproject.com/en/dev/topics/auth/#customizing-the-user-model

    【讨论】:

      【解决方案4】:

      这个答案变成了相当的叙述,所以这是简短的部分:

      这对我来说效果很好,但如果你想要你的 User 子类而不是 RequestContext 实例上的 auth.User,你需要做额外的工作。

      TLDR

      我过去这样做的目的是从用户名切换到基于电子邮件的登录。这增加了一些开销,因为它还需要一个新的身份验证后端。从好的方面来说,替换 auth 后端会导致 RequestContext.user 和 HTTPRequest.user 成为自定义 User 子类的实例。

      根据我的经验,扩展用户的难点在于使用 contrib.admin。

      诀窍是 contrib.admin 在未经身份验证/未经授权的用户尝试访问其中一个管理员 URL 时使用自己的登录视图。当我登陆不同的登录页面时,这对我来说是显而易见的,但如果你还没有覆盖这些页面,可能就不那么明显了。不过,这也使用了标准的身份验证后端,所以我的 RequestContexts 以 auth.User 实例结束,而不是我的子类。

      解决方案是覆盖 AdminSite 并定义新的登录方法。我刚刚使用?next 重定向到我的前端登录页面。

      与其跳过所有这些麻烦,一个更简单的解决方案是将 auth.User 留在上下文中,并在您的用户子类上定义一个类方法:

      @classmethod
      def for_auth_user(cls, auth_user):
          return cls.objects.get(user_ptr_id=auth_user.id)
      

      这只是每个页面加载的额外数据库命中。你甚至可以编写一个中间件在每个请求开始时进行这种交换。

      【讨论】:

        【解决方案5】:

        【讨论】:

          猜你喜欢
          • 2018-03-07
          • 2011-06-13
          • 2017-08-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-10-07
          • 2020-02-16
          相关资源
          最近更新 更多