开发者

Django auth.user with unique email

开发者 https://www.devze.com 2023-02-28 05:22 出处:网络
I use the django.auth system and I\'ve this: class RegisterForm(UserCreationForm): username = forms.RegexField(label= \"Username\" , max_length = 30, regex = r\'^[\\w]+$\', error_messages = {\'invali

I use the django.auth system and I've this:

class RegisterForm(UserCreationForm):
    username = forms.RegexField(label= "Username" , max_length = 30, regex = r'^[\w]+$', error_messages = {'invalid': "This value may contain only letters, numbers and _ characters."})
    email = forms.EmailField(label = "Email")
    first_name = forms.CharField(label = "First name", required = False)
    last_name = forms.CharField(label = "Last name", required = False)

    class Meta:
        model = User
        fields = ("username", "first_name", "last_name", "email", )

    def save(self, commit = True):
        user = super(RegisterForm, self).save(commit = False)
        user.开发者_如何学编程first_name = self.cleaned_data["first_name"]
        user.last_name = self.cleaned_data["last_name"]
        user.email = self.cleaned_data["email"]
        if commit:
            user.save()
        return user

I want to set emails as uniques and check the form for this validation. How can I do it?


Somewhere in your models:

from django.contrib.auth.models import User
User._meta.get_field('email')._unique = True

Notice the underscore before unique. This is where the information is actually held. User._meta.get_field('email').unique is just a @property which looks into it.

This should work for syncdb too, so you will have consistency with the database.

Note too, that from Django 1.5 you will not have to do such things, as User model will be pluggable.


add this to your form. But this isn't perfect way. race condition is available by only using this form. I recommend you to add unique constraint at db level.

def clean_email(self):
    data = self.cleaned_data['email']
    if User.objects.filter(email=data).exists():
        raise forms.ValidationError("This email already used")
    return data

SQL to add unique constraint:

ALTER TABLE auth_user ADD UNIQUE (email)


I am not sure how to use this, but

from django.contrib.auth.models import User
User._meta.get_field_by_name('email')[0].unique=True

should do it. I guess this goes in your models.py before you run syncdb on the auth model. Bout to try this myself.


Overriding the clean() method as suggested by mumimo is described here: http://docs.djangoproject.com/en/dev/topics/forms/modelforms/#overriding-the-clean-method

Ordinarily you could use unique=True on your field definition and then use ModelForm, so that it'll automatically run clean() for all of the fields in your form, but if you're using the django.auth user class you can't modify the fields.


You can do the same thing using this in Abstract User Model:

class User(AbstractUser):
...

class Meta:
    unique_together = ('email',)


While doing the registration, i found one thing that email is not required in django auth but while simple validation, if we don't provide the email it gives 500 error as we must be checking for the email at the backend.

So to make it required, add to the registrationSerializer;

extra_kwargs = {'email': {'required': True}}

For unique email, other answers are showing that.


You can make the email unique and even allow it to be null by adding the following code in your models.py

from django.db import models
from django.contrib.auth.models import User

User.email = models.EmailField(_("email address"), blank=True, null=True, unique=True)

Tested on Django 4.0.3

0

精彩评论

暂无评论...
验证码 换一张
取 消