Skip to content

Commit

Permalink
Custom FilterSpec to limit groups to that of the user in list_filter
Browse files Browse the repository at this point in the history
Sub-classed Django's RelatedFilterSpec and filtered the available groups
based on the current user's groups. This now overrides the standard
FilterSpec for the groups field.
  • Loading branch information
ghickman committed Jun 4, 2011
1 parent 290aee3 commit ab247ec
Showing 1 changed file with 44 additions and 0 deletions.
44 changes: 44 additions & 0 deletions password/admin.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,54 @@
from django.contrib import admin
from django.contrib.admin.filterspecs import FilterSpec, RelatedFilterSpec
from django.contrib.auth.models import Group
from django.db.models import Q
from django.utils.encoding import smart_unicode
from django.utils.translation import ugettext_lazy as _

from forms import PasswordForm
from models import Password

class UserGroupsFilterSpec(RelatedFilterSpec):
"""
Custom filter spec taken from:
http://stackoverflow.com/questions/2251851/django-admin-list-filter-attribute-from-userprofile
"""
def __init__(self, f, request, params, model, model_admin, field_path=None):
super(UserGroupsFilterSpec, self).__init__(f, request, params, model, model_admin, field_path=field_path)

# The lookup string that will be added to the queryset by this filter
self.lookup_kwarg = 'group__id__exact'
# get the current filter value from GET (we will use it to know which filter item is selected)
self.lookup_val = request.GET.get(self.lookup_kwarg)

# A list of the user's groups, ordered alphabetically, containing only the id and name.
self.lookup_choices = Group.objects.filter(user=request.user).order_by('name').values_list('id', 'name')

def choices(self, cl):
"""
Generator that returns all the possible items in the filter including 'All' and 'Private' items.
"""
yield { 'selected': self.lookup_val is None,
'query_string': cl.get_query_string({}, [self.lookup_kwarg]),
'display': _('All') }
for pk_val, val in self.lookup_choices:
yield { 'selected' : self.lookup_val == smart_unicode(pk_val),
'query_string': cl.get_query_string({self.lookup_kwarg: pk_val}),
'display': val }

def title(self):
return _('Group')

# Here, we insert the new FilterSpec at the first position, to be sure it gets picked up before any other.
FilterSpec.filter_specs.insert(0,
(lambda f: getattr(f, 'usergroup_filter', False), UserGroupsFilterSpec)
)

# Add the usergroup filter by setting the usergroup_filter attribute on an existing field.
# This will activate the user groups filter if we add it to the admin's `list_filter`,
# however we won't be able to use it in it's own filter anymore.
Password._meta.get_field('group').usergroup_filter = True

class PasswordAdmin(admin.ModelAdmin):
form = PasswordForm
list_display = ('__unicode__', 'domain', 'is_public')
Expand Down

0 comments on commit ab247ec

Please sign in to comment.