【问题标题】:Django, set initial data to formset with ManyToManyDjango,使用ManyToMany将初始数据设置为formset
【发布时间】:2011-03-07 17:35:22
【问题描述】:

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

通常,当我的 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>

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

【问题讨论】:

  • 其实我找到了解决方案。但那是一年多以前的事了。不记得了。我可以帮你找。

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


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    您可以使用__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())]
    

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

    【讨论】:

      【解决方案3】:

      像这样:

      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)
      

      【讨论】:

        猜你喜欢
        • 2017-05-20
        • 2019-02-05
        • 2018-06-08
        • 2016-03-17
        • 2016-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多