Администратор django фильтрует каскадирование - PullRequest
3 голосов
/ 04 сентября 2011

У меня есть вопрос - можно ли настроить интерфейс администратора Django таким образом, чтобы он представлял только те параметры фильтра, которые присутствуют в подмножестве данных, соответствующих выбранным в данный момент фильтрам?

Скажите, у меня естьдБ из трех объектов:

a.Foo = "One"
a.Bar = "Drink"

b.Foo = "One"
b.Bar = "Shot"

c.Foo = "Two"
c.Bar = "Shot"

и интерфейс администратора django с фильтрами 'Foo' и 'Bar'.Мне нужно следующее поведение:

  • Если фильтры не выбраны, «Foo» перечисляет «Один», «Два»;«Бар» отображает «Напиток», «Выстрел»
  • Если для фильтра «Foo» установлено значение «Один», «Бар» отображает как «Напиток», так и «Выстрел»
  • Если «Foo»для фильтра установлено значение «Два», «Бар» содержит только «Выстрел»
  • Если для фильтра «Бар» установлено значение «Выстрел», в «Foo» перечислены «Один» и «Два»
  • Если для фильтра «Бар» установлено значение «Напиток», в «Foo» отображается только «Один»

Приветствия!


Чтобы быть более конкретными - после прочтениянекоторые документы:

from django.contrib.admin import SimpleListFilter

class SomeFilter(SimpleListFilter):
  title = "Foo"
  parameter_name="Some"
  def lookups(self, request, model_admin):
    qs = model_admin.queryset(request)
    print qs.query
    return (('Foo', 'Bar'))
  def queryset(self, request, queryset):
    if (self.value()):
      return queryset.filter(Some=self.value())
    else:
      return queryset

Однако он получает «набор запросов», как это было бы без других фильтров.Как я могу пропустить его через другие фильтры?


Теоретически я мог бы проанализировать запрос и отфильтровать вручную - но, безусловно, должен быть способ передать все фильтры.

Ответы [ 2 ]

2 голосов
/ 07 сентября 2011

Этот вид динамической фильтрации действительно выглядит как огранка. Хотя вы можете достичь этого результата с помощью стандартного набора запросов, это, вероятно, не будет оптимальным. У вас может быть больше шансов с помощью специального инструмента, такого как Solr.

В стоге сена также есть страница документации по огранке .

1 голос
/ 08 ноября 2013

в случае, если кому-то нужно облегченное решение, оно выполняет фильтр Страны, который скрыт, когда в фильтре не выбран Континент, и предлагает только те страны, которые существуют на выбранном Континенте:

from django.utils.translation import ugettext_lazy as _
class ContinentCountryListFilter(admin.SimpleListFilter):
    # Human-readable title which will be displayed in the
    # right admin sidebar just above the filter options.
    title = _('country')

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

    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.
        """

        continent = request.GET.get('country__continent__iso_code__exact', '')

        if continent:
            countries = models.Country.objects.filter(continent__iso_code__exact=continent)
        else:
            countries = models.Country.objects.none()

        return countries.values_list('iso_code', 'name')

    def queryset(self, request, queryset):
        """
        Returns the filtered queryset based on the value
        provided in the query string and retrievable via
        `self.value()`.
        """
        continent = request.GET.get('country__continent__iso_code__exact', '')

        # only apply filter if continent is set and country exists in continent
        if continent and models.Country.objects.filter(continent__iso_code__exact=continent, iso_code__exact=self.value()).count():
            return queryset.filter(country__iso_code__exact=self.value())

        return queryset

, а затем применить с:

list_filter = ('country__continent', ContinentCountryListFilter, )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...