2011-02-02 19 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 

私は、クエリセットを構築し、クラスを取得するためのURLconfで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()) 
関連する問題