2013-04-28 83 views
0

假設我有個條目的博客我想按類別或日期選擇地過濾:對於我使用以下形式的濾波器濾波形式設計

#forms.py 

class MyForm(forms.Form): 
    categories = forms.ModelMultipleChoiceField(Category.objects.all(), 
               required=False) 
    start_date = forms.DateField(required=False) 
    end_date = forms.DateField(required=False) 

我已經得到了以下觀點:

#views.py 

blog_entries = Blog.objects.all() 
cat_filter = TurnoverFilterForm(request.GET) 
    if cat_filter.is_valid(): 
     categories_chosen = cat_filter.cleaned_data['categories'] 
     start_date = cat_filter.cleaned_data['start_date'] 
     end_date = cat_filter.cleaned_data['end_date'] 
     blog_entries = blog_entries.cat_filter(categories_chosen).date_filter(start_date,end_date) 
return render(request,'index.html',{'blog_entries':blog_entries} 

其中date_filtercat_filter是自定義管理器功能(工作)。

的問題是:

  1. 我真的需要在形式可選每場?這些情況下是否有任何可選表單? (因爲有很多代碼冗餘)
  2. 我在窗體中有一個醜陋的if語句,因爲窗體總是有效的(或者至少應該是類別和日期範圍是可選的,並且窗體的請求類型是'獲得」
  3. 是否有這類問題的任何其他優雅的解決方案嗎?我能想象它是非常常見的
+0

該表格當然不總是有效的。如果我向您發送的請求的類別不是您給定的類別或未格式化爲日期的日期? – Xymostech 2013-04-28 22:45:55

+0

兩者都被'date_filter'和'cat_filter'抓住了 – ProfHase85 2013-04-28 22:51:00

+0

我不明白第2點。我沒有看到醜陋的'if'。它是'views.py'中的嗎? – 2013-04-29 02:20:31

回答

2

如果你想在表單中所有字段是可選的,你可能會覆蓋的的__init__功能形式是這樣的:

def __init__(self, *args, **kwargs): 
    super(forms.Form, self).__init__(*args, **kwargs) 
    for f in self.fields: 
     self.fields[f].required=False 

這樣您將所有字段的必填字段設置爲False,並避免代碼冗餘,以使整個表單成爲可選項。

is_valid方法將返回True總是你可以從你的代碼中刪除它,並添加到另一個函數,其餘的代碼封裝在views.py

有了這個,你可以簡化一點點代碼。如果你想要一些更好的東西來考慮Form類的子類並創建OptionalForm,那麼你可以使代碼重用。

+0

在這種情況下,我無法刪除'is_valid'方法,否則我的表單沒有'cleaned_data'。我非常感興趣的是:這是執行這類任務的常用方式嗎?我可以想象一個人會經常遇到這樣的問題;) – ProfHase85 2013-04-29 08:34:14

+1

嗯,我不是Django最佳實踐中的一個機構,但我認爲儘管它是一個相當大的框架,但它沒有爲每一個可能的目的用戶。與所有的框架一樣,有時候開發人員需要做一些聰明的編碼,以獲得漂亮而有用的解決方案:) PS:你說的是'is_valid',但是你仍然可以不用'if ':P – 2013-04-29 12:31:50