CreateView使用参数

时间:2015-03-13 12:21:10

标签: python django django-class-based-views

在我的表单中,我有一个下拉列表projects,它应该使用ModelChoiceField显示基于某种类型的一些元素。此查询需要一些参数,但如何将此参数传递给表单?

class TaskCreate(CreateView):
    model = Task
    fields = ['name', 'description', 'project']

    def form_valid(self, form):
        return super(TaskCreate, self).form_valid(form)

\

class TaskcreateForm(forms.ModelForm):
    projects = forms.ModelChoiceField(queryset=Project.objects.filter(type=someParameter))
    class Meta:
        model = Task

3 个答案:

答案 0 :(得分:2)

您应该使用视图的get_form_kwargs方法:

class TaskCreate(CreateView):
    model = Task
    fields = ['name', 'description', 'project']

    def form_valid(self, form):
        return super(TaskCreate, self).form_valid(form)

    def get_form_kwargs(self):
        """
        Returns the keyword arguments for instantiating the form.
        """
        kwargs = super(TaskCreate, self).get_form_kwargs()
        kwargs.update({'my_var': 'my value'})
        return kwargs

然后以__init__形式捕获该参数。您还需要在__init__方法中为字段设置查询集:

class TaskcreateForm(forms.ModelForm):
    projects = forms.ModelChoiceField(queryset=Project.objects.none())

    def __init__(self, *args, **kwargs):
        self.my_var = kwargs.pop('my_var')
        super(TaskcreateForm, self).__init__(*args, **kwargs)
        self.fields['projects'].queryset = Project.objects.filter(type=self.my_var))

    class Meta:
        model = Task

必须使用kwargs.pop(),否则对super()的调用会因意外的关键字参数而引发错误。

CCBV是详细介绍所有基于类的基于通用视图的可用方法的绝佳资源。

答案 1 :(得分:1)

您可以覆盖视图的get_form()方法。例如,如果您通过request.GET提供此参数,则视图将如下所示:

class TaskCreate(CreateView):
    ...
    def get_form(self, form_class):
        form = super(TaskCreate, self).get_form(form_class)
        form.fields['project'].queryset = Project.objects.filter(
                                               type=self.request.GET['type'])
        return form

在表单中,您可以将查询集设置为none()

class TaskcreateForm(forms.ModelForm):
    projects = forms.ModelChoiceField(queryset=Project.objects.none())
    class Meta:
        model = Task

答案 2 :(得分:0)

Catavaran的回答是直截了当的。另一种选择可能是将类型添加到url模式(未经测试的语法)

url(r'^create/(?P<type>[-\w]+)/$', TaskCreate.as_view(), name='create_task')

这样你就会通过kwargs收到类型,你仍然可以使用反向模式创建指向某些类型的自定义链接

{% url 'create_task' type='foo' %}

不要忘记你有机会从GET参数中获得虚假输入。