将当前过滤器选择提供给Django中的另一个自定义SimpleListFilter

时间:2012-03-14 17:29:58

标签: python django django-admin django-admin-filters

我正在尝试提示一个过滤器更改,以响应在另一个过滤器中进行的当前选择。关于如何将当前选择的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 个答案:

答案 0 :(得分:2)

以下是对我有用的...“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 :(得分:1)

找到你的问题,因为我正在寻找别的东西。

这就是我所做的只展示在所选游戏中有角色的玩家:

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]

看起来这也是dan-klasson所建议的。

提示:出于安全原因,将ID放入查询参数通常被视为禁忌。