'Django custom admin filter: get filtered queryset before the current filter itself is applied

I have a classic admin.SimpleListFilter. I would want to get the current filtered/displayed queryset, but before my own filter is applied, so I can show the result count for each of my filter lookups. The current code below always shows total counts of each lookup, not respecting eventual other selected filters.

class ByAssignementStatusFilter(admin.SimpleListFilter):
    title = _('Assignement Status')
    parameter_name = 'status__exact'

    def lookups(self, request, model_admin):
        choices = []
        qs = model_admin.get_queryset(request)
        # qs.count() is always the unfiltered amount
        for key, label in Assignement.STATUS_CHOICES:
            count = qs.filter(assignement__status=key).count()
            label = f"{label} ({count})"
            choices.append((key, label))
        return choices

    def queryset(self, request, queryset):
        if self.value() is not None:
            return queryset.filter(assignement__status=self.filter_value)
        else:
            return queryset

The goal is to have a filter that displays like this:

  • All
  • New (4)
  • In Progress (99)
  • Done (0)
  • Etc (69)

I've done some more research, it looks like the queryset is filtered in the actual ChangeListView. Currently I'm doing a hacked together filtering on my own (preparing the qs with other selected filters), which works, but feels awkward.

Others on SO:
How to get the filtered queryset in admin, through Changelist view
How to access the filtered queryset in SimpleListFilter - no real solution there



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source