2011-09-03 103 views
3

我有一個問題 - 可以自定義Django Admin界面,它只顯示那些匹配當前選定過濾器的數據子集中出現的那些過濾器選項?django管理過濾器級聯

說我有三個對象的DB:

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

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

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

,並與「富」和「酒吧」過濾器Django管理界面。我想要下面的行爲:

  • 如果沒有過濾器被選中,'Foo'列出「一」,「兩」; 'Bar'列出「Drink」,「Shot」
  • 如果'Foo'過濾器設置爲「One」,'Bar'列出「Drink」和「Shot」
  • 如果'Foo'如果'Bar'過濾器設置爲'Shot','Foo'將同時列出「One」和「Two」
  • 如果'Bar'過濾器設置爲「飲料「,」Foo「僅列出」One「

乾杯!


更具體 - 閱讀一些文檔後:

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 

它做什麼,但是,是得到「查詢集」,因爲它會一直沒有其他過濾器。我怎樣才能通過其他過濾器?


我可以在理論上解析請求和手動過濾 - 但肯定需要一個方式來管所有過濾器。

+0

在一些研究之後添加了更多信息 - 我無法完全弄清楚如何在所有其他過濾器通過它傳遞後獲取查詢集。 – qdot

回答

2

這種動態過濾真的看起來像刻面。雖然您可以使用標準查詢集來實現此結果,但這可能不是最佳選擇。您可能有更多機會使用像Solr這樣的專用工具。

Haystack has also a doc page on faceting

+0

乾草堆確實聽起來像一個不錯的地方,開始鑽進..好的提示! – qdot

1

的情況下,任何人都需要一個輕量級的解決方案,這其中確實當過濾器沒有選擇大陸,只提供了存在於選定大陸的國家是隱藏一個國家過濾:

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,)