Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering list_filter in Django admin based on field in foreign key

I would like to filter one of my list_filters by a field in the table that the foreign key points to.

My models:

class Organisation(models.Model):
    name = models.CharField()
    COMPANY = 'COMPANY'
    CHARITY = 'CHARITY'
    ORG_CHOICES = (
        (COMPANY, 'COMPANY'),
        (CHARITY, 'CHARITY'),
        )
    type = models.CharField(choices = ORG_CHOICES)

class Issue(models.Model):
   name = models.CharField
   charity = models.ForeignKey(Organisation)

I would like to put in IssueAdmin:

list_filter = (charity)

And for that to supply a list of charities. Currently it just lists everything in the organisation model, both the charities and the companies. For example I get this list in the filter at the moment:

oxfam
yamaha
greenpeace
microsoft

When I want a filter that lists:

oxfam
greenpeace

I could fix this by splitting the organisation table into two tables (charity and company) but that feels wrong.

It seems like SimpleListFilter should work, but I've not had any luck so far. Basically I would like something the uses the following filter and returns a list of charities for the filter:

Organisation.objects.filter(type = 'CHARITY')

My (poor) attempt at a filter:

class CharityFilter(SimpleListFilter):
    title = _('Charity')
    parameter = _('charity__type')
    def lookups(self, request, model_admin):
        return Organisation.objects.filter(type = 'CHARITY')

    def queryset(self, request, queryset):
        if not self.value() is not None:
            return queryset.filter(type = 'CHARITY')
        else:
            return queryset

Can any one help me?

like image 279
Matthew Moore Avatar asked Nov 22 '13 16:11

Matthew Moore


1 Answers

Why don't you just filter on the type, ie:

class OrganisationAdmin(admin.ModelAdmin):
    list_filter = ("type", )
    # etc

It would allow you to have either all organisations, companies only or charities only.

Else if you realy want to treat "Charities" and "Companies" as distinct entities with distinct admins but still keep them in the same table, you can use proxy models, but I don't see the point here.

Edit : to filter issues based on organization type it works just the same as with querying on relayed models (not a surprise since it's exactly what happens)

class IssueAdmin(admin.ModelAdmin):
    list_filter =("charity__type", )
like image 180
bruno desthuilliers Avatar answered Sep 28 '22 14:09

bruno desthuilliers