我有一个扩展 AbstractUser 的自定义用户模型。我添加了两个自定义字段。但我希望默认电子邮件字段是唯一的并且是必需的。我在网上搜索了很多,但找不到好的建议。
使用覆盖的“clean_email”方法在扩展的用户创建表单中这样做是正确的方法吗?
谢谢
我有一个扩展 AbstractUser 的自定义用户模型。我添加了两个自定义字段。但我希望默认电子邮件字段是唯一的并且是必需的。我在网上搜索了很多,但找不到好的建议。
使用覆盖的“clean_email”方法在扩展的用户创建表单中这样做是正确的方法吗?
谢谢
我面临同样的问题,我正在扩展 AbstractUser 因为我只需要添加信息。这是唯一对我有用的东西:
AbstractUser._meta.get_field('email')._unique = True
这解决了独特的问题,但我仍然无法使其成为必需,当您扩展 AbstractUser 时,它的电子邮件字段不是,如果您从管理员添加扩展用户,并且因为表单不采用这种方式,则会注意到它。
我试过了
AbstractUser._meta.get_field('email')._blank = False
AbstractUser._meta.get_field('email')._null = False
但这似乎不起作用。
编辑:出于某种原因,独特的作品与'_',但空白和空不,我只是试过这个
AbstractUser._meta.get_field('email').blank = False
AbstractUser._meta.get_field('email').null = False
它奏效了!
email
已经在AbstractUser.REQUIRED_FIELDS
.
为了使它独一无二:
class User(AbstractUser):
...
(emailField,) = (f for f in User._meta.fields if f.name == "email")
emailField.unique = True
有点hacky,但应该可以
或者您可以使用自定义调整简单地扩展AbstractBaseUser
并添加自己缺少的东西AbstractUser
也许您可以覆盖__init__
模型上的 以使该字段成为必需且唯一的。
更新
在玩了一会儿之后,我发现这说起来容易做起来难(我还没有找到一种方法来required = False
在父类中创建子类中的字段)。
这里给出的有点老套但有效的解决方案在 Django 1.7 中不起作用
User._meta.get_field('email')._unique = True
这是因为在模块范围内访问模型违反了 AppRegistry 断言,即在加载完成之前不应修改模型:
django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.
您可以使用新的App Loading功能为您执行此操作。使用在您的应用程序目录ready
中执行猴子补丁的方法定义一个 AppConfig 类。apps.py
from django.apps import AppConfig
class YourAppConfig(AppConfig):
name="your_app_name"
def ready(self):
from .models import MyAbstractUser
MyAbstractUser._meta.get_field_by_name('email')[0]._unique=True
这假设MyAbstractUser
是 的子类AbstractUser
。
您还必须__init__.py
在应用程序的目录中进行修改:
default_app_config = 'your_app_name.apps.YourAppConfig'
如果你忘记了你的新ready
方法将不会被调用。
现在您的系统检查应该通过了。
mderk 的回答并不完全适合我 - 我得到了AttributeError: can't set attribute
. 原因是 Django 在内部将unique
' 值保存在self._unique
.
所以长话短说:
class User(AbstractUser):
...
(emailField,) = (f for f in User._meta.fields if f.name == "email")
emailField._unique = True
作品。
甚至更好:
User._meta.get_field('email')._unique = True
AbstractUser._meta.get_field('email')._unique = True
AbstractUser._meta.get_field('email').blank = False
AbstractUser._meta.get_field('email').null = False
它起作用了,我检查了数据库。但是,当我从默认管理页面创建用户时,它将毫无问题地创建它并且电子邮件字段为空。它只会在您尝试保存时询问电子邮件。但它仍然是一个 goog 解决方案。我什至不需要 sudo。我建议确保在从视图创建新用户时需要电子邮件。*使用 django 1.10 和 SQlite3
这也将使您了解可以覆盖的字段:
(如果有人在您创建时找到了一种方法来制作必填字段,请发表评论:))
dir(User._meta.get_field('email'))
Out[3]:
['__class__',
'__copy__',
'__deepcopy__',
'__delattr__',
'__dict__',
'__doc__',
'__eq__',
'__format__',
'__ge__',
'__getattribute__',
'__gt__',
'__hash__',
'__init__',
'__le__',
'__lt__',
'__module__',
'__new__',
'__reduce__',
'__reduce_ex__',
'__repr__',
'__setattr__',
'__sizeof__',
'__str__',
'__subclasshook__',
'__unicode__',
'__weakref__',
'_blank',
'_check_backend_specific_checks',
'_check_choices',
'_check_db_index',
'_check_deprecation_details',
'_check_field_name',
'_check_max_length_attribute',
'_check_null_allowed_for_primary_keys',
'_description',
'_error_messages',
'_get_flatchoices',
'_get_lookup',
'_get_val_from_obj',
'_unique',
'_unregister_lookup',
'_validators',
'_verbose_name',
'attname',
'auto_created',
'auto_creation_counter',
'blank',
'cached_col',
'check',
'choices',
'class_lookups',
'clean',
'clone',
'column',
'concrete',
'contribute_to_class',
'creation_counter',
'db_check',
'db_column',
'db_index',
'db_parameters',
'db_tablespace',
'db_type',
'db_type_suffix',
'deconstruct',
'default',
'default_error_messages',
'default_validators',
'description',
'editable',
'empty_strings_allowed',
'empty_values',
'error_messages',
'flatchoices',
'formfield',
'get_attname',
'get_attname_column',
'get_cache_name',
'get_choices',
'get_col',
'get_db_converters',
'get_db_prep_save',
'get_db_prep_value',
'get_default',
'get_filter_kwargs_for_object',
'get_internal_type',
'get_lookup',
'get_pk_value_on_save',
'get_prep_value',
'get_transform',
'has_default',
'help_text',
'hidden',
'is_relation',
'many_to_many',
'many_to_one',
'max_length',
'model',
'name',
'null',
'one_to_many',
'one_to_one',
'pre_save',
'primary_key',
'register_lookup',
'rel',
'rel_db_type',
'related_model',
'remote_field',
'run_validators',
'save_form_data',
'select_format',
'serialize',
'set_attributes_from_name',
'system_check_deprecated_details',
'system_check_removed_details',
'to_python',
'unique',
'unique_for_date',
'unique_for_month',
'unique_for_year',
'validate',
'validators',
'value_from_object',
'value_to_string',
'verbose_name']