Django在单个视图中保存不同的对象

时间:2017-02-18 18:16:19

标签: django django-forms formset

我需要渲染一个我显示的视图:

  • 模型A的一种形式。
  • 模型B的多种形式。它具有FK到A。

用户点击保存后,应保存模型A和所有模型B.然后,在正确更新字段的情况下呈现相同的视图。

有一种特殊情况,这个视图必须是init,模型B表格填充了来自另一个模型(C)的数据。

我正在尝试使用FormView实现此视图,FormView为模型A呈现ModelForm,为模型B呈现formset,没有运气。这是正确的方法吗?什么样的表格适合更好?

1 个答案:

答案 0 :(得分:0)

有几种方法可以做到这一点。您可以使用FormView,也可以使用CreateView和UpdateView。如果有多个表单,则需要至少覆盖​​视图中的四种方法:

  1. 获取 - 初始化所有需要的表单并将其传递给上下文
  2. 发布 - 处理表单发送的数据(使用self.request.POST初始化表单并验证它们)
  3. form_valid - 继续使用有效表单
  4. form_invalid - 继续使用无效表单
  5. 每个对象都应该定义其ModelForm类(在forms.py中)。如果有一个类的多种形式与另一个类的实例相关,则应使用Django formsets。

    您还可以尝试将所有逻辑放在窗体类中,并在视图中使用最少的代码。这是我使用crispy_forms时的首选方式,我认为它更短更清洁。在主类的ModelForm类中,我初始化所有其他表单并将POST数据传递给它们。使用crispy_forms我将所有表单放在主表单中(使用FormHelper和Layout),以便您通过单个{%crispy form%}

    在模板中调用所有表单

    步骤如下:

    1. 为forms.py
    2. 中的每个类创建ModelForm类
    3. 使用CreateView和UpdateView为主类(其他类与之关联的那个)创建views.py中的视图。
    4. 在主类的表单类中覆盖init方法,以便初始化其他相关类的表单,并将它们全部放在main中以便使用FormHelper和Layout
    5. 在同一个类中覆盖is_valid方法,因此它在所有表单上调用is_valid
    6. 在同一个类中覆盖save方法,以便在所有表单上调用save