Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django admin form for creating AbstractUser extended model

I've got a custome user model that extends/inherits AbstractUser. I also want the user creation form in admin to match, but for some reason I can only get it to show Username and Password fields. Nothing else.

What I find particularly interesting is that the changes I makes to those 3 fields in my admin.py reflect in the creation form, but the additional fields never show up. So for example I can change the helptext or label of a password1 and is renders that in the form, but the other fields don't.

Also, if I set extend UserAdmin and register that (as is shown in the code below) I get the 3 field creation view of a generic user, but if I extend ModelAdmin I get ALL my fields, but can't use the password update form. It 404s.

Of note also is that the link into the object list is 'User', not 'CommonUser' as my model is called, but that is probably a class meta somewhere.


admin.py

from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import UserChangeForm, UserCreationForm
from models import CommonUser, Account, Registry
from django import forms


class MyUserChangeForm(UserChangeForm):
    class Meta(UserChangeForm.Meta):
        model = CommonUser


class MyUserCreationForm(UserCreationForm):

 password = forms.CharField(
    label='Password',
    max_length = 32,
    required=True,
    widget=forms.PasswordInput,
    )

password2 = forms.CharField(
    label='Confirm',
    max_length = 32,
    required=True,
    widget=forms.PasswordInput,
    help_text="Make sure they match!",
    )


class Meta(UserCreationForm.Meta):
    model = CommonUser
    fields = ['username', 'password', 'password2', 'email',
        'first_name','last_name','address','city','state','zipcode',
        'phone1','phone2',]
    help_texts = {
        'password': 'Must be at least 8 characters.',
    }


def clean_username(self):
    username = self.cleaned_data['username']
    try:
        CommonUser.objects.get(username=username)
    except CommonUser.DoesNotExist:
        return username
    raise forms.ValidationError(self.error_messages['duplicate_username'])


class MyUserAdmin(UserAdmin):
    form = MyUserChangeForm
    add_form = MyUserCreationForm
    fieldsets = UserAdmin.fieldsets + (
        ('Personal info', {'fields': ('address', 'phone1',)}),
    )

admin.site.register(CommonUser, MyUserAdmin)

(snippet of) model.py

from django.contrib.auth.models import AbstractUser

class CommonUser(AbstractUser):
    "User abstraction for carrying general info."

    WORK_STATES = (
            ('FL', 'FL'),
        )

    address = models.CharField(max_length=50)
    city = models.CharField(max_length=30)
    state = models.CharField(max_length=2, default='FL', choices=WORK_STATES)
    zipcode = models.CharField(max_length=10)
    phone1 = models.CharField(max_length=15)
    phone2 = models.CharField(max_length=15, null=True)
    gets_email_updates = models.BooleanField(default=False)

sources

Extending new user form, in the admin Django Using Django auth UserAdmin for a custom user model https://docs.djangoproject.com/en/1.6/topics/auth/customizing/#a-full-example

like image 689
meteorainer Avatar asked Dec 06 '22 02:12

meteorainer


1 Answers

UserAdmin from django.contrib.auth.admin also sets the "add_fieldsets" attribute, that sets the fields to be shown on the add user view. Since UserAdmin sets this field you need to overwrite it to set your own fields.

Here is an example:

class CustomUserAdmin(UserAdmin):
# ...code here...

    fieldsets = (
        (None, {'fields': ('email',)}),
        (_('Personal info'), {'fields': ('first_name', 'last_name')}),
        (_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser',
                                       'groups', 'user_permissions')}),
        (_('Important dates'), {'fields': ('last_login', 'date_joined')}),
    )
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'first_name', 'last_name', 'password1',
                       'password2')}
         ),
    )

Hope this helps!

like image 174
ignacio.munizaga Avatar answered Feb 01 '23 23:02

ignacio.munizaga