CreateView使用参数

CreateView use parameters

在我的表单中,我有一个下拉列表 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

您可以覆盖视图的 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

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

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

这样您将通过 kwargs 接收类型,并且您仍然可以使用反向模式创建指向某些类型的自定义链接

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

不要忘记您有可能从 GET 参数中获得虚假输入。

您应该使用视图的 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__方法中为字段设置queryset:

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 是详细介绍所有基于 class 的通用视图可用方法的重要资源。