Django 1.5覆盖抽象用户电子邮件字段是必需且唯一的

时间:2013-02-15 23:15:12

标签: django django-forms

我有一个扩展AbstractUser的自定义用户模型。我添加了两个自定义字段。但我希望默认的电子邮件字段是唯一且必需的。我在网上搜索了很多,但找不到好的建议。

使用覆盖的'clean_email'方法在扩展的usercreationform中执行此操作是否正确?

感谢名单

6 个答案:

答案 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)

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

答案 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

这假设MyAbstractUserAbstractUser的子类。

您还必须修改应用目录中的__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']