Django 1.5 redefines abstractuser email field, which is necessary and unique

I have a custom model extending AbstractUser. I added two custom fields. But I want the default email field to be uniqe and required. I searched a lot on the net but did not find good advice.

Is this correct in an extended usercreation form with an overridden "clean_email" method?

Thanx

+6
source share
6 answers

Im facing the same problem, I am expanding AbstractUser since I only need to add the information. This is the only thing that worked for me:

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

This solves a unique problem, but still I cannot demand it when you extend AbstractUser, this email field is NOT, this can be noticed if you add an advanced user from the administrator, and also because the forms do not accept it this way.

I tried

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

But that does not work.

EDIT: For some reason, the unique works with '_', but empty and empty don't, I just tried this

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

And it worked!

+5
source

email already in AbstractUser.REQUIRED_FIELDS .

To make it unique:

 class User(AbstractUser): ... (emailField,) = (f for f in User._meta.fields if f.name == "email") emailField.unique = True 

Stealth but should work

Or you can simply extend AbstractBaseUser and add the missing material from AbstractUser yourself with your user preferences

+2
source

Perhaps you could override __init__ in your model to make the field mandatory and unique.

UPDATE

After a little game, I found this easier said than done (I did not find a way to create the field in the child class required while required = False on the parent).

0
source

Mderk's answer didn't help me - I got AttributeError: can't set attribute . The reason is that inside Django stores the unique value in self._unique .

So, a short short story:

 class User(AbstractUser): ... (emailField,) = (f for f in User._meta.fields if f.name == "email") emailField._unique = True 

work.

Or even better :

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

A somewhat hacky, albeit effective, solution given here does not work in Django 1.7

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

This is because accessing the model in the module area violates the AppRegistry statement that the models should not be changed until the download is complete:

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

You can use the new Download App function to do this for you. Define the AppConfig class with the ready method, which makes the monkey patch in apps.py in your application directory.

 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 

Suppose MyAbstractUser is a subclass of AbstractUser .

You will also need to change __init__.py in the application directory:

 default_app_config = 'your_app_name.apps.YourAppConfig' 

If you forget that your new ready method will not be called.

Your system checks should now pass.

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

This worked and I checked the database. However, when I create a user on the default administration page, he will create it without problems and an empty email field. When you try to save it, he will only ask about it. But it is still a goog solution. I didn’t even need a court. I recommend that you make sure you need an email when creating a new user from the submissions. * Using django 1.10 and SQlite3

It will also give you an idea of ​​the fields that you can override:

(If someone finds a way to create the field needed when creating it, leave a comment :))

 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'] 
0
source

All Articles