问题描述
我正在尝试使一个过滤器的提示响应于在另一个过滤器中进行的当前选择。关于如何获取传入AttributeFilter的AttributeCategoryFilter的当前选定值,我很失落。我正在使用Django 1.4-dev。试图弄清楚我是否应该使用RelatedFieldListFilter来达到这个目的。看起来这些功能非常年轻,没有(m)在野外的任何例子浮动。
I am trying to make the prompts of one filter change in response to the current selection made in another filter. I am pretty lost as to how to get the currently selected value of the AttributeCategoryFilter passed into the AttributeFilter. I am using Django 1.4-dev. Trying to figure out if I should be using RelatedFieldListFilter for this purpose. It looks like these features are so young as to not have (m)any examples floating around in the wild yet.
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)
推荐答案
这是对我有用的...TypeListFilter仅在使用类别过滤器后才可见,然后显示所有条目subTypeOf所选类别。 特殊情况进一步下降确保当用户选择其他类别时,过滤器消失。
_class参数增加了一些额外的灵活性。我使用与不同但相关的Type类相同的过滤器,只需覆盖此一个参数即可。只需将其替换为您要过滤的admin.Model类。
Here is what worked for me... The "TypeListFilter" is only visible once the "Category" filter is used and then displays all the entries that are a "subTypeOf" the selected category. The "special case" hack further down ensures that the filter disappears when the user selects another Category.The "_class" parameter adds some extra flexibility. I am using the same filter with different but related Type classes and just have to override this one parameter. Just replace it by the admin.Model class that you want to filter.
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())
这篇关于将当前过滤器选择提供给Django中另一个定制的SimpleListFilter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!