16👍
It’s amazing, but I found a best solution for me!
django-registration have form with checking uniqueness of email field: RegistrationFormUniqueEmail
example of usage here
51👍
Caution:
The code below was written for an older version of Django (before Custom
User Models were introduced). It contains a race condition, and
should only be used with a Transaction Isolation Level ofSERIALIZABLE
and request-scoped transactions.
Your code won’t work, as the attributes of field instances are read-only. I fear it might be a wee bit more complicated than you’re thinking.
If you’ll only ever create User instances with a form, you can define a custom ModelForm that enforces this behavior:
from django import forms
from django.contrib.auth.models import User
class UserForm(forms.ModelForm):
class Meta:
model = User
def clean_email(self):
email = self.cleaned_data.get('email')
username = self.cleaned_data.get('username')
if email and User.objects.filter(email=email).exclude(username=username).exists():
raise forms.ValidationError(u'Email addresses must be unique.')
return email
Then just use this form wherever you need to create a new user.
BTW, you can use Model._meta.get_field('field_name')
to get fields by name, rather than by position. So for example:
# The following lines are equivalent
User._meta.fields[4]
User._meta.get_field('email')
UPDATE
The Django documentation recommends you use the clean
method for all validation that spans multiple form fields, because it’s called after all the <FIELD>.clean
and <FIELD>_clean
methods. This means that you can (mostly) rely on the field’s value being present in cleaned_data
from within clean
.
Since the form fields are validated in the order they’re declared, I think it’s okay to occasionally place multi-field validation in a <FIELD>_clean
method, so long as the field in question appears after all other fields it depends on. I do this so any validation errors are associated with the field itself, rather than with the form.
- [Django]-Accessing "Media" files in Django
- [Django]-Simple guestbook django: __init__() takes 1 positional argument but 2 were given
- [Django]-Django values_list vs values
41👍
What about using unique_together
in a “different” way? So far it works for me.
class User(AbstractUser):
...
class Meta(object):
unique_together = ('email',)
- [Django]-Pycharm error Django is not importable in this environment
- [Django]-Django REST Framework combining routers from different apps
- [Django]-What's the point of Django's collectstatic?
21👍
Simply use below code in models.py of any app
from django.contrib.auth.models import User
User._meta.get_field('email')._unique = True
- [Django]-Django Setup Default Logging
- [Django]-Django ModelForm to have a hidden input
- [Django]-Using Python's os.path, how do I go up one directory?
17👍
In settings module:
# Fix: username length is too small,email must be unique
from django.contrib.auth.models import User, models
User._meta.local_fields[1].__dict__['max_length'] = 75
User._meta.local_fields[4].__dict__['_unique'] = True
- [Django]-Django: guidelines for speeding up template rendering performance
- [Django]-Django's self.client.login(…) does not work in unit tests
- [Django]-Check if an object exists
8👍
Your form should look something like this.
def clean_email(self):
email = self.cleaned_data.get('email')
username = self.cleaned_data.get('username')
print User.objects.filter(email=email).count()
if email and User.objects.filter(email=email).count() > 0:
raise forms.ValidationError(u'This email address is already registered.')
return email
- [Django]-How to revert the last migration?
- [Django]-How to produce a 303 Http Response in Django?
- [Django]-South migration: "database backend does not accept 0 as a value for AutoField" (mysql)
6👍
To ensure a User, no matter where, be saved with a unique email, add this to your models:
@receiver(pre_save, sender=User)
def User_pre_save(sender, **kwargs):
email = kwargs['instance'].email
username = kwargs['instance'].username
if not email: raise ValidationError("email required")
if sender.objects.filter(email=email).exclude(username=username).count(): raise ValidationError("email needs to be unique")
Note that this ensures non-blank email too. However, this doesn’t do forms validation as would be appropriated, just raises an exception.
- [Django]-Django test RequestFactory vs Client
- [Django]-Django: Example of generic relations using the contenttypes framework?
- [Django]-How to change status of JsonResponse in Django
3👍
Django has a Full Example on its documentation on how to substitute and use a Custom User Model, so you can add fields and use email as username.
- [Django]-Scoped_session(sessionmaker()) or plain sessionmaker() in sqlalchemy?
- [Django]-How do i pass GET parameters using django urlresolvers reverse
- [Django]-Django Admin Show Image from Imagefield
2👍
One possible way to do this is to have a pre-save hook on the User object and reject the save of the email already exists in the table.
- [Django]-Django character set with MySQL weirdness
- [Django]-Unable to perform collectstatic
- [Django]-Django: best practice way to get model from an instance of that model
2👍
This method won’t make email field unique at the database level, but it’s worth trying.
Use a custom validator:
from django.core.exceptions import ValidationError
from django.contrib.auth.models import User
def validate_email_unique(value):
exists = User.objects.filter(email=value)
if exists:
raise ValidationError("Email address %s already exists, must be unique" % value)
Then in forms.py:
from django.contrib.auth.models import User
from django.forms import ModelForm
from main.validators import validate_email_unique
class UserForm(ModelForm):
#....
email = forms.CharField(required=True, validators=[validate_email_unique])
#....
- [Django]-How to access the user profile in a Django template?
- [Django]-Itertools.groupby in a django template
- [Django]-<Django object > is not JSON serializable
2👍
I think that the correct answer would assure that uniqueness check was placed inside the database (and not on the django side). Because due to timing and race conditions you might end with duplicate emails in the database despite having for example pre_save
that does proper checks.
If you really need this badly I guess you might try following approach:
- Copy User model to your own app, and change field email to be unique.
- Register this user model in the admin app (using admin class from
django.contrib.auth.admin
) - Create your own authentication backend that uses your model instead of django one.
- [Django]-How to get the current language in Django?
- [Django]-Django: Record with max element
- [Django]-OSError: [Errno 18] Invalid cross-device link
2👍
Add the below function in any of the models.py file. Then run makemigrations and migrate. Tested on Django1.7
def set_email_as_unique():
"""
Sets the email field as unique=True in auth.User Model
"""
email_field = dict([(field.name, field) for field in MyUser._meta.fields])["email"]
setattr(email_field, '_unique', True)
#this is called here so that attribute can be set at the application load time
set_email_as_unique()
- [Django]-Different db for testing in Django?
- [Django]-Django-reversion and related model
- [Django]-Django's ModelForm unique_together validation
2👍
Since version 1.2 (May 11th, 2015) there has been a way to dynamically import any chosen registration form using the settings option REGISTRATION_FORM
.
So, one could use something like this:
REGISTRATION_FORM = 'registration.forms.RegistrationFormUniqueEmail'
This is documented here.
And here’s the link to the changelog entry.
- [Django]-How to create a Django FloatField with maximum and minimum limits?
- [Django]-Is there a way to negate a boolean returned to variable?
- [Django]-Import error django corsheaders
2👍
Django does not allow direct editing User object but you can add pre_save signal and achieve unique email. for create signals u can follow https://docs.djangoproject.com/en/2.0/ref/signals/. then add the following to your signals.py
@receiver(pre_save, sender=User)
def check_email(sender,instance,**kwargs):
try:
usr = User.objects.get(email=instance.email)
if usr.username == instance.username:
pass
else:
raise Exception('EmailExists')
except User.DoesNotExist:
pass
- [Django]-Celery discover tasks in files with other filenames
- [Django]-Error: No module named psycopg2.extensions
- [Django]-Django's Double Underscore
1👍
Add somewhere this:
User._meta.get_field_by_name('email')[0]._unique = True
and then execute SQL similar to this:
ALTER TABLE auth_user ADD UNIQUE (email);
- [Django]-How to Unit test with different settings in Django?
- [Django]-How to pass information using an HTTP redirect (in Django)
- [Django]-Django: Arbitrary number of unnamed urls.py parameters
0👍
The first answer here is working for me when I’m creating new users, but it fails when I try to edit a user, since I am excluding the username from the view. Is there a simple edit for this that will make the check independent of the username field?
I also tried including the username field as a hidden field (since I don’t want people to edit it), but that failed too because django was checking for duplicate usernames in the system.
(sorry this is posted as an answer, but I lack the creds to post it as a comment. Not sure I understand Stackoverflow’s logic on that.)
- [Django]-Django Query Related Field Count
- [Django]-How to implement FirebaseDB with a Django Web Application
- [Django]-Why do we need to use rabbitmq
0👍
You can use your own custom user model for this purpose. You can use email as username or phone as username , can have more than one attribute.
In your settings.py you need to specify below settings
AUTH_USER_MODEL = ‘myapp.MyUser’.
Here is the link that can help you .
https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#auth-custom-user
- [Django]-How to properly use the "choices" field option in Django
- [Django]-GeoDjango GEOSException error
- [Django]-How to mix queryset results?
-2👍
from an User inherited model, redefine the attribute correctly. It should work, as is it’s not usefull to have that in django core because it’s simple to do.
- [Django]-How to access Enum types in Django templates
- [Django]-What is a "django backend"?
- [Django]-Variable subtraction in django templates
-5👍
I went to \Lib\site-packages\django\contrib\auth\models
and in class AbstractUser(AbstractBaseUser, PermissionsMixin):
I changed email to be:
email = models.EmailField(_('email address'), **unique=True**, blank=True)
With this if you try to register with email address already present in the database you will get message: User with this Email address already exists.
- [Django]-Django syncdb and an updated model
- [Django]-Django – getting Error "Reverse for 'detail' with no arguments not found. 1 pattern(s) tried:" when using {% url "music:fav" %}
- [Django]-Test that user was logged in successfully