python 如何更改默认的 django 用户模型以满足我的需求?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/896421/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 21:05:01  来源:igfitidea点击:

How to change default django User model to fit my needs?

pythondjangodjango-models

提问by kender

The default Django's Usermodel has some fields, and validation rules, that I don't really need. I want to make registration as simple as possible, i.e. require either email or username, or phone number - all those being unique, hence good as user identifiers.

默认的 DjangoUser模型有一些我并不真正需要的字段和验证规则。我想让注册尽可能简单,即需要电子邮件或用户名或电话号码 - 所有这些都是唯一的,因此可以作为用户标识符。

I also don't like default character set for user name that is validated in Django user model. I'd like to allow any character there - why not?

我也不喜欢在 Django 用户模型中验证的用户名的默认字符集。我想允许任何角色出现 - 为什么不呢?

I used user-profile django application before to add a profile to user - but this time I'd rather make the class mimimal. But I still want to use the Userclass, as it gives me an easy way to have parts of site restricted only for users logged in.

我之前使用用户配置文件 django 应用程序向用户添加配置文件 - 但这次我宁愿使类最小化。但是我仍然想使用这个User类,因为它给了我一个简单的方法来限制站点的某些部分只供登录的用户使用。

How do I do it?

我该怎么做?

采纳答案by Carl Meyer

Rather than modify the User class directly or do subclassing, you can also just repurpose the existing fields.

除了直接修改 User 类或进行子类化之外,您还可以重新调整现有字段的用途。

For one site I used the "first_name" field as the "publicly displayed name" of a user and stuff a slugified version of that into the "username" field (for use in URLs). I wrote a custom auth backend to allow people to log in using their "public name" or their email address, and I enforce the uniqueness of both of those at registration time. This plays nicely with other reusable apps and doesn't introduce extra tables or queries.

对于一个站点,我使用“first_name”字段作为用户的“公开显示名称”,并将该名称的 slugified 版本填充到“用户名”字段中(用于 URL)。我编写了一个自定义身份验证后端以允许人们使用他们的“公共名称”或他们的电子邮件地址登录,并且我在注册时强制执行这两者的唯一性。这可以很好地与其他可重用应用程序配合使用,并且不会引入额外的表或查询。

For another site I didn't want usernames at all, just unique emails. In order to satisfy Django's need for a unique username, I just hashed the email address and used that as the username (you have to base64-encode the hash to squeeze it under 30 characters). Custom auth backend to allow login with email.

对于另一个站点,我根本不需要用户名,只需要独特的电子邮件。为了满足 Django 对唯一用户名的需求,我只是对电子邮件地址进行散列并将其用作用户名(您必须对散列进行 base64 编码以将其压缩到 30 个字符以下)。自定义身份验证后端以允许使用电子邮件登录。

If backwards-compatibility weren't an issue, there are a lot of improvements I'd love to see made to django.contrib.auth and the User model to make them more flexible. But there's quite a lot you can do inside the current constraints with a little creativity.

如果向后兼容性不是问题,我很想看到 django.contrib.auth 和 User 模型有很多改进,使它们更加灵活。但是,在当前的限制条件下,您可以通过一点创造力来做很多事情。

回答by Daniel Naab

The Django User model is structured very sensibly. You really don't want to allow arbitrary characters in a username, for instance, and there are ways to achieve email address login, without hacking changes to the base model.

Django User 模型的结构非常合理。例如,您真的不想在用户名中允许任意字符,并且有一些方法可以实现电子邮件地址登录,而无需对基本模型进行黑客更改。

To simply store additional information around a user account, Django supports the notion of user profiles. While you don't need to rely on the built in support to handle this, it is a convention that is commonly followed and it will allow you to play nice with the reusable Django apps that are floating around in the ether. For more information, see here.

为了简单地围绕用户帐户存储附加信息,Django 支持用户配置文件的概念。虽然您不需要依赖内置的支持来处理这个问题,但这是一个普遍遵循的约定,它将允许您很好地使用漂浮在以太坊中的可重用 Django 应用程序。有关更多信息,请参见此处

If you want to actually modify the core User model but also "play nice" with reusable apps that rely on it, you're opening a bit of a Pandora's Box. Developers make base assumptions about how the core library is structured, so any changes may cause unexpected breakage. Nonetheless, you can monkeypatch changes to the base model, or branch a copy of Django locally. I would discourage the latter, and only recommend the former if you know what you're doing.

如果您想实际修改核心 User 模型,但同时也希望使用依赖它的可重用应用程序“玩得开心”,那么您就打开了一个潘多拉魔盒。开发人员对核心库的结构做出基本假设,因此任何更改都可能导致意外损坏。尽管如此,您可以对基本模型进行猴子补丁更改,或者在本地分支 Django 的副本。我会劝阻后者,并且只在您知道自己在做什么时才推荐前者。

回答by Raisins

I misread the question. Hope this post is helpful to anyone else.

我误读了这个问题。希望这篇文章对其他人有帮助。

#in models.py
from django.db.models.signals import post_save  

class UserProfile(models.Model):  
    user = models.ForeignKey(User)  
    #other fields here

    def __str__(self):  
          return "%s's profile" % self.user  

     def create_user_profile(sender, instance, created, **kwargs):  
        if created:  
           profile, created = UserProfile.objects.get_or_create(user=instance)  

post_save.connect(create_user_profile, sender=User) 

#in settings.py
AUTH_PROFILE_MODULE = 'YOURAPP.UserProfile'

This will create a userprofile each time a user is saved if it is created. You can then use

这将在每次保存用户时创建一个用户配置文件(如果已创建)。然后你可以使用

  user.get_profile().whatever

Here is some more info from the docs

这是文档中的更多信息

http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users

http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users

回答by David Berger

You face a bit of a dilemma which really has two solutions if you're committed to avoiding the profile-based customization already pointed out.

如果您致力于避免已经指出的基于配置文件的自定义,您将面临一些困境,这实际上有两种解决方案。

  1. Change the Usermodel itself, per Daniel's suggestions
  2. Write a CustomUserclass, subclassing Useror copying its functionality.
  1. User根据丹尼尔的建议更改模型本身
  2. 编写一个CustomUser类,子类化User或复制其功能。

The latter suggestion means that you would have to implement some things that Userdoes automatically manually, but I wonder whether that's as bad as it sounds, especially if you're at the beginning of your project. All you'd have to do is rewrite a middle-ware class and some decorators.

后一个建议意味着您必须实现一些User手动自动执行的操作,但我想知道这是否像听起来那样糟糕,尤其是当您处于项目的开始阶段时。您所要做的就是重写一个中间件类和一些装饰器。

Of course, I don't think this buys you anything that 1 won't get you, except that your project shouldn't break if you svn updateyour django. It may avoid some of the compatibility problems with other apps, but my guess is most problems will exist either way.

当然,我不认为这会给你带来任何 1 不会给你的东西,除非你的项目不应该破坏你svn update的 django。它可能会避免与其他应用程序的一些兼容性问题,但我的猜测是大多数问题都会存在。

回答by Leigh Brenecki

There are anumber of ways to do this, but here's what I'd do: I'd allow a user to enter an email, username (which must contain at least one letter and no @symbols) or mobile number. Then, when I validate it:

有多种方法可以做到这一点,但我会这样做:我允许用户输入电子邮件、用户名(必须包含至少一个字母且无@符号)或手机号码。然后,当我验证它时:

  1. Check for the presence of @. If so, set it as the user's email, hash it appropriately and set it as their username as well.
  2. Check to see if it's only numbers, dashes and +. Then, strip the appropriate characters and store it as both mobile number and username (if you're storing the mobile number in another model for SMS purposes or something).
  3. If it's not either, just set it as username.
  1. 检查 的存在@。如果是这样,请将其设置为用户的电子邮件,对其进行适当的散列并将其设置为他们的用户名。
  2. 检查是否只有数字、破折号和+. 然后,去除适当的字符并将其存储为手机号码和用户名(如果您将手机号码存储在另一个模型中用于 SMS 目的或其他目的)。
  3. 如果不是,只需将其设置为用户名。

I'd also validate the user/phone/email field similarly on login and look in the appropriate place so that if, say, a user signs up with their mobile number and then changes their username (for some other purpose), they can still sign in with their mobile number.

我还会在登录时类似地验证用户/电话/电子邮件字段并查看适当的位置,以便如果用户使用他们的手机号码注册然后更改其用户名(出于某些其他目的),他们仍然可以使用他们的手机号码登录。