我想什麼才達到的是:飼養過濾器
- 我去管理網站,應用一些過濾器的對象列表
- 我點擊和對象編輯,編輯,編輯,打'保存'
- 網站將我帶到未過濾的對象列表。我想從步驟1開始記憶和應用過濾器。
有沒有簡單的方法來做到這一點?
我想什麼才達到的是:飼養過濾器
有沒有簡單的方法來做到這一點?
不幸的是,沒有簡單的方法來做到這一點。過濾似乎不會保存在任何會話變量中。
點擊返回兩次是正常的方法,但如果您剛剛更改了某個對象,以便不再使用您的過濾器顯示該對象,則該方法可能會不受歡迎和煩人。
如果它只是一次性的,請點擊兩次或再次過濾,這是最簡單的方法。
如果您要更頻繁地進行過濾,或者您只想瞭解黑客入侵(這非常開放和容易),您需要編寫FilterSpec。
要做到這一點,真的很可怕的方法是編輯管理界面,以便在點擊「保存」後,您被重定向到您過濾的URL。我不會推薦這個,但它是一個選項。
另一個相當簡單的方法是編寫一個通用視圖來顯示過濾對象,然後使用Django表單來編輯這些項目。我會看看這個,你會驚訝於你要寫一個簡單的視圖/編輯頁面的代碼很少。
點擊2次「返回」?
KISS最好:) – 2010-10-03 16:43:13
有一個簡單的方法來做到這一點,但它不是一個通用的解決方案,並且需要修改每個想要支持這個的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
另一種方法是將過濾器嵌入到queryset中。
您可以動態創建一個代理模型,其中包含一個管理器,用於過濾您想要的方式,然後調用admin.site.register()創建一個新的模型admin。所有的鏈接將與這個觀點相關。
我認爲它能夠更好地從的ModelAdmin changelist_view
和change_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
如你所願,後保存對象,你回去與有源濾波器對象列表。
在Django項目中有一個更改請求,要求準確地使用這個功能。
所有它等待檢查的是一些測試和文檔。你可以寫這些,並幫助整個項目,或者你可以採取建議的補丁(接近頁面底部)並嘗試一下。
這個功能已經被添加到的Django的1.6版本的一部分,現在默認啓用。它在release notes描述:現在
的ModelAdmin創建後保留在列表視圖中的過濾器, 編輯或刪除的對象。通過將preserve_filters屬性 設置爲False,可以恢復以前的 清除過濾器的行爲。
寫一個`FilterSpec`是不夠的。它實際上是控制查詢集的視圖,它從`request.GET`中獲取參數。所有`FilterSpec`真的會影響過濾器選項的顯示。 – 2010-04-15 10:58:37
此外,重定向到一個過濾的URL不是「真的,真的很糟糕」。過濾器選項應該在URL中明確。如果在URL中沒有明顯的變化,將會有一個不可見的會話變量影響查詢集。 – 2010-04-15 13:52:00