6

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

使用覆盖的“clean_email”方法在扩展的用户创建表单中这样做是正确的方法吗?

谢谢

4

6 回答 6

9

我面临同样的问题,我正在扩展 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

它奏效了!

于 2013-06-28T16:18:10.277 回答
3

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

于 2013-02-16T17:29:51.890 回答
0

也许您可以覆盖__init__模型上的 以使该字段成为必需且唯一的。

更新

在玩了一会儿之后,我发现这说起来容易做起来难(我还没有找到一种方法来required = False在父类中创建子类中的字段)。

于 2013-02-15T23:27:00.220 回答
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

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方法将不会被调用。

现在您的系统检查应该通过了。

于 2014-12-04T20:43:54.593 回答
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
于 2013-05-03T10:38:06.107 回答
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']
于 2017-02-02T08:53:44.533 回答