【问题标题】:Feeding a current filter selection to another custom SimpleListFilter in Django将当前过滤器选择提供给 Django 中的另一个自定义 SimpleListFilter
【发布时间】:2012-03-31 05:01:58
【问题描述】:

我正在尝试更改一个过滤器的提示以响应在另一个过滤器中所做的当前选择。对于如何获取传递给 AttributeFilter 的 AttributeCategoryFilter 的当前选定值,我非常迷茫。我正在使用 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)   

【问题讨论】:

  • 一种选择是从请求中获取。

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


【解决方案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 的建议。

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

【讨论】:

    【解决方案2】:

    这对我有用...“TypeListFilter”仅在使用“Category”过滤器后可见,然后显示所有属于“subTypeOf”所选类别的条目。 “特殊情况” hack 进一步确保过滤器在用户选择另一个类别时消失。 “_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())
    

    【讨论】:

      猜你喜欢
      • 2020-12-15
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 2020-01-11
      • 1970-01-01
      • 2017-08-17
      • 2016-07-01
      • 1970-01-01
      相关资源
      最近更新 更多