ModelMultipleChoiceField没有选择初始选择,我无法在我的示例中进行以下修复(链接如下):
http://code.djangoproject.com/ticket/5247#comment:6
我的模特和表格:
class Company(models.Model):
company_name = models.CharField(max_length=200)
class Contact(models.Model):
company = models.ForeignKey(Company)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
class Action(models.Model):
company = models.ForeignKey(Company, blank=True, null=True)
from_company = models.ManyToManyField(Contact, verbose_name='Participant(s) from "Company"', blank=True, null=True)
class Action_Form(ModelForm):
from_company = forms.ModelMultipleChoiceField(queryset=Contact.objects.none(), widget=forms.CheckboxSelectMultiple())
class Meta:
model = Action
我的所作所为和结果:
>>> contacts_from_company = Contact.objects.filter(company__exact=1) # "1" for test, otherwise a variable >>> form = Action_Form(initial={'from_company': [o.pk for o in contacts_from_company]}) # as suggested in the fix >>> print form['from_company'] <ul> </ul> >>> print contacts_from_company [<Contact: test person>, <Contact: another person>] >>> form2 = Action_Form(initial={'from_company': contacts_from_company}) >>> print form2['from_company'] <ul> </ul> >>> form3 = Action_Form(initial={'from_company': Contact.objects.all()}) >>> print form3['from_company'] <ul> </ul>
我希望它能起作用的方式:
我的观点得到了“公司”的请求.GET
2.然后它过滤所有“公司”的“联系人”
3.最后,它创建一个表单并将这些“联系人”传递为“initial = {...}”
两个问题:
的 1。 [尚未回答] 如何让ModelMultipleChoiceField获取那些“初始”值?
的 2。 [回答] 作为替代方案,我可以将变量传递给Action_Form(ModelForm),以便在我的ModelForm中可以有:
from_company = forms.ModelMultipleChoiceField(queryset=Contact.objects.filter(company__exact=some_id) # where some_id comes from a view
答案 0 :(得分:21)
我正在回复1)
1。如何让ModelMultipleChoiceField获取那些“初始”值?
可以使用ModelMultipleChoiceField Action_Form
属性在__init__
initial
方法中完成此操作。
正如它在Django源代码中所说的那样( db / models / fields / related.py )
在def formfield(self, **kwargs)
:
# If initial is passed in, it's a list of related objects, but the
# MultipleChoiceField takes a list of IDs.
所以你需要给它一个ID列表:
class Action_Form(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(Action_Form, self).__init__(*args, **kwargs)
self.fields['from_company'].initial = [c.pk for c in Contact.object.filter()]
答案 1 :(得分:14)
您需要向__init__
添加Action_Form
方法以设置初始值,并记住通过 super <在基础__init__
课程上调用ModelForm
/强>
class Action_Form(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(Action_Form, self).__init__(*args, **kwargs)
self.fields['from_company'].queryset = Contact.object.filter(...
如果您计划将过滤器参数作为关键字参数传递给Action_Form
,则需要在调用super之前将其删除:
myfilter = kwargs['myfilter']
del kwargs['myfilter']
或者,可能更好:
myfilter = kwargs.pop('myfilter')
有关详细信息,请参阅Dynamic ModelForms in Django的另一个链接。
答案 2 :(得分:11)
如果以前的答案不够直截了当,我会再次尝试回答1):
- 如何让ModelMultipleChoiceField获取那些“初始”值?
醇>
您可以保留原始问题中的Action_Form
,并使用它来准确呈现您想要的内容:
>>> form4 = Action_Form(initial={'from_company': Contact.objects.all().values_list('id',flat=True)})
>>> print form4['from_company']
答案 3 :(得分:10)
回答(1)问题!
这不起作用:
self.fields['from_company'].initial = [c.pk for c in Contact.object.filter()]
但确实有效:
self.initial['from_company'] = [c.pk for c in Contact.object.filter()]