Reputation: 8039
The Django Admin's User management gives us easy access to setting a User's group allegiances via the list for picking the Groups. This is the ManyToMany relationship default widget for assignment. And for the most part that's nice for User creation from the get go.
However, say I have a huge number of users and groups, I'd like the chance to view and manage group membership by clicking on the Group in the admin and then seeing all the members in a similar picker (or via the horizontal widget).
Is there a built-in Django method/trick to show ManyToMany relations in "reverse?"
Setting group assignment is fine from the User adminform on User creation. But this can be a big pain to find and manage once users and groups are well established.
I guess the workaround is to make my own view to show group members, I just wanted to see if there was some trick I could do with inlines or something in the admin.
Upvotes: 3
Views: 6103
Reputation: 8315
Try to use this snippet. It's customisation example of contrib.auth app admin part.
# utils/admin_auth.py
# -*- coding: utf-8 -*-
from django.utils.safestring import mark_safe
from django.contrib.auth.models import User, Group
from django.contrib.auth.admin import UserAdmin, GroupAdmin
from django.contrib import admin
def roles(self):
#short_name = unicode # function to get group name
short_name = lambda x:unicode(x)[:1].upper() # first letter of a group
p = sorted([u"<a title='%s'>%s</a>" % (x, short_name(x)) for x in self.groups.all()])
if self.user_permissions.count(): p += ['+']
value = ', '.join(p)
return mark_safe("<nobr>%s</nobr>" % value)
roles.allow_tags = True
roles.short_description = u'Groups'
def last(self):
fmt = "%b %d, %H:%M"
#fmt = "%Y %b %d, %H:%M:%S"
value = self.last_login.strftime(fmt)
return mark_safe("<nobr>%s</nobr>" % value)
last.allow_tags = True
last.admin_order_field = 'last_login'
def adm(self):
return self.is_superuser
adm.boolean = True
adm.admin_order_field = 'is_superuser'
def staff(self):
return self.is_staff
staff.boolean = True
staff.admin_order_field = 'is_staff'
from django.core.urlresolvers import reverse
def persons(self):
return ', '.join(['<a href="%s">%s</a>' % (reverse('admin:auth_user_change', args=(x.id,)), x.username) for x in self.user_set.all().order_by('username')])
persons.allow_tags = True
class UserAdmin(UserAdmin):
list_display = ['username', 'email', 'first_name', 'last_name', 'is_active', staff, adm, roles, last]
list_filter = ['groups', 'is_staff', 'is_superuser', 'is_active']
class GroupAdmin(GroupAdmin):
list_display = ['name', persons]
list_display_links = ['name']
admin.site.unregister(User)
admin.site.unregister(Group)
admin.site.register(User, UserAdmin)
admin.site.register(Group, GroupAdmin)
Upvotes: 1