proposal: decouple admin index page from INSTALLED_APPS

126 views
Skip to first unread message

patrickk

unread,
Sep 4, 2009, 5:00:37 AM9/4/09
to Django developers
hi everyone,

I just wanted to outline a basic idea in order to improve (at least
from my point of view) the index-page of the admin-interface. I don´t
have any code to share (so far), so I´m basically explaining my idea -
if people agree that this is useful, I´m trying to submit a patch.

here´s the idea: currently, the admin index page is strictly coupled
to the settings-file of my project (the INSTALLED_APPS). to me, that
doesn´t seem the best way. a while ago, the admin-definition for apps
has been coupled to the model-definition ... now there is a file
called admin.py, which is much better IMHO. so why don´t we have a
file admin.py for every project? within that file, one could define
which apps (from INSTALLED_APPS) should be visible at the admin index
page. moreover, the possibility to reorder/rearrange the way these
apps are shown would be great.
e.g, when I´m using djangos auth-app and I´m extending the user-model
with a user-profile, I´m having "auth" (with users and groups) and
"user" (with user profile) on my admin index page. orderd by names,
auth is very much on the top of my page while user is at the bottom.
for an editor, this is probably hard to understand (because the editor
doesn´t know anything about apps). for an editor, it´d more
comfortable having a headline "user management" with the apps "users",
"groups" and "user profiles". this re-arrangement could be defined in
admin.py.

I hope this is somehow understandable. it´s a bit hard to explain in a
foreign language ... it´d be great to hear other opinions.

thanks,
patrick

Joshua Russo

unread,
Sep 4, 2009, 5:32:49 AM9/4/09
to django-d...@googlegroups.com
I think this sounds like a good idea. This was one of the first things I wanted to do when getting started with the admin app. 

Luke Plant

unread,
Sep 4, 2009, 7:02:28 AM9/4/09
to django-d...@googlegroups.com
On Friday 04 September 2009 10:00:37 patrickk wrote:

> e.g, when I´m using djangos auth-app and I´m extending the user-model
> with a user-profile, I´m having "auth" (with users and groups) and
> "user" (with user profile) on my admin index page. orderd by names,
> auth is very much on the top of my page while user is at the bottom.
> for an editor, this is probably hard to understand (because the editor
> doesn´t know anything about apps). for an editor, it´d more
> comfortable having a headline "user management" with the apps "users",
> "groups" and "user profiles". this re-arrangement could be defined in
> admin.py.

You can also define the arrangement by overriding the admin template for the
index and hard coding in your own order. It's not ideal, but it's perhaps
preferable to adding another place for configuring the admin. If you want
this kind of flexibility for the index page, you might also want to add extra
notes etc onto the page, which makes customising the template a reasonably
good way to do it.

Having an admin.py for every project is a bit vague, because 'projects' don't
really exist as far as Django is concerned, only 'apps'.

Luke

--
I teleported home one night
With Ron and Sid and Meg,
Ron stole Meggie's heart away
And I got Sidney's leg
(THHGTTG)

Luke Plant || http://lukeplant.me.uk/

patrickk

unread,
Sep 4, 2009, 7:19:44 AM9/4/09
to Django developers
thanks for the reply.

On 4 Sep., 13:02, Luke Plant <L.Plant...@cantab.net> wrote:
> On Friday 04 September 2009 10:00:37 patrickk wrote:
>
> > e.g, when I´m using djangos auth-app and I´m extending the user-model
> > with a user-profile, I´m having "auth" (with users and groups) and
> > "user" (with user profile) on my admin index page. orderd by names,
> > auth is very much on the top of my page while user is at the bottom.
> > for an editor, this is probably hard to understand (because the editor
> > doesn´t know anything about apps). for an editor, it´d more
> > comfortable having a headline "user management" with the apps "users",
> > "groups" and "user profiles". this re-arrangement could be defined in
> > admin.py.
>
> You can also define the arrangement by overriding the admin template for the
> index and hard coding in your own order.  It's not ideal, but it's perhaps
> preferable to adding another place for configuring the admin.  If you want
> this kind of flexibility for the index page, you might also want to add extra
> notes etc onto the page, which makes customising the template a reasonably
> good way to do it.

yep. I know that that´s possible, but it leads to another problem: the
app-index is missing. because (referring to my initial example) "user
management" is not an app and therefore it´s not clickable. of course
I could make "user management" a link and define custom templates for
every section of my index-page.
with my proposal, "user management" would be a section containing
different apps. and either "user management" as well as every app
within this section should be clickable.

moreover, hardcoding the index-template doesn´t seem very clean from
my point of view.

> Having an admin.py for every project is a bit vague, because 'projects' don't
> really exist as far as Django is concerned, only 'apps'.

I´m not exactly sure, but I don´t think that´s a huge problem, right?
maybe I used the wrong terms, but it can´t make a big difference
whether the settings-file is used for the admin or another file is
used. however, I could be mistaken.

-----

a bit of background information: while using djangos admin-interface
for about 3 years now, customers always complain about not finding
stuff on the admin index page. for a bigger website with about 50 apps
you get a really long list. and I just thought it would be easier if
apps are combined within sections (again, don´t nail me down on the
terms ...).

thanks,
patrick

Russell Keith-Magee

unread,
Sep 4, 2009, 8:23:05 AM9/4/09
to django-d...@googlegroups.com

It depends :-)

It is a slight problem in that we currently require no project-level
code. Everything besides settings and the top-level URLconf is stored
in an application. The admin app is "just another app" - there's
nothing specifically "project level" about it. All the current admin
registrations, for instance, occur with app-level admin.py files, and
you can get very creative about those files.

If you can come up with a compelling reason why a top-level admin.py
file is required, we're happy to listen to it.

> a bit of background information: while using djangos admin-interface
> for about 3 years now, customers always complain about not finding
> stuff on the admin index page. for a bigger website with about 50 apps
> you get a really long list. and I just thought it would be easier if
> apps are combined within sections (again, don´t nail me down on the
> terms ...).

On the face of it, having more ability to customize is always going to
be good. The problem is, we need specificity here. So far, all we know
about your proposal is that it involves a project-level admin.py. What
will be in that file? How will it integrate with the AdminSite? With
ModelAdmins? A project-level admin.py file isn't inherently wrong
(although I must say I do share Luke's aversion to such a suggestion).
However, it really depends on what you intend to put into that file.

If you give some concrete suggestions, we can give some concrete
feedback. Making suggestions with an eye to potential implementation
difficulties (i.e., can we actually push admin to do this?) will gain
bonus points.

Yours,
Russ Magee %-)

patrickk

unread,
Sep 4, 2009, 8:37:50 AM9/4/09
to Django developers
fair enough.

I don´t have a problem with just seperating INSTALLED_APPS from
ADMIN_APPS within the settings-file. I just thought another admin-file
is nicer (but that´s not the key argument of my proposal).

INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.admin',
'movies',
'stars',
'cinemas',
'games',
'promos',
'polls',
'festivals',
'trailer',
'user',
'registration',
'voting',
'django.contrib.comments',
'custom_tags',
'mediadata',
'stats',
'newsletter',
)

ADMIN_APPS = (
(_('User Management'), {
'apps': ('django.contrib.auth', 'registration', 'user',)
}),
(_('Main Content'), {
'apps': ('movies', 'stars', 'cinemas', 'festivals',
'trailer',)
}),
(_('Games'), {
'apps': ('games', 'promos', 'polls',)
}),
(_('Voting/Comments'), {
'classes': ('collapsed',),
'apps': ('voting', 'comments',)
}),
(_('Extras'), {
'classes': ('collapsed',),
'apps': ('mediadata', 'stats', 'newsletter',)
}),
)

if you need more details, please let me know.

thanks,
patrick


On 4 Sep., 14:23, Russell Keith-Magee <freakboy3...@gmail.com> wrote:

Russell Keith-Magee

unread,
Sep 4, 2009, 9:30:06 AM9/4/09
to django-d...@googlegroups.com

Well, for starters, some clarification would help.

Are we talking about an alternate organization for models in the admin
so you're not bound to app-based categories, or are we talking about
some higher level organization?

Your example puts django.contrib.auth into the 'User Management'
collection - is that indicating that all the apps in auth should be
shown in "User Management", or that there is a "User Management"
super-group that contains the auth group that contains the auth
applications?

Your language is particularly confusing in this regard - it isn't
clear when you say 'apps' if you actually mean 'models'.

Secondly, why would this be included in settings.py (or a top level
admin.py for that matter)? Admin registrations are currently
distributed across the apps in the entire project - why is there a
need to pull this into a single location?

Couldn't this be achieved by registering a model with a particular
"app collection" (with the default being the collection formed by the
app containing the model)?

i.e., to create a "User Management" group, and put "user" in it:

class UserManagement(AdminGroup):
label = "UserManagement"

class UserAdmin(ModelAdmin):
...
class UserAdmin(ModelAdmin):
...

admin.site.register(User, UserAdmin, group=UserManagement)

Yours,
Russ Magee %-)

patrickk

unread,
Sep 4, 2009, 9:52:22 AM9/4/09
to Django developers


On 4 Sep., 15:30, Russell Keith-Magee <freakboy3...@gmail.com> wrote:
I´d personally replace the group "Auth" with the group "User
Management".
the reason is that "Auth" is an application (something which is - IMHO
- irrelevant for an editor to know/see).

that said, I can also think of putting the group "Auth" within the
super-group "User Management". however, I don´t think that´s necessary
and makes the admin index page more complicated.

> Your language is particularly confusing in this regard - it isn't
> clear when you say 'apps' if you actually mean 'models'.

sorry. trying to concentrate on the right terms a bit more.

> Secondly, why would this be included in settings.py (or a top level
> admin.py for that matter)? Admin registrations are currently
> distributed across the apps in the entire project - why is there a
> need to pull this into a single location?

the only reason I can think of is to change the order of collections
(see below).

> Couldn't this be achieved by registering a model with a particular
> "app collection" (with the default being the collection formed by the
> app containing the model)?

from my point of view this leads to the problem of sorting the "app
collections". how would you achieve that? e.g., if I want "User
Management" to be shown as the first collection (independent of the
collections name)?

moreover, it´d be nice (at least from a theoretical point of view) to
assign an app (or model) to more than one collection.

regards,
patrick

patrickk

unread,
Sep 4, 2009, 11:03:15 AM9/4/09
to Django developers
alright, I´ve been trying to implement the most basic functionality
and here´s what I came up with. Please note that this is just a draft
in order to explain what I´ve been talking about. It works ok, but it
probably can be done better.

thanks,
patrick

– SETTINGS.PY

ADMIN_COLLECTIONS = [
{
'name': 'Main Content',
'classes': 'highlight',
'show_apps': True,
'apps': ['movies', 'stars', 'trailer']
},
{
'name': 'User Management',
'show_apps': False,
'apps': ['auth', 'grappelli']
}
]

– SITES.PY

for collection in ADMIN_COLLECTIONS:
app_list = []
for app in collection['apps']:
app_list.append(app_dict[app])
collection['app_list'] = app_list

context = {
'title': _('Site administration'),
'app_list': app_list,
'collection_list': ADMIN_COLLECTIONS,
'root_path': self.root_path,
}

– INDEX.HTML:

{% for collection in collection_list %}
<div class="module">
<table summary="{% blocktrans with app.name as name %}Models
available in the {{ name }} application.{% endblocktrans %}">
<caption><a href="{{ app.app_url }}" class="section">{%
blocktrans with collection.name as name %}{{ name }}{% endblocktrans %}
</a></caption>
{% for app in collection.app_list %}
{% if collection.show_apps %}
<tr>
<th>{{ app.name }}</th>
</tr>
{% endif %}
{% for model in app.models %}
<tr>
{% if model.perms.change %}
<th scope="row"><a href="{{ model.admin_url }}">
{{ model.name }}</a></th>
{% else %}
<th scope="row">{{ model.name }}</th>
{% endif %}

{% if model.perms.add %}
<td><a href="{{ model.admin_url }}add/"
class="addlink">{% trans 'Add' %}</a></td>
{% else %}
<td>&nbsp;</td>
{% endif %}

{% if model.perms.change %}
<td><a href="{{ model.admin_url }}"
class="changelink">{% trans 'Change' %}</a></td>
{% else %}
<td>&nbsp;</td>
{% endif %}
</tr>
{% endfor %}
{% endfor %}
</table>
</div>
{% endfor %}

andybak

unread,
Sep 4, 2009, 3:21:18 PM9/4/09
to Django developers
I've been hoping a discussion like this would start as soon as 1.1 was
out the door. It would tie in nicely with the Admin GSOC work as well.

I would like to chime in with some ideas for requirements and stay
away from the implementation discussion for now.

1. I think worrying about projects vs. apps is a red-herring. We are
talking about a way to configure an admin app. There might be several
of these on a 'site/project/whatever'

2. Some ability to regroup and choose better names is a biggie. It
pains me when I try and explain to my admins what 'auth' means...

3. A way to have custom entries in an category that don't relate to a
model and don't neccesarily have add and change links. This would
allow us to integrate projects like Django-filebrowser into the admin
nicely without the code copy and pasting that comes from the admin
template override mechanism.

5. Talking of the admin template override mechanism for those times we
are forced to use it can we have lots lots more blocks? Object-tools,
I'm looking at you!

6. (pony time) When everyone comes to their senses and accepts that
jQuery is going to be an essential ingredient in contrib.admin, then
jQuery.ui tabs add a whole heap of awesome to the admin index page :-P

cheers!

Andy

James Bennett

unread,
Sep 4, 2009, 3:32:54 PM9/4/09
to django-d...@googlegroups.com
On Fri, Sep 4, 2009 at 2:21 PM, andybak<and...@gmail.com> wrote:
> 1. I think worrying about projects vs. apps is a red-herring. We are
> talking about a way to configure an admin app. There might be several
> of these on a 'site/project/whatever'

Since this all seems to be specific to particular instances of
AdminSite, AdminSite would be the logical place to do it if it's going
to get code-level support. However...

> 2. Some ability to regroup and choose better names is a biggie. It
> pains me when I try and explain to my admins what 'auth' means...

Practically everything being requested here is purely presentational.
And Django has a component for doing presentational logic: the
template system. The admin templates are deliberately easy to override
with custom versions, and it feels like all of this is really just
asking for things that are more cleanly done in templates.

We (World Online) do this rather frequently, including shuffling
things around, re-labeling bits, showing extra links to custom things
we've added to particular applications. And we do it entirely in
templates; it's not particularly hard.


--
"Bureaucrat Conrad, you are technically correct -- the best kind of correct."

Russell Keith-Magee

unread,
Sep 5, 2009, 12:02:48 AM9/5/09
to django-d...@googlegroups.com
On Sat, Sep 5, 2009 at 3:32 AM, James Bennett<ubern...@gmail.com> wrote:
>
> On Fri, Sep 4, 2009 at 2:21 PM, andybak<and...@gmail.com> wrote:
>> 1. I think worrying about projects vs. apps is a red-herring. We are
>> talking about a way to configure an admin app. There might be several
>> of these on a 'site/project/whatever'
>
> Since this all seems to be specific to particular instances of
> AdminSite, AdminSite would be the logical place to do it if it's going
> to get code-level support. However...
>
>> 2. Some ability to regroup and choose better names is a biggie. It
>> pains me when I try and explain to my admins what 'auth' means...
>
> Practically everything being requested here is purely presentational.
> And Django has a component for doing presentational logic: the
> template system. The admin templates are deliberately easy to override
> with custom versions, and it feels like all of this is really just
> asking for things that are more cleanly done in templates.

This isn't completely true - at least, not if you want to affect the
URL structure as well. If you're just looking be able to use:

/admin/<app>/<model>

and replace that with:

/admin/<app group>/<model>

then you need some form of representation at the code level. This
can't be done purely with templates.

This distinction is really only important if you want the URL
structure to reflect of logical structure, rather than code structure
(which, broadly speaking, is a good thing to be doing from the "URL as
interface" argument). However, this use case could be handled at
present with a custom site that overrides get_urls to provide the
'group' landing page, etc.

I can see that providing a DSL-style way to set up these groups could
be handy for a small group of users, but I can't say it's a
particularly compelling use case for me personally.

I strongly suspect that this could (and therefore, should) be handled
as an external project in the initial phases - i.e., a
"django-extended-admin' project that provides the AdminSite and
ModelAdmin extensions that would make a DSL-for-groups approach
possible. Patrick, Joshua - if you're enthused about this idea, I
suggest you combine your efforts and try to make this external project
a reality. If this external project gains traction, then we can look
at merging it back to trunk.

Yours,
Russ Magee %-)

patrickk

unread,
Sep 5, 2009, 3:19:03 AM9/5/09
to Django developers



On 5 Sep., 06:02, Russell Keith-Magee <freakboy3...@gmail.com> wrote:
> On Sat, Sep 5, 2009 at 3:32 AM, James Bennett<ubernost...@gmail.com> wrote:
will do. I´m going to use grappelli (http://code.google.com/p/django-
grappelli/) for this. if anybody wants to join (joshua?, andy?),
please drop me an email.

thanks for all the feedback & suggestions.

regards,
patrick

>
> Yours,
> Russ Magee %-)

Russ Ryba

unread,
Sep 5, 2009, 2:22:15 PM9/5/09
to django-d...@googlegroups.com
I'm coming late to the coversation but wanted to add by thoughts on the admin index issue. I'm at a campground on a cell phone so bandwidth and typing is limited.

I'll try to be specific in my comments.

1. I think that this should be handled by individual app admin.py.  I like the idea of just modifying one line in installed_apps to turn an application on or off.

2. I think settings.py should only know about applications.  You should never specify model sorting or model anything in settings.py.

3. Admin.py per app should specify grouping and sorting per model. First by registering a modrladmin group, then later assigning modeladmins to that group.

I would extend the previous example as follows. 

class UserManagement(AdminGroup):
   label = "User Management"
   sort_order = 100
   merge_with_existing_group = True

class UserAdmin(ModelAdmin):
      Meta:
             sort_order = 50
class FooAdmin(ModelAdmin):
     Meta:
             sort_order = 60

admin.site.register(User, UserAdmin, group=UserManagement)
admin.site.register(Foo, FooAdmin, group=UserManagement)

Then in the index template app groups would be sorted by sort order values, then alphanumeric. 

- This would keep grouping defined in each app admin class.
- This would let you sort apps/groups by numerical values. 
- mergewexisting would let apps join together or not, being false by default so you could see when name collisions occur with app or group names.  It could also let complimentary apps extend each other by adding new models.  

Further thoughts. 

- SQL tables are currents based on appname_model, as are the URL mappings. Changing the index grouping is essentially the same as merging applications. 

I love the sound of it if we focus on the index.  However I foresee the next logical request would be to "fix" the SQL and URL mappings to match the index display. That would be practically impossible or very ugly. 

Name collisions suddenly have to be accounted for, SQL migrations to rename tables, as well as permission names.  

4. Thinking about how to implement the URL and SQL mappings leads me to suggest a new file App/meta.py.  This would contain application name override, Application sort order and model grouping would be defined here. 

The meta class would know about the applications models, and admin interfaces and define how to group then all together.


Accessible via something like 

   Appname.meta.property = value

Since it's define at the app level the SQL and URL processors should have access to it. 

This could also be a good place to define things I use a lot like custom permissions specific to the application per app or per app model. 

Maybe I'm getting ahead of myself with URL and SQL stuff?

Comments?

Russ Ryba 
 

patrickk

unread,
Sep 6, 2009, 5:38:11 AM9/6/09
to Django developers
my thoughts:
1. defining groups within admin.py of each app makes reordering groups
complicated.
2. to assign an app to a group, I have to register that app with a
group - if I want (for example) to assign django.contrib.auth to the
group "User Management", I have to change that app (which breaks
future svn-updates). this is true for almost every 3rd-party app (if I
´m using an svn-checkout).

instead of using a bottom-up structure (registering apps with groups),
why not using a top-down structure (defining groups and assigning
apps).
e.g., you could have a file admin.py within your project and this file
could define the groups:

class UserManagement(AdminGroup):
label = "User Management"
...
'apps': ('django.contrib.auth', 'user',)

regards,
patrick

patrickk

unread,
Sep 17, 2009, 6:55:52 AM9/17/09
to Django developers
I´ve opened a ticket with my patches (and a screenshot):
http://code.djangoproject.com/ticket/11895

I´ve given up on changing the app-index page since this seems to break
the overall coherence of the admin-interface. therefore, my patch doesn
´t change the breadcrumbs. it only gives you the ability to group (and
reorder) the apps shown on the index-page of every admin-site.

I´ve not included a patch for index.html ... basically, one has to
loop the group-list first and then the app-list (every app which is
not part of a group is displayed at the bottom of the index-page). if
one doesn´t define a group, all apps are listed as is.

the file admin.py show how the apps can be defined for an admin-site.

thanks,
patrick

patrickk

unread,
Sep 17, 2009, 10:58:31 AM9/17/09
to Django developers
just for the records ...

as russell commented on the ticket, this can all be done with
subclassing AdminSite.

so ... here´s how grouping and reordering app with the admin-interface
can be achieved:
http://code.google.com/p/django-grappelli/wiki/customizingindex

and here´s the code (subclassing AdminSite), just in case someone
wants to do something similar without grappelli:
http://code.google.com/p/django-grappelli/source/browse/branches/grappelli_2/sites.py

thanks for all the feedback/help,
patrick
Reply all
Reply to author
Forward
0 new messages