2013-02-15 1 views
6

У меня есть пользовательская модель, расширяющая AbstractUser. Я добавил два настраиваемых поля. Но я хочу, чтобы поле электронной почты по умолчанию было uniqe и требовалось. Я много искал в сети, но не нашел хорошего совета.Django 1.5 override абстрактное поле электронной почты требуется и уникально

Правильный способ сделать это в расширенной форме пользовательской формы с переопределенным методом «clean_email»?

Thanx

ответ

0

Может быть, вы могли бы переопределить __init__ на вашей модели, чтобы сделать поле обязательным и уникальным.

UPDATE

После немного играть вокруг я нашел, что это легче сказать, чем сделать (я не нашел способ сделать поле в классе ребенка требуется в то время как required = False на родителя).

+0

Я уже создал модель и добавил пользователей, поэтому я не могу переопределить ее из расширенной модели абстрактного пользователя. Он дает - FieldError: локальное поле «электронная почта» в столкновении класса «CustomUser» с полем аналогичного имени из базового класса «AbstractUser» - – ratata

+0

, он дает объект «unicode», не имеет атрибута «обязательная» ошибка – ratata

+0

Я не смог найти решение вопроса. Я думаю, что лучше всего расширить «AbstractBaseUser». ??? – ratata

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 себя пользовательских ухищрений

+0

Если вы запустите это в основной части класса, 'User' не определен (как' self'). Я попробовал это в '__init__' и получил' AttributeError: не могу установить атрибут'. –

+0

Я бы не запускал это в '__init__' или где-либо внутри определения класса. Просто поставьте это право ** под ** определение класса – mderk

+0

В Django 1.7 это не работает. Я нашел это решение, работающее: http://stackoverflow.com/a/26108834/865664 –

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 
5

Im сталкиваются с той же проблемой, я расширяющий AbstractUser как мне нужно только добавить информацию. Это было единственное, что работает для меня:

AbstractUser._meta.get_field('email')._unique = True 

Это решает уникальную проблему, но до сих пор я не могу сделать это необходимо, когда вы расширяете AbstractUser это адрес электронной почты поля нет, то можно заметить, если добавить расширенный пользователь от администратора, а также потому, что формы не принимают его таким образом.

Я попытался

AbstractUser._meta.get_field('email')._blank = False 
AbstractUser._meta.get_field('email')._null = False 

Но это не похоже на работу.

EDIT: По какой-то причине уникальных работ с «_», но пустой и пустой не, я просто попытался это

AbstractUser._meta.get_field('email').blank = False 
AbstractUser._meta.get_field('email').null = False 

И это сработало!

+0

Так что это полезно! ;) Спасибо – pztrick

+1

Это работает в версии 1.6, но в реестре приложений изменилось с 1.7. Любая идея о том, как адаптировать этот ответ для использования в 1.7? Как-то вы подняли '' raise AppRegistryNotReady («Модели еще не загружены».) '' – Flowpoke

+0

Простите Flowpoke, я еще не переехал в 1.7, но я не знаю, как его решить. – steven2308

0

Немного хакерское, хотя и эффективное решение, данное здесь, не работает в Django 1.7

User._meta.get_field('email')._unique = True 

Это происходит потому, что доступ к модели в рамках модуля нарушает утверждение AppRegistry, что модели не должны быть изменены, пока загрузка не завершена:

django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet. 

Вы можете использовать новую функцию App Loading, чтобы сделать это для тебя. Определите класс AppConfig с помощью метода ready, который делает патч обезьяны в 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 не будет вызван.

Теперь ваши системные проверки должны пройти.

0
AbstractUser._meta.get_field('email')._unique = True 
AbstractUser._meta.get_field('email').blank = False 
AbstractUser._meta.get_field('email').null = False 

Это сработало, и я проверил базу данных. Однако, когда я создаю пользователя на странице администрирования по умолчанию, он создаст его без проблем и пустое поле электронной почты. Когда вы попытаетесь сохранить его, он попросит только об этом. Но это все еще решение для goog. Мне даже не нужно sudo. Я рекомендую вам убедиться, что вам требуется электронное письмо при создании нового пользователя из представлений. * Использование Джанго 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'] 
Смежные вопросы