Code

Opened 6 years ago

Last modified 3 months ago

#9602 assigned New feature

Add admin.site._registry manipulation methods

Reported by: robhudson Owned by: anonymous
Component: contrib.admin Version: master
Severity: Normal Keywords: register modeladmin
Cc: rob@… Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

This is a feature request...

Currently, one can unregister a model from the admin and register it again with a new ModelAdmin. The problem I'm anticipating is when 2 or more apps want to add ModelAdmin options to a Model and the last one wins.

Not to point out a specific 3rd party app, but this is an easily contrived example... If I have my own apps and one of them unregisters the User model's ModelAdmin and registers its own that, say, adds the is_superuser to the list_display. Then if I add the django-openid app that (currently) also unregisters the User model's ModelAdmin and registers its own that adds an inline to a ManyToManyField for the OpenID associations tied to that user. If django-openid is after my app in the INSTALLED_APPS list, I lose my list_display override. And if my app is after the django-openid app, I lose the OpenID associations inlines. (See: http://code.google.com/p/django-openid/source/browse/trunk/django_openid/admin.py)

It's possible currently to write the unregistration/registration such that this doesn't happen, but it relies on pulling the ModelAdmin out of the "private" _registry dictionary in the admin.site class. For example:

useradmin = admin.site._registry.get(User, None)
if useradmin:
    useradmin.list_display = useradmin.list_display + ('is_superuser',)
else:
    class MyUserAdmin(AuthUserAdmin):
        list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff', 'is_superuser')
    admin.site.register(User, MyUserAdmin)

I can think of a few ways of fixing this, from least involved to more involved:

  1. At the very least I think it would be nice if the internal _registry dictionary didn't have the prepended underscore to signify that it is a private variable not to be touched, so one doesn't feel dirty doing something like this.
  1. I think it would be a bit cleaner if there were methods to lookup, get, and update this dict and keep it as a private dict. For example, something like admin.site.get_model_admin(User)?
  1. Along with 2, provide methods to update common ModelAdmin options, like list_display. This one is definitely venturing into debatable area, but something like useradmin.list_display.add('is_superuser') takes much away from this feeling so "monkey patchy".

Attachments (0)

Change History (5)

comment:1 Changed 5 years ago by jacob

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Design decision needed

comment:2 Changed 3 years ago by lukeplant

  • Severity set to Normal
  • Type set to New feature

comment:3 Changed 3 years ago by julien

  • Easy pickings unset
  • Triage Stage changed from Design decision needed to Accepted
  • UI/UX unset

Accepting that there should be a cleaner API for interacting with the registry. However the third point ("provide methods to update common ModelAdmin options") doesn't seem so useful.

comment:4 Changed 3 months ago by anonymous

  • Easy pickings set
  • Has patch set
  • Needs documentation set
  • Needs tests set
  • Owner changed from nobody to anonymous
  • Status changed from new to assigned

useradmin = admin.site._registry.get(User, None)
if useradmin:

useradmin.list_display = useradmin.list_display + ('is_superuser',)

else:

class MyUserAdmin(AuthUserAdmin):

list_display = ('username', 'email', 'first_name', 'last_name', 'is_staff', 'is_superuser')

admin.site.register(User, MyUserAdmin)

comment:5 Changed 3 months ago by timo

  • Easy pickings unset
  • Has patch unset
  • Needs documentation unset
  • Needs tests unset
  • Version changed from 1.0 to master

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as assigned
Next status will be 'assigned'
The ticket will be disowned. Next status will be 'new'
as The resolution will be set. Next status will be 'closed'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.