2011-02-02 23 views
22

forms.ModelChoiceField的構造函數需要一個查詢集。在請求發生之前,我不知道該查詢集。蒸餾水:如何在forms.Form子類上動態設置models.ModelChoiceField的查詢集

# models.py 
class Bar(models.model): 
    text = models.TextField() 

class Foo(models.Model): 
    name = models.CharField() 
    bar = models.ForeignKey(Bar) 

# forms.py 
class FooForm(forms.Form): 
    name = forms.CharField() 
    text = forms.CharField(widget=forms.TextArea) 

    bar = forms.ModelChoiceField(queryset='??????') 

什麼我目前做的:

# forms.py 

def get_foo_form_class(bars_queryset): 
    class FooForm(forms.Form): 
     name = forms.CharField() 
     text = forms.CharField(widget=forms.TextArea) 

     bar = forms.ModelChoiceField(queryset=bars_queryset) 

    return FooForm 

然後我就可以使用解析出該URL的參數與URL配置來構造查詢集和獲取類調用它的觀點。這感覺就像是錯誤的做法。有沒有一種在Django中做到這一點的既定方法?

回答

50

重寫窗體的__init__方法並在那裏設置查詢集。

class FooForm(forms.Form): 
    bar = forms.ModelChoiceField(queryset=Bar.objects.none()) 

    def __init__(self, *args, **kwargs): 
     qs = kwargs.pop('bars') 
     super(FooForm, self).__init__(*args, **kwargs) 
     self.fields['bar'].queryset = qs 
11

您也可以在模板中顯示錶單之前在視圖中執行此操作。我用這個,並發現它更靈活的櫃面你重新使用在其他視圖的形式,需要在每次更改查詢集:

from assets.models import Asset 
location_id = '123456' 
edit_form = AsssetSelectForm(request.POST or None, instance=selected_asset) 
edit_form.fields["asset"].queryset = Asset.objects.filter(location_id=location_id) 

我還設置了默認查詢集首屈一指的forms.py:

class AsssetSelectForm(forms.Form): 
    asset = forms.ModelChoiceField(queryset=Asset.objects.none())