Using Django auth UserAdmin for a custom user model

前端 未结 6 1164
甜味超标
甜味超标 2020-11-30 17:48

From the Django.Contrib.Auth docs:

Extending Django’s default User If you’re entirely happy with Django’s User model and you just w

相关标签:
6条回答
  • 2020-11-30 17:54

    Just do as follows

    from django.contrib import admin
    from .models import MyUser
    
    admin.site.register(MyUser, admin.ModelAdmin)
    

    That's it. All MyUser model's fields will be showed up. UserAdmin's fields list to show is hardcoded (see its source code), but ModelAdmin isn't. It's flexible.

    0 讨论(0)
  • 2020-11-30 17:57

    nico's answer has been extremely helpful but I found Django still references the User model when creating a new user.

    Ticket #19353 references this problem.

    In order to fix it i had to make a few more additions to admin.py

    admin.py:

    from django.contrib import admin
    from django.contrib.auth.admin import UserAdmin
    from django.contrib.auth.forms import UserChangeForm, UserCreationForm
    from main.models import MyUser
    from django import forms
    
    
    class MyUserChangeForm(UserChangeForm):
        class Meta(UserChangeForm.Meta):
            model = MyUser
    
    
    class MyUserCreationForm(UserCreationForm):
        class Meta(UserCreationForm.Meta):
            model = MyUser
    
        def clean_username(self):
            username = self.cleaned_data['username']
            try:
                MyUser.objects.get(username=username)
            except MyUser.DoesNotExist:
                return username
            raise forms.ValidationError(self.error_messages['duplicate_username'])
    
    
    class MyUserAdmin(UserAdmin):
        form = MyUserChangeForm
        add_form = MyUserCreationForm
        fieldsets = UserAdmin.fieldsets + (
            (None, {'fields': ('extra_field1', 'extra_field2',)}),
        )
    
    admin.site.register(MyUser, MyUserAdmin)
    
    0 讨论(0)
  • 2020-11-30 18:01

    cesc's answer wasn't working for me when I attempted to add a custom field to the creation form. Perhaps it's changed since 1.6.2? Either way, I found adding the field to both fieldsets and add_fieldsets did the trick.

    ADDITIONAL_USER_FIELDS = (
        (None, {'fields': ('some_additional_field',)}),
    )
    
    class MyUserAdmin(UserAdmin):
        model = MyUser
    
        add_fieldsets = UserAdmin.add_fieldsets + ADDITIONAL_USER_FIELDS
        fieldsets = UserAdmin.fieldsets + ADDITIONAL_USER_FIELDS
    
    admin.site.register(MyUser, MyUserAdmin)
    
    0 讨论(0)
  • 2020-11-30 18:03

    After digging around the Django source code for a while, I found a working soultion. I am not totally happy with this solution, but it seems to work. Feel free to suggest better solutions!


    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)
    

    However, this alone is probably not a good solution, since Django Admin will not display any of your special fields. There are two reasons for this:

    • UserAdmin uses UserChangeForm as the form to be used when modifying the object, which in its turn uses User as its model.
    • UserAdmin defines a formsets-property, later used by UserChangeForm, which does not include your special fields.

    So, I created a special change-form which overloads the Meta inner-class so that the change form uses the correct model. I also had to overload UserAdmin to add my special fields to the fieldset, which is the part of this solution I dislike a bit, since it looks a bit ugly. Feel free to suggest improvements!

    from django.contrib.auth.admin import UserAdmin
    from django.contrib.auth.forms import UserChangeForm
    
    class MyUserChangeForm(UserChangeForm):
        class Meta(UserChangeForm.Meta):
            model = MyUser
    
    class MyUserAdmin(UserAdmin):
        form = MyUserChangeForm
    
        fieldsets = UserAdmin.fieldsets + (
                (None, {'fields': ('some_extra_data',)}),
        )
    
    
    admin.site.register(MyUser, MyUserAdmin)
    
    0 讨论(0)
  • 2020-11-30 18:10

    Another similar solution (Took from here):

    from __future__ import unicode_literals
    
    from django.contrib import admin
    from django.contrib.auth.admin import UserAdmin
    from django.contrib.auth.models import AbstractUser
    from django.utils.translation import ugettext_lazy as _
    
    from .models import User
    
    
    class UserAdminWithExtraFields(UserAdmin):
    
        def __init__(self, *args, **kwargs):
            super(UserAdminWithExtraFields, self).__init__(*args, **kwargs)
    
            abstract_fields = [field.name for field in AbstractUser._meta.fields]
            user_fields = [field.name for field in self.model._meta.fields]
    
            self.fieldsets += (
                (_('Extra fields'), {
                    'fields': [
                        f for f in user_fields if (
                            f not in abstract_fields and
                            f != self.model._meta.pk.name
                        )
                    ],
                }),
            )
    
    
    admin.site.register(User, UserAdminWithExtraFields)
    
    0 讨论(0)
  • 2020-11-30 18:19

    A simpler solution, admin.py:

    from django.contrib.auth.admin import UserAdmin
    from main.models import MyUser
    
    class MyUserAdmin(UserAdmin):
        model = MyUser
    
        fieldsets = UserAdmin.fieldsets + (
                (None, {'fields': ('some_extra_data',)}),
        )
    
    admin.site.register(MyUser, MyUserAdmin)
    

    Django will correctly reference MyUser model for creation and modification. I'm using Django 1.6.2.

    0 讨论(0)
提交回复
热议问题