How to access filtered request in django admin.SimpleListFilter

Let's say we have two objects:

class Author(models.Model): name = models.CharField(length=50) class Book(models.Model): author = models.ForeignKey(Author) is_bestseller = models.BooleanField() 

In BookAdmin, if we specify

 list_filter = ('author', 'is_bestseller') 

the choice provided to you for the "author" will always be for all authors in the database, regardless of whether he wrote a bestseller or not.

I want my filters to be limited to the current selection. I tried to do this in a general way using admin.SimpleListFilter, however I am stuck as:

 model_admin.get_queryset() 

returns an unfiltered query (i.e. all objects, and not just those that are currently filtered by the user).

How to get a filtered set of requests in BookAdmin?

EDIT: To better illustrate the problem, here is my code:

 class ForeignFieldFilter(admin.SimpleListFilter): field = None def lookups(self, request, model_admin): queryset = model_admin.get_queryset(request).select_related(self.field) # ^^^ !!! Returns UNFILTERED queryset - it not affected by other filters field_ids = queryset.values_list(self.field, flat=True) for field_value in self.model..objects.filter(id__in=field_ids): yield (field_value.pk, str(field_value)) def queryset(self, request, queryset): value = self.value() # Check that any value was passed, if not, return unmodified queryset if not value: return queryset return queryset.filter({'{0}__pk'.format(self.field): value}) def foreign_field_filter_factory(field, model, title=None): title = title or (field[:1].upper() + field[1:]) return type( "ForeignFieldFilter_{0}".format(field), (ForeignFieldFilter,), { 'field': field, 'title': title, 'parameter_name': field, 'model': model }) 
+7
django django-admin
source share
1 answer

For BookAdmin

 class AuthorBestSeller(admin.SimpleListFilter): title = 'Best selling authors' parameter_name = 'bestseller' def queryset(self, request, queryset): if self.value(): return querset.filter(author_id=self.value()) else: return queryset def lookups(self, request, model_admin): qs = model_admin.get_queryset(request) query_attrs = dict([(param, val) for param, val in request.GET.iteritems()]) qs = qs.filter(**query_attrs) for book in qs.filter(is_bestseller=1): # or might be able to use yeild here ret.append((book.author_id, book.author)) return ret 

edit: humm ... this will not work either. he will just give you a list of authors with the best sellers.

then add to BookAdmin

 list_filter = (AuthorBestSeller, ) 
+2
source share

All Articles