Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django 1.5: UserCreationForm & Custom Auth Model

I'm using Django 1.5 & Python 3.2.3.

I've got a custom Auth setup, which uses an email address instead of a username. There's no username defined in the model at all. That works fine. Yet, when I build a user creation form, it adds in a username field anyway. So I tried defining exactly which fields I want displayed, but it's still forcing a username field into the form anyway.... even tho it doesn't even exist in the custom auth model. How can I make it stop doing that?

My form for this is defined like so:

class UserCreateForm(UserCreationForm):

    class Meta:
        model = MyUsr
        fields = ('email','fname','surname','password1','password2',
                  'activation_code','is_active')

At the docs, the Custom Users and Builtin Forms says it "Must be re-written for any custom user model." and I think that's what I'm doing here. Neither this, nor the UserCreationForm documentation say anything more about this though. So I don't know what I'm missing. I didn't find anything via Google either.

like image 512
Zamphatta Avatar asked May 15 '13 10:05

Zamphatta


People also ask

What is UserAdmin in Django?

Django uses UserAdmin to render the nice admin look for User model. By just using this in our admin.py -file, we can get the same look for our model. from django.contrib.auth.admin import UserAdmin admin.site.register(MyUser, UserAdmin)

What is Auth_user_model in Django?

Django allows you to override the default user model by providing a value for the AUTH_USER_MODEL setting that references a custom model. Method 2 – AUTH_USER_MODEL : AUTH_USER_MODEL is the recommended approach when referring to a user model in a models.py file.


1 Answers

Your UserCreationForm should look something like

# forms.py
from .models import CustomUser

class UserCreationForm(forms.ModelForm):
    password1 = forms.CharField(label="Password", widget=forms.PasswordInput)
    password2 = forms.CharField(label="Password confirmation", widget=forms.PasswordInput)

    class Meta:
        model = CustomUserModel
        # Note - include all *required* CustomUser fields here,
        # but don't need to include password1 and password2 as they are
        # already included since they are defined above.
        fields = ("email",)

    def clean_password2(self):
        # Check that the two password entries match
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            msg = "Passwords don't match"
            raise forms.ValidationError("Password mismatch")
        return password2

    def save(self, commit=True):
        user = super(UserCreationForm, self).save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user

You'll also want a user change form, which won't overrwrite the password field:

class UserChangeForm(forms.ModelForm):
    password = ReadOnlyPasswordHashField()

    class Meta:
        model = CustomUser

    def clean_password(self):
        # always return the initial value
        return self.initial['password']

Define these in your admin like this:

#admin.py

from .forms import UserChangeForm, UserAddForm

class CustomUserAdmin(UserAdmin):
    add_form = UserCreationForm
    form = UserChangeForm

You'll also need to override list_display, list_filter, search_fields, ordering, filter_horizontal, fieldsets, and add_fieldsets (everything in django.contrib.auth.admin.UserAdmin that mentions username, I think I listed all of it).

like image 148
Chris Lawlor Avatar answered Sep 20 '22 18:09

Chris Lawlor