Передача текущего выбранного фильтра другому пользовательскому SimpleListFilter в Django - PullRequest
3 голосов
/ 14 марта 2012

Я пытаюсь запросить изменение одного фильтра в ответ на текущий выбор, сделанный в другом фильтре. Я довольно растерялся относительно того, как получить текущее выбранное значение AttributeCategoryFilter, переданное в AttributeFilter. Я использую Django 1.4-dev. Попытка выяснить, должен ли я использовать RelatedFieldListFilter для этой цели. Похоже, что эти функции настолько молоды, что пока не имеют (m) примеров, плавающих в дикой природе.

    class AttributeCategoryFilter(SimpleListFilter):
        title = _('Attribute Category')
        parameter_name = 'attribute_category'
        def lookups(self, request, model_admin):
            attributes = Attribute.objects.filter(parent_attribute=None)
            prompts = []
            for attribute in attributes:
                prompts.append((attribute.title, _(str(attribute.title))))
            return prompts
        def queryset(self, request, queryset):
            if self.value():
                return queryset.filter(attribute__category=self.value())
            else:
                return queryset


    class AttributeFilter(SimpleListFilter):
        title = _('Attribute Title')
        parameter_name = 'attribute_title'
        def lookups(self, request, model_admin):
            desired_category =  # Needs to be a reference to the selected value in the AttributeCategoryFilter above
            attributes = Attribute.objects.filter(category=desired_category).exclude(parent_attribute=None)
            prompts = []
            for attribute in attributes:
                prompts.append((attribute.title, _(str(attribute.title))))
            return prompts
        def queryset(self, request, queryset):
            if self.value():
                return queryset.filter(attribute__title=self.value())
            else:
                return queryset


    class ValueAdmin(admin.ModelAdmin):
        list_display = ('package', 'attribute', 'presence', 'text', 'modified', 'created')
        list_filter = ('package', AttributeCategoryFilter, AttributeFilter, 'presence', 
            'attribute__admin_approved', 'attribute__dtype', 'modified')
        search_fields = ('package', 'attribute', 'text')
        list_display_links = ('package', )
        list_editable = ('presence', 'text')
        list_per_page = 20000
    admin.site.register(Value, ValueAdmin)   

Ответы [ 2 ]

2 голосов
/ 19 сентября 2013

Вот что сработало для меня ... «TypeListFilter» отображается только после использования фильтра «Категория», а затем отображает все записи, которые являются «subTypeOf» выбранной категории. Хак «особый случай» далее гарантирует, что фильтр исчезнет, ​​когда пользователь выберет другую категорию. Параметр "_class" добавляет дополнительную гибкость. Я использую один и тот же фильтр с разными, но связанными классами типов, и мне просто нужно переопределить этот параметр. Просто замените его классом admin.Model, который вы хотите отфильтровать.

class TypeListFilter( admin.SimpleListFilter):
    """
    Provide filter for DnaComponentType (the actual "second level" type).

    This filter has one cosmetic problem, which is that it's setting is not
    automatically deleted if the category filter is changed. I tried but the
    request and queryset are all immutable. Instead, the queryset method is 
    checking for any missmatch between category and filter name and filtering
    is ignored if the category name doesn't match the current subType name.
    """
    title = 'Type'
    parameter_name = 'type'

    _class = None

    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.
        """
        if not u'category' in request.GET:
            return ()

        category_name = request.GET[u'category']
        types = self._class.objects.filter(subTypeOf__name=category_name)
        return ( (t.name, t.name) for t in types )

    def queryset(self, request, queryset):
        """
        Returns the filtered queryset based on the value
        provided in the query string and retrievable via
        `self.value()`.
        """
        if not u'category' in request.GET:
            return queryset

        category = request.GET[u'category']
        subtypes = self._class.objects.filter(subTypeOf__name=category)

        r = queryset.filter(componentType__subTypeOf__name=category)

        if not self.value():
            return r

        ## special case: missmatch between subtype and category
        ## which happens after switching the category
        if len(subtypes.filter(name=self.value())) == 0:
            return r

        return r.filter(componentType__name=self.value())
1 голос
/ 29 ноября 2012

Нашел ваш вопрос, когда я искал что-то еще.

Вот что я сделал, чтобы показать игроков, у которых есть персонажи в выбранной игре:

def lookups(self, request, model_admin):
    game_id = request.GET.get('game', None)
    players = Player.objects.all()
    if game_id:
        players = players.filter(character__game_id=game_id)
    return [(p.id, p.__unicode__()) for p in players]

Похоже, это то, что предложил и Дан-Классон.

Подсказка: по соображениям безопасности ввод идентификаторов в параметры запроса обычно запрещается.

...