1

Here is my code for a school project http://dpaste.com/434311/

The code works fine, on studentadmin list page, I get filter for classes which is good but as you can see my project is multi-tenant so in filter area I want to show only the classes for the school the current user is logged in (tracked thru sessions) but right now I can see list of all classes from all schools

so I want to replace this line

list_filter   = ['xclass']  

with something like

list_filter   = Class.objects.filter(school=request.session['school_id'])

how can I do it ?

Simple Dimple
  • 167
  • 1
  • 5
  • 1
    after hitting lots of road block I figured out that I used the wrong track...to master django one should 1) first learn python 2) then learn django 3) then make manual form using your own html 4) then learn unbounded forms 5) then bounded forms 6) then multiple forms 7) and then get to django-admin django auto admin is great tool but if you get excited and directly jump on it, you won't be able to customize it and u will get stuck like me really. now that i followed the above mentioned track, I feel lot better. – Simple Dimple Mar 28 '12 at 09:17
  • And I add that many choose Django for its 'admin' feature... and then realize they can't use it! – Don Apr 30 '14 at 05:18
  • The link does not work. Please post only relevant code. – styrofoam fly Feb 14 '18 at 14:46

2 Answers2

2

As of version 1.4 released March 23, 2012 you can use the official django.contrib.admin.SimpleListFilter

Here is an example of filter code used to that list active company only:

class ActiveCompaniesFilter(SimpleListFilter):
    # Human-readable title which will be displayed in the
    # right admin sidebar just above the filter options.
    title = _('active companies')

    # Parameter for the filter that will be used in the URL query.
    parameter_name = 'project__company'

    def lookups(self, request, model_admin):
        """
        Returns a list of tuples. The first element in each
        tuple is the coded value for the option that will
        appear in the URL query. The second element is the
        human-readable name for the option that will appear
        in the right sidebar.
        """
        lookup_list = Company.objects.active().values_list('id', 'name').distinct()
        # 'objects.active' is a custom Company manager and is 
        # equivalent to filter 'objects.filter(status=100)'  
        return lookup_list

    def queryset(self, request, queryset):
        """
        Returns the filtered queryset based on the value
        provided in the query string and retrievable via
        `self.value()`.
        """
        # Compare the requested value (either '80s' or 'other')
        # to decide how to filter the queryset.
        if self.value():
            return queryset.filter(project__company=self.value())
dan-klasson
  • 13,734
  • 14
  • 63
  • 101
Daniel Sokolowski
  • 11,982
  • 4
  • 69
  • 55
1

I've run into this issue many times. Unfortunately, you are going to need to write a custom, undocumented FilterSpec.

Custom Filter in Django Admin on Django 1.3 or below

It's being worked on so should be here soon...
http://code.djangoproject.com/ticket/5833


An alternative is to modify the base queryset for the list page with only those from your school id. http://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.queryset

def queryset(self, request):
    qs = super(MyModelAdmin, self).queryset(request)
    return qs.filter(xclass__school__id=request.session['school_id'])
Community
  • 1
  • 1
Yuji 'Tomita' Tomita
  • 115,817
  • 29
  • 282
  • 245
  • Thanks @Yuji, I'll look into custom filters, the link you provided. BTW the alternate that you provided for queryset does not makes any difference since I am already doing this on line 59, see my code qs = self.model._default_manager.filter(school=school_id) – Simple Dimple Feb 20 '11 at 09:02
  • Btw, [Status changed from assigned to closed, Resolution set to fixed](http://code.djangoproject.com/ticket/5833#comment:126). – Paolo May 03 '11 at 20:12