2008-10-07 61 views
5

我想什麼才達到的是:飼養過濾器

  • 我去管理網站,應用一些過濾器的對象列表
  • 我點擊和對象編輯,編輯,編輯,打'保存'
  • 網站將我帶到未過濾的對象列表。我想從步驟1開始記憶和應用過濾器。

有沒有簡單的方法來做到這一點?

回答

3

不幸的是,沒有簡單的方法來做到這一點。過濾似乎不會保存在任何會話變量中。

點擊返回兩次是正常的方法,但如果您剛剛更改了某個對象,以便不再使用您的過濾器顯示該對象,則該方法可能會不受歡迎和煩人。

如果它只是一次性的,請點擊兩次或再次過濾,這是最簡單的方法。

如果您要更頻繁地進行過濾,或者您只想瞭解黑客入侵(這非常開放和容易),您需要編寫FilterSpec

看看herehere爲自己寫的人的例子。

要做到這一點,真的很可怕的方法是編輯管理界面,以便在點擊「保存」後,您被重定向到您過濾的URL。我不會推薦這個,但它是一個選項。

另一個相當簡單的方法是編寫一個通用視圖來顯示過濾對象,然後使用Django表單來編輯這些項目。我會看看這個,你會驚訝於你要寫一個簡單的視圖/編輯頁面的代碼很少。

+1

寫一個`FilterSpec`是不夠的。它實際上是控制查詢集的視圖,它從`request.GET`中獲取參數。所有`FilterSpec`真的會影響過濾器選項的顯示。 – 2010-04-15 10:58:37

+0

此外,重定向到一個過濾的URL不是「真的,真的很糟糕」。過濾器選項應該在URL中明確。如果在URL中沒有明顯的變化,將會有一個不可見的會話變量影響查詢集。 – 2010-04-15 13:52:00

1

點擊2次「返回」?

+0

KISS最好:) – 2010-10-03 16:43:13

1

有一個簡單的方法來做到這一點,但它不是一個通用的解決方案,並且需要修改每個想要支持這個的ModelAdmin。也許有一個通用的方法來做到這一點,但我沒有花時間在一般水平上解決它。

第一步是爲過濾器編寫自定義FilterSpec(請參閱哈利的鏈接幫助文章),該過濾器會將所選過濾器值保存在會話中(並在不再需要時將其刪除)。

# in cust_admin/filterspecs.py 
from django.contrib.admin.filterspecs import FilterSpec, ChoicesFilterSpec 

class MyFilterSpec(ChoicesFilterSpec): 

    def __init__(self, f, request, params, model, model_admin): 
     super(MyFilterSpec, self).__init__(f, request, params, model, 
              model_admin) 
     if self.lookup_val is not None: 
      request.session[self.lookup_kwarg] = self.lookup_val 
     elif self.lookup_kwarg in request.session: 
      del(request.session[self.lookup_kwarg]) 

# Register the filter with a test function which will apply it to any field 
# with a my_filter attribute equal to True 
FilterSpec.filter_specs.insert(0, (lambda f: getattr(f, 'my_filter', False), 
           MyFilterSpec)) 

必須導入模塊,這是在某個地方,比如你的urls.py

# in urls.py 
from cust_admin import filterspecs 

設置要過濾器適用於在該領域的屬性:

# in models.py 
class MyModel(models.Model): 
    my_field = Models.IntegerField(choices=MY_CHOICES) 
    my_field.my_filter = True 

在自定義ModelAdmin類中,覆蓋change_view方法,以便在用戶單擊保存後,它們會返回到列表視圖,並將其篩選字段值添加到URL中。

class MyModelAdmin(admin.ModelAdmin): 
    def change_view(self, request, object_id, extra_context=None): 
     result = super(MyModelAdmin, self).change_view(request, object_id, 
                 extra_context) 
     if '_save' in request.POST: 
      if 'my_field__exact' in request.session: 
       result['Location'] = '/admin/myapp/mymodel/?my_field__exact=%s' \ 
            % request.session['my_field__exact'] 
     return result 
0

另一種方法是將過濾器嵌入到queryset中。

您可以動態創建一個代理模型,其中包含一個管理器,用於過濾您想要的方式,然後調用admin.site.register()創建一個新的模型admin。所有的鏈接將與這個觀點相關。

0

我認爲它能夠更好地從的ModelAdmin changelist_viewchange_view重載方法:

像這樣:

class FakturaAdmin(admin.ModelAdmin): 

[...] 

def changelist_view(self, request, extra_context=None): 
    result = super(FakturaAdmin, self).changelist_view(request, extra_context=None) 
    request.session['qdict'] = request.GET 
    return result 

def change_view(self, request, object_id, extra_context=None): 
    result = super(FakturaAdmin, self).change_view(request, object_id, extra_context) 
    try: 
     result['location'] = result['location']+"?"+request.session['qdict'].urlencode() 
    except: 
     pass 
    return result 

如你所願,後保存對象,你回去與有源濾波器對象列表。

0

在Django項目中有一個更改請求,要求準確地使用這個功能。

所有它等待檢查的是一些測試和文檔。你可以寫這些,並幫助整個項目,或者你可以採取建議的補丁(接近頁面底部)並嘗試一下。

https://code.djangoproject.com/ticket/6903

0

這個功能已經被添加到的Django的1.6版本的一部分,現在默認啓用。它在release notes描述:現在

的ModelAdmin創建後保留在列表視圖中的過濾器, 編輯或刪除的對象。通過將preserve_filters屬性 設置爲False,可以恢復以前的 清除過濾器的行爲。