2013-03-06 18 views
0

我有以下形式:依賴於其他其他車型表單字段需要重新啓動服務器

class AlertForm(forms.Form): 
    user_choices = sorted([(c.id, c.first_name + ' ' + c.last_name) \ 
     for c in User.objects.all()], key=lambda user: user[1]) 
    message = forms.CharField(widget=forms.Textarea()) 
    recipients = forms.MultipleChoiceField(choices=user_choices, 
     widget=forms.SelectMultiple(attrs={'size':'20'}), 
     help_text="You will automatically be included with the recipients.") 

的問題是,如果我將用戶添加到使用管理界面或任何其他方法的數據庫,我有在新添加的用戶出現在MultipleChoiceField中之前重新啓動服務器。我怎樣才能避免服務器重啓?

回答

3

如果要動態計算choices,則需要在表單的__init__方法中執行此操作,而不是在表單定義中執行此操作。請記住,類的主體只在加載類定義時執行一次 - 這就是爲什麼服務器重新啓動可以解決您的問題。

你會想是這樣的:

def __init__(self, *args, **kwargs): 
    super(AlertForm, self).__init__(*args, **kwargs) 
    user_choices = sorted([(c.id, c.first_name + ' ' + c.last_name) \ 
     for c in User.objects.all()], key=lambda user: user[1]) 
    self.fields['recipients'].choices = user_choices 

你也很可能condense是到使用聚合,order_by一個QuerySet,並values達到同樣的效果。

0

在我的搜索中,我發現了一個更簡單的解決方案:ModelMultipleChoiceField。它的實現是這樣的:

class AlertForm(forms.Form): 
    message = forms.CharField(widget=forms.Textarea()) 
    recipients = forms.ModelMultipleChoiceField(queryset=User.objects.all()) 

此表單字段處理所有的細節,包括動態更新收件人場。

+0

請注意,這並不完全符合你的問題所要求的:選擇文本將是你的User類的'__unicode__'或__string__'方法的值(默認只是'username',而不是「」就像你的問題一樣,排序順序也會回落到模型的默認值,而不是你正在使用的默認值。 – 2013-03-06 19:50:01