我需要通过确保电子邮件字段条目是唯一的来修补 contrib.auth
的标准用户模型:
User._meta.fields[4].unique = True
代码中最好的位置在哪里?
我想避免使用数字字段[4] . 用户字段['email']更好,但字段不是字典,只有列表 .
另一个想法可能是打开一张新票并在 settings.py
中上传一个带有新参数的补丁:
AUTH_USER_EMAIL_UNIQUE = True
有关在Django用户模型中实现电子邮件地址唯一性的最正确方法的任何建议吗?
19 回答
在这里添加:
然后执行类似于这样的SQL:
Django不允许直接编辑User对象,但您可以添加pre_save信号并实现唯一的电子邮件 . 对于创建信号,你可以按照https://docs.djangoproject.com/en/2.0/ref/signals/ . 然后将以下内容添加到signals.py中
您的代码将无法工作,因为字段实例的属性是只读的 . 我担心它可能比你想的要复杂得多 .
如果您只使用表单创建User实例,则可以定义强制执行此行为的自定义ModelForm:
然后只需在需要创建新用户的地方使用此表单 .
顺便说一句,您可以使用
Model._meta.get_field('field_name')
按名称而不是按位置获取字段 . 例如:更新
Django文档建议您使用
clean
方法进行跨越多个表单字段的所有验证,因为它在所有<FIELD>.clean
和<FIELD>_clean
方法之后调用 . 这意味着您可以(大部分)依赖cleaned_data
中cleaned_data
中存在的字段值 .由于表单字段按顺序进行验证,因此只要有问题的字段出现在它所依赖的所有其他字段之后,它们就可以偶尔在
<FIELD>_clean
方法中进行多字段验证 . 我这样做是因为任何验证错误都与字段本身相关联,而不是与表单相关联 .以"different"方式使用unique_together怎么样?到目前为止它对我有用 .
在设置模块中:
这太棒了,但我找到了最适合我的解决方案!
django-registration 具有检查电子邮件字段唯一性的表单:RegistrationFormUniqueEmail
用法示例here
你的表格看起来应该是这样的 .
要确保用户,无论身在何处,使用唯一的电子邮件保存,请将其添加到您的模型中:
请注意,这也确保了非空白电子邮件 . 但是,这不会进行表格验证,因为它会被占用,只会引发异常 .
只需在任何应用程序的models.py中使用以下代码
Django有关于如何替换和使用自定义用户模型的文档Full Example,因此您可以添加字段并使用电子邮件作为用户名 .
一种可能的方法是在User对象上使用预保存挂钩,并拒绝保存表中已存在的电子邮件 .
我认为正确的答案可以确保在数据库中放置唯一性检查(而不是在django端) . 因为时间和竞争条件,您可能会在数据库中以重复的电子邮件结束,尽管例如
pre_save
正在进行适当的检查 .如果你真的需要这个,我想你可能会尝试以下方法:
将用户模型复制到您自己的应用程序,并将字段电子邮件更改为唯一 .
在管理员应用中注册此用户模型(使用
django.contrib.auth.admin
中的管理类)创建自己的身份验证后端,使用您的模型而不是django .
此方法不会使电子邮件字段在数据库级别上唯一,但值得尝试 .
使用自定义validator:
然后在forms.py中:
在任何models.py文件中添加以下函数 . 然后运行makemigrations并迁移 . 在Django1.7上测试过
从版本1.2(2015年5月11日)开始,有一种方法可以使用设置选项
REGISTRATION_FORM
动态导入任何选定的注册表单 .所以,可以使用这样的东西:
REGISTRATION_FORM = 'registration.forms.RegistrationFormUniqueEmail'
记录here .
这是changelog entry的链接 .
第一个答案在这里我在创建新用户时正在为我工作,但是当我尝试编辑用户时它失败了,因为我从视图中排除了用户名 . 是否有一个简单的编辑,使检查独立于用户名字段?
我还尝试将用户名字段包含为隐藏字段(因为我不希望人们编辑它),但这也失败了因为django正在检查系统中的重复用户名 .
(对不起,这是作为答案发布的,但我缺乏将其作为评论发布的信誉 . 不确定我理解Stackoverflow的逻辑 . )
您可以使用自己的自定义用户模型来实现此目的 . 您可以使用电子邮件作为用户名或电话作为用户名,可以有多个属性 .
在您的settings.py中,您需要指定以下设置AUTH_USER_MODEL ='myapp.MyUser' .
这是可以帮助您的链接 . https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#auth-custom-user
从用户继承的模型,正确地重新定义属性 . 它应该有效,因为它在django核心中没有用,因为它很简单 .
我去了
\Lib\site-packages\django\contrib\auth\models
并在课堂AbstractUser(AbstractBaseUser, PermissionsMixin):
我改变了电子邮件:如果您尝试使用数据库中已存在的电子邮件地址注册,您将收到消息:具有此电子邮件地址的用户已存在 .