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']
我希望它的工作方式:
1.我的视图从request.GET获得"公司"
2.然后它过滤所有"联系人"为该"公司"
3.最后,它创建一个表单并传递这些"联系人"作为"初始= {...}"
两个问题:
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
Andre Miras.. 22
我正在回复1)
1.如何使ModelMultipleChoiceField获取那些"初始"值?
这可以Action_Form
__init__
使用ModelMultipleChoiceField 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()]
Jeff Bauer.. 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(...
如果您计划将过滤器参数作为关键字args传递给Action_Form
,则需要在调用super之前删除它们:
myfilter = kwargs['myfilter'] del kwargs['myfilter']
或者,可能更好:
myfilter = kwargs.pop('myfilter')
有关更多信息,请参阅Django中指向Dynamic ModelForms的另一个链接.
我正在回复1)
1.如何使ModelMultipleChoiceField获取那些"初始"值?
这可以Action_Form
__init__
使用ModelMultipleChoiceField 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()]
您需要添加一个__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(...
如果您计划将过滤器参数作为关键字args传递给Action_Form
,则需要在调用super之前删除它们:
myfilter = kwargs['myfilter'] del kwargs['myfilter']
或者,可能更好:
myfilter = kwargs.pop('myfilter')
有关更多信息,请参阅Django中指向Dynamic ModelForms的另一个链接.
如果以前的答案不够直截了当,我会再次尝试回答1):
如何让ModelMultipleChoiceField获取那些"初始"值?
您可以Action_Form
像原始问题一样离开,只需使用它来准确呈现您想要的内容:
>>> form4 = Action_Form(initial={'from_company': Contact.objects.all().values_list('id',flat=True)}) >>> print form4['from_company']
回答(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()]