在我的表单中,我有一个下拉列表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
答案 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参数中获得虚假输入。