Django ModelForm 使用不同的 ForeignKeys 创建多个实例

Posted

技术标签:

【中文标题】Django ModelForm 使用不同的 ForeignKeys 创建多个实例【英文标题】:Django ModelForm create multiple instances with different ForeignKeys 【发布时间】:2016-02-15 06:26:48 【问题描述】:

在我的 Django 应用程序中,我有两个这样的模型:

class Foo(models.Model):
    name = models.CharField(max_length=10)
    bar = models.ForeignKey(Bar)

class Bar(models.Model):
    class descr = models.CharField(max_length=50)

我想要一个很简单的 Foo 模型表单。但是,我希望能够创建多个单独绑定到不同 Bar 实例的 Foo 实例。所以,假设我有三个 Bar 实例,我想要一个模型表单,只有一个表单和一个提交,将创建三个 Foo 实例,每个实例分别将新的 Foo 实例链接到我的一个Bar 实例。

基本上我正在做的是对 Foo 进行“批量创建”。我不想使用多对多,因为我不想将一个 Foo 对象绑定到三个 Bar 对象。我希望每个酒吧都有自己独特的 Foo。

我想我可以使用 ModelForm,当我实例化它时,可能会添加一些对我的 Bar 实例的引用,然后在 modelform 上覆盖 save() 以创建“重复”条目。我的模型表单不包含 bar 字段,因为我将手动处理它。

这看起来是正确的方法吗?有什么陷阱吗?其他设计方法?

【问题讨论】:

【参考方案1】:

它没有你想象的那么复杂。在 django 中,当您将对象的 id 设置为 null 并再次保存时,django 将创建一个与第一个相同的新实例。所以你可以大致做:

form = FooForm(request.POST or None)
if form.is_valid():
    new_foo = form.save()
    new_foo.id = None
    # this will create another instance
    new_foo.save()

The doc has a section describes this.

你的方法有一个陷阱,你应该尽量远离覆盖模型/模型形式 save() 方法,它会搞砸很多事情和/或使事情变得复杂。如果您想通过模型上的其他步骤来保存某些内容,请使用 django pre_savepost_save signals。如果你想对模型表单做一些事情,请执行obj = form.save(commit=False) 并根据需要更改obj,然后执行obj.save()

【讨论】:

以上是关于Django ModelForm 使用不同的 ForeignKeys 创建多个实例的主要内容,如果未能解决你的问题,请参考以下文章

Django ModelForm 日期验证

Django CheckboxSelectMultiple 覆盖 ModelForm 中的“选择”

Django - Form嵌套的Meta类 + 为什么type()能创建类

如何在 django ModelForm CharField 之后添加“星 *”?

django - 使用 FormView 和 ModelForm 更新模型

django的modelform怎么设置required=False