将Queryset的参数传递给Django表单

时间:2018-12-31 15:27:22

标签: django django-forms

我正在为表单使用Django(2.1)ModelMultipleChoice字段。我正在尝试根据URL中的子弹修改queryset。我可以肯定我想念一些愚蠢的东西。

表格:

class SubdomainForm(forms.Form):
    # TODO Get the value slug from init
    slug = "camp" # Works well if value of slug set here.
    q = Feature2Subdomain.objects.all().select_related().filter(subdomain__slug=slug)
    choices = forms.ModelMultipleChoiceField(
        queryset = q,
        widget = forms.CheckboxSelectMultiple,
    )

def __init__(self, *args, **kwargs):
    slug = kwargs.pop('slug', None) # Correctly obtains slug from url
    super(SubdomainForm, self).__init__(*args, **kwargs)

视图:

class SubdomainDetailView(FormView):
    template_name = "guide/subdomain-detail.html"
    form_class = SubdomainForm

    def get_form_kwargs(self, form_class=SubdomainForm):
        s = dict(slug = self.kwargs['slug'])
        return s

URLS.py

urlpatterns = [
    path('subdomain/<slug:slug>/',
         SubdomainDetailView.as_view(),
         name="subdomain-detail"
    ),
    .....

很明显,这个想法是使用URL中的段来修改查询集。 (在示例中,该条的值为“ camp”

我可以在表单的 init 方法中获取该段的值,并可以调用super()实例化该表单。但是,我不知道如何访问表单的“选择”行中的值。如果我对slug =“ camp”的值进行硬编码,则可以使整个事情正常运行。

我已经为此工作了几天,并用完了SO和google中的所有示例。

我尝试将“选择”分配移至 init 方法并使用

 self.choices = forms.ModelMultipleChoiceField(
        queryset = Feature2Subdomain.objects.all().select_related().filter(subdomain__slug=slug)
        widget = forms.CheckboxSelectMultiple,
    )

但这不会显示正确的响应(它返回一个空表格)

也尝试使用这种 init 方法分配查询集。

class SubdomainForm(forms.Form):
    choices = forms.ModelMultipleChoiceField(
        widget = forms.CheckboxSelectMultiple,
    )

    def __init__(self, *args, **kwargs):
        slug = kwargs.pop('slug', None) # Correctly obtains slug from url
        self.queryset = Feature2Subdomain.objects.all().select_related().filter(subdomain__slug=slug)

        super(SubdomainForm, self).__init__(*args, **kwargs) 

然后我得到了错误: TypeError: init ()缺少1个必需的位置参数:“ queryset”

下一步去哪里感觉很茫然。

任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

对于上一次尝试,您可以像下面这样修改代码:

class SubdomainForm(forms.Form):
    choices = forms.ModelMultipleChoiceField(
        widget = forms.CheckboxSelectMultiple,
        queryset = Feature2Subdomain.objects.all()
    )

    def __init__(self, *args, **kwargs):
        slug = kwargs.pop('slug', None) # Correctly obtains slug from url
        self.fields['choices'].queryset = Feature2Subdomain.objects.filter(subdomain__slug=slug)  # you don't need select related

        super(SubdomainForm, self).__init__(*args, **kwargs)