Customizing StaffMember¶
While the StaffMember
model is meant to be general, sometimes you need something extra. You can create your own subclass of StaffMember
for tweaking. In the example project you can browse the mystaff
app. To test it out:
- Comment out
'staff',
fromINSTALLED_APPS
insettings.py
- Uncomment
'mystaff',
fromINSTALLED_APPS
insettings.py
- Delete the
dev.db
file - Run
./manage.py syncdb
- Create a new superuser when prompted
Create the custom class¶
Your custom StaffMember
model is going to subclass BaseStaffMember
, which is an abstract version of StaffMember
. Add your additional fields to the class.
1 2 3 4 5 6 7 8 9 10 11 12 | from django.db import models
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from staff.models import BaseStaffMember, get_staff_updater
class MyStaffMember(BaseStaffMember):
github = models.CharField(max_length=50, blank=True)
update_staff_member = get_staff_updater(MyStaffMember)
post_save.connect(update_staff_member, sender=User)
|
Connect the signal¶
You need to manually connect the post_save
signal to a function that keeps your custom staff member class in sync.
1 2 3 4 5 6 7 8 9 10 11 12 | from django.db import models
from django.db.models.signals import post_save
from django.contrib.auth.models import User
from staff.models import BaseStaffMember, get_staff_updater
class MyStaffMember(BaseStaffMember):
github = models.CharField(max_length=50, blank=True)
update_staff_member = get_staff_updater(MyStaffMember)
post_save.connect(update_staff_member, sender=User)
|
- Import
get_staff_updater()
fromstaff.models
. See line 5 in the example. - Execute it, passing in your model, and assign it to a variable. See line 11 in the example.
- Import
post_save
fromdjango.db.models.signals
. See line 2 in the example. - Finally connect the
post_save
signal to your staff updater variable as in line 12 in the example.
Create your admin class¶
The admin class is more complicated. It consists of three parts: customizing the StaffMemberAdmin
class, creating a custom UserAdmin
, and finally swapping out the currently registered UserAdmin
class with yours.
Your own admin class¶
Your admin class simply needs to redefine the fieldsets and model of the StaffMemberAdmin
class.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin
from django.contrib import admin
from staff.admin import StaffMemberAdmin
from .models import MyStaffMember
class MyStaffMemberAdmin(StaffMemberAdmin):
fieldsets = (
('Personal Info', {'fields': ('bio', 'photo', 'website', 'phone',)}),
('Social Media', {'fields': ('github', 'twitter', 'facebook', 'google_plus')}),
('Responsibilities', {'fields': ('sites',)}),
)
model = MyStaffMember
class MyStaffUserAdmin(UserAdmin):
"""
Subclasses the UserAdmin to add the staffmember as an inline.
"""
inlines = [MyStaffMemberAdmin, ]
admin.site.unregister(User)
admin.site.register(User, MyStaffUserAdmin)
|
The class is very straightforward. Since we only added one field, github
, we copy the fieldsets
value from the base class and add that field in.
Then we set the model to our new model.
Making a custom User admin class¶
We need to add an inline class to the current UserAdmin
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin
from django.contrib import admin
from staff.admin import StaffMemberAdmin
from .models import MyStaffMember
class MyStaffMemberAdmin(StaffMemberAdmin):
fieldsets = (
('Personal Info', {'fields': ('bio', 'photo', 'website', 'phone',)}),
('Social Media', {'fields': ('github', 'twitter', 'facebook', 'google_plus')}),
('Responsibilities', {'fields': ('sites',)}),
)
model = MyStaffMember
class MyStaffUserAdmin(UserAdmin):
"""
Subclasses the UserAdmin to add the staffmember as an inline.
"""
inlines = [MyStaffMemberAdmin, ]
admin.site.unregister(User)
admin.site.register(User, MyStaffUserAdmin)
|
This is merely sublassing the existing UserAdmin
and adding our own inlines
attribute equal to a list containing the new admin class defined above.
Re-registering the UserAdmin¶
Now we carefully swap the old UserAdmin
with our UserAdmin
subclass.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin
from django.contrib import admin
from staff.admin import StaffMemberAdmin
from .models import MyStaffMember
class MyStaffMemberAdmin(StaffMemberAdmin):
fieldsets = (
('Personal Info', {'fields': ('bio', 'photo', 'website', 'phone',)}),
('Social Media', {'fields': ('github', 'twitter', 'facebook', 'google_plus')}),
('Responsibilities', {'fields': ('sites',)}),
)
model = MyStaffMember
class MyStaffUserAdmin(UserAdmin):
"""
Subclasses the UserAdmin to add the staffmember as an inline.
"""
inlines = [MyStaffMemberAdmin, ]
admin.site.unregister(User)
admin.site.register(User, MyStaffUserAdmin)
|
Django’s admin has the ability to both register an admin class and unregister an admin class. After removing any admin classes associated with the User
class, we register and associate our custom user admin class.
Gather the templates¶
Django staff includes a set of templates for various Django versions. Since we’ll remove 'staff'
from INSTALLED_APPS
, Django won’t find them any more. We need to copy them into either the project’s templates directory or your application’s template directory.
The templates, named staff.html
and staff13.html
, need to go into:
templates
admin
edit_inline
staff.html
staff13.html
Remove staff from INSTALLED_APPS¶
If Django Staff is still included in your INSTALLED_APPS
setting, you’ll have a bit of redundancy. Make sure that 'staff'
is not in that list. It still must remain available to your new application, so don’t don’t uninstall the library.