首页 > 解决方案 > Django CreateView 多对象插入

问题描述

我不知道标题应该是什么,但在这里我有一个案例,如果提交了表单,它将从其他模型中查找数据并插入每个匹配的数据。

目前这里是我的代码。

我在这里models.py

class Foo(models.Model):
    name = models.CharField()
    value = models.DecimalField()

class Bar(models.Model):
    name = models.CharField()
    date = models.DateField()
    foo = models.ForeignKey(Foo, related_name='foo')

我在这里views.py

class Foo(CreateView):
    fields = ('name', 'value')
    model = models.Foo

    def form_valid(self, form):
        self.object = form.save(commit=False)
        for i in range(30):
            self.object.bar.foo.append(self.object.id)


        return super(ModelFormMixin, self).form_valid(form)

Bar必须ForeignKeyFoo个例子,如果表单是随它一起提交的,range(30)它将为每个数据找到Bar并插入 ( append) Foo id。现在我做这个,

self.object.bar.foo.append(self.object.id)但错误说'Foo' object has no attribute 'bar'

如何将append多个数据插入到Barfrom Foo(CreateView)?...

标签: pythondjangodjango-views

解决方案


首先 append是 的方法list,而 FK 关系绝对不是一个列表。其次,你已经related_name='foo'在你的Bar模型中使用了,所以实际上你可以Bar通过Foo使用foo.foo. 我确信这是一个错误。只要一个Foo可以有很多Bar,你的related_name应该是bars,这样你就能用foo.bars.all()。要创建Bar,你应该首先保存你的Foo,所以使用commit=True.
最后一个。在您的 for 循环中使用Bar.objects.create(foo=self.object). 您还想用它bulk_create来优化该循环,因此您不会对数据库进行 30 次查询,而只需进行一次查询。bars = []要实现它,请在循环之前创建一个列表。比内部循环使用bars.append(Bar(foo=self.object). 这里append是方法list,所以你只是创建一个Bar对象列表而不将它们保存到数据库中。最后在循环使用后将Bar.objects.bulk_create(bars)它们实际保存到数据库中。

我已经重读了你的问题,也许我错过了重点。你想如何“找到”你的Bar?此外,您不能将多个添加Foo到您的Bar中,因为如果 FK 表示单个对象。


推荐阅读