简体   繁体   中英

Django custom user creation form

I'm trying to create a new user in my Django app but nothing happens. I'm using a custom user auth model. Part of the code I edited from the docs. Why the error message "Users must have an email address" is reported by the model and not the forms? Why am I not able to create a user? I don't get any error back.

My model:

from django.db import models
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
from django.utils import timezone


class MyUserManager(BaseUserManager):

    def create_user(self, email, name, neighborhood, password=None):

        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            email=self.normalize_email(email),
            name=name,
            neighborhood=neighborhood
        )

        user.set_password(password)
        user.save(using=self._db)

        return user

    def create_superuser(self, email, name, neighborhood, password):

        user = self.create_user(
            email=email,
            name=name,
            password=password,
            neighborhood=neighborhood
        )

        user.is_admin = True
        user.save(using=self._db)

        return user


class MyUser(AbstractBaseUser):

    name = models.CharField(max_length=255)
    email = models.EmailField(max_length=255, unique=True)
    created_at = models.DateTimeField(default=timezone.now, blank=True)
    neighborhood = models.CharField(max_length=255)
    consultant_id = models.IntegerField(null=True)
    moip_id = models.IntegerField(null=True)
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    objects = MyUserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['name', 'neighborhood']

    def __str__(self):
        return self.name

    def get_full_name(self):
        return self.name

    def get_short_name(self):
        return self.name

    def has_perm(self, perm, obj=None):
        return True

    def has_module_perms(self, app_label):
        return True

    @property
    def is_staff(self):
        "Is the user a member of staff?"
        # Simplest possible answer: All admins are staff
        return self.is_admin

My form:

from django import forms
from django.contrib.auth.forms import ReadOnlyPasswordHashField

from dashboard.models import MyUser


class UserCreationForm(forms.ModelForm):

    password = forms.CharField(label='Senha', widget=forms.PasswordInput)
    confirm_password = forms.CharField(label='Confirmar senha', widget=forms.PasswordInput)

    class Meta:

        model = MyUser

        # Note - include all *required* MyUser fields here,
        # but don't need to include password and confirm_password as they are
        # already included since they are defined above.
        fields = ('email', 'name', 'neighborhood',)

    def clean(self):

        cleaned_data = super(UserCreationForm, self).clean()

        password = cleaned_data.get('password')
        confirm_password = cleaned_data.get('confirm_password')

        if password and confirm_password and password != confirm_password:
            raise forms.ValidationError('As senhas nao batem.')

    def save(self, commit=True):

        user = super(UserCreationForm, self).save(commit=False)

        user.set_password(self.cleaned_data['password'])

        if commit:
            user.save()

        return user

And my view:

from django.shortcuts import render

from frontend.forms import UserCreationForm

# Create your views here.

def register(request):

    message = None

    if request.method == 'POST':

        form = UserCreationForm(request.POST)

        if form.is_valid():

            form.save()

    return render(request, 'frontend/register.html', {'message': message})

So far I know, you do not raise error from forms, you just -

1) add the error in it, then it automatically gets invalided by django and is posted back with error and also

2) since you are overriding the clean method you must return the cleaned data . So change the clean method with these details -

def clean(self):
    cleaned_data = self.cleaned_data

    password = cleaned_data.get('password')
    confirm_password = cleaned_data.get('confirm_password')

    if password and confirm_password and password != confirm_password:
        #raise forms.ValidationError('As senhas nao batem.') => we do not raise error in form clean, instead we add it in validation error.
        self.add_error('confirm_password', 'As senhas nao batem.')
    return super(UserCreationForm, self).clean() # =>this line is IMPORTANT to not break the calling hierarchy

a little shorter -

def clean(self):
    if self.cleaned_data['password'] != self.cleaned_data['confirm_password']:
        self.add_error('confirm_password', 'Password & Confirm Password must match.')

    return super().clean()

Sine you are not returning anything, the cleaned_data of your form is empty and thus django is returning you back to the form page with no data in it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM