Django,使用ManyToMany将初始数据设置为formset

时间:2011-03-07 17:35:22

标签: python django django-forms many-to-many

我需要使用formset字段将初始数据设置为ManyToMany

通常我在我的fomset形式中有 no ManyToMany字段时这样做:

PersonFormSet = forms.formsets.formset_factory(NickName, can_delete=True)
init_data = [{'name':'Vasya pupkin','nick':'Vasya'}, 
             {'name':'Vasyapupkin','nick':'Petya'}]

nick_formset = PersonFormSet(initial=init_data)

但是现在我需要设置ManyToMany字段的初始数据并尝试这样的事情:

NickNameFormSet = forms.formsets.formset_factory(NickName, can_delete=True)
init_data = [{'name': 'Vasya Pupkin',
              'nick': {'Vasya':'selected',
                       'Petya':'notselected'}}]

nick_formset = NickNameFormSet(initial=init_data)

但它不起作用。

如何将初始数据传递给Formset,以便像我这样呈现我的小部件:

<select multiple="multiple" name="person_set-0-nickname" id="id_person_set-0-nickname">
    <option value="1" selected="selected">Vasya</option>
    <option value="2">Petya</option>
</select>

注意:我只使用Forms和Django的Formsets。没有Django模型。我实际上可以定义它,但它是空的,我正在使用NoSQL

3 个答案:

答案 0 :(得分:1)

您应该提供pk列表作为ManyToMany关系的初始数据,而不是dict

看看this thread,它可能对您有所帮助。

答案 1 :(得分:0)

您可以使用__init__功能预先填充初始数据。

以下是我用于类似问题的内容:

class MyUpdateForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(MyUpdateForm, self).__init__(*args, **kwargs)
        self.initial['real_supplements'] = [s.pk for s in list(self.instance.plan_supplements.all())]

您可以提供任何Queryset,而不是在我的示例中使用self.instance.plan_supplements.all()

答案 2 :(得分:0)

赞:

class CustomFormSet(BaseInlineFormSet):
    def __init__(self, *args, **kwargs):
        kwargs['initial'] = [
            {'foo_id': 1}
        ]
        super(CustomFormSet, self).__init__(*args, **kwargs)

foo_id取决于您为模型关系中哪个字段选择的值

您还必须更改表单类上的has_changed方法,以使它知道保存时要考虑初始值的“更改”:

class CustomForm(forms.ModelForm):
    def has_changed(self):
        """
        Overriding this, as the initial data passed to the form does not get noticed,
        and so does not get saved, unless it actually changes
        """
        changed_data = super(starnpc_class, self).has_changed()
        return bool(self.initial or changed_data)