如何在forms.Form子类上动态设置models.ModelChoiceField的查询集

knu*_*ler 29 python django django-forms

构造函数forms.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='??????')
Run Code Online (Sandbox Code Playgroud)

我目前在做什么:

# 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
Run Code Online (Sandbox Code Playgroud)

然后我可以使用urlconf从url解析出的参数在视图中调用它来构造查询集并获取类.这感觉就像是错误的做法.有没有一种既定的方法在django做到这一点?

Dan*_*man 62

覆盖表单的__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
Run Code Online (Sandbox Code Playgroud)


rad*_*tek 14

在模板中显示表单之前,您也可以在视图中执行此操作.我使用它并发现它更灵活,因为你在其他视图中重用表单,并且每次都需要更改查询集:

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)
Run Code Online (Sandbox Code Playgroud)

我还在forms.py中将默认查询设置为none:

class AsssetSelectForm(forms.Form):
    asset = forms.ModelChoiceField(queryset=Asset.objects.none())
Run Code Online (Sandbox Code Playgroud)