How to make email field unique in model User from

2019-01-07 05:03发布

I need to patch the standard User model of contrib.auth by ensuring the email field entry is unique:

User._meta.fields[4].unique = True

Where is best place in code to do that?

I want to avoid using the number fields[4]. It's better to user fields['email'], but fields is not dictionary, only list.

Another idea may be to open a new ticket and upload a patch with new parameter inside settings.py:

AUTH_USER_EMAIL_UNIQUE = True

Any suggestions on the most correct way to achieve email address uniqueness in the Django User model?

19条回答
叛逆
2楼-- · 2019-01-07 05:04

What about using unique_together in a "different" way? So far it works for me.

class User(AbstractUser):
    ...
    class Meta(object):
        unique_together = ('email',)
查看更多
forever°为你锁心
3楼-- · 2019-01-07 05:04

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
查看更多
不美不萌又怎样
4楼-- · 2019-01-07 05:05

Simply use below code in models.py of any app

from django.contrib.auth.models import User
User._meta.get_field('email')._unique = True
查看更多
戒情不戒烟
5楼-- · 2019-01-07 05:08

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()
查看更多
虎瘦雄心在
6楼-- · 2019-01-07 05:09

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.

查看更多
\"骚年 ilove
7楼-- · 2019-01-07 05:09

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.)

查看更多
登录 后发表回答