2009-09-16 55 views
2

我基於模型的數據定義ChoiceField。基於模型數據向ChoiceField添加「空」選項

field = forms.ChoiceField(choices=[[r.id, r.name] for r in Model.objects.all()]) 

不過,我想在前面加上我的選擇與空單選擇「否」的對象。 但我找不到一個很好的方式來預先說明這一點。

我所有的測試,如:

field = forms.ChoiceField(choices=[[0, '----------']].extend([[r.id, r.name] for r in Model.objects.all()])) 

返回我 「NoneType對象不是可迭代」 的錯誤。 我發現到現在爲止唯一的辦法是:

def append_empty(choices): 
    ret = [[0, '----------']] 
    for c in choices: 
     ret.append(c) 
    return ret 

當我定義我的領域:

forms.ChoiceField(choices=append_empty([[r.id, r.name] for r in 
    Restaurant.objects.all()]), required=False) 

不過,我想保持我的代碼乾淨,沒有那種的恐怖。 你有想法嗎? :p 提前致謝。

回答

8

一個簡單的答案是做:

field = forms.ChoiceField(choices=[[0, '----------']] + [[r.id, r.name] for r in Model.objects.all()]) 

不幸的是,你的做法是錯誤的。即使使用「工作」方法,字段選項也是在表單定義時定義的,而不是在實例化時定義的 - 所以如果您將元素添加到「模型」表中,它們將不會出現在選擇列表中。

您可以通過執行表單的__init__方法中的分配來避免這種情況。

但是,有一種更簡單的方法。不要動態地混淆字段選擇,而應該使用專門設計用於從模型中提供選擇的字段 - ModelChoiceField。這不僅在實例化時動態獲取模型元素列表,而且默認情況下它已經包含空白選項。請參閱the documentation

+0

Yay! :) 謝謝。它現在可以找到。 – 2009-09-16 10:15:26

0

由於這個問題及其答案几乎解決了一個問題,我只是想添加一些東西。對我來說,id必須是空的,因爲模型沒有將「0」識別爲有效的選項,但它接受空(null = True,空白= True)。在初始化程序中:

self.fields['option_field'].choices = [ 
    ('', '------')] + [[r.id, r.name] for r in Model.objects.all()]