我有一个扩展AbstractUser的自定义用户模型。我添加了两个自定义字段。但我希望默认的电子邮件字段是唯一且必需的。我在网上搜索了很多,但找不到好的建议。
使用覆盖的'clean_email'方法在扩展的usercreationform中执行此操作是否正确?
感谢名单
答案 0 :(得分:7)
我面临同样的问题,我正在扩展AbstractUser,因为我只需要添加信息。这是唯一对我有用的东西:
AbstractUser._meta.get_field('email')._unique = True
这解决了这个独特的问题,但是我仍然无法满足它的要求,当你扩展AbstractUser时它的电子邮件字段不是,如果你从管理员添加一个扩展用户并且因为表单不接受它,它会被注意到那样。
我试过
AbstractUser._meta.get_field('email')._blank = False
AbstractUser._meta.get_field('email')._null = False
但它似乎不起作用。
编辑: 出于某种原因,使用'_'但空白和null的独特作品不会,我只是尝试了这个
AbstractUser._meta.get_field('email').blank = False
AbstractUser._meta.get_field('email').null = False
它有效!
答案 1 :(得分:2)
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
自己添加缺少的内容
答案 2 :(得分:0)
也许您可以覆盖模型上的__init__
以使字段成为必需且唯一。
更新
经过一段时间的游戏,我发现这说起来容易做起来难(我没有找到一种方法,在父母的required = False
上需要在子课堂上制作一个字段)。
答案 3 :(得分:0)
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
答案 4 :(得分:0)
这里给出了一些有点愚蠢但有效的解决方案在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
中执行monkey patch。
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
方法,则不会被调用。
现在你的系统检查应该通过。
答案 5 :(得分:0)
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']