在 django 中保存对象列表
Posted
技术标签:
【中文标题】在 django 中保存对象列表【英文标题】:Save a list of objects in django 【发布时间】:2013-04-10 02:22:09 【问题描述】:我正在使用 django 1.5,我正在尝试做这样的事情:
quotes = formset.save()
user = client_form.save()
for quote in quotes:
quote.client = user
quotes.save()
但是列表没有 save() 方法,所以有一些内置功能可以做类似的事情吗?
我在 SO Question about batch save objects in Django 上找到了这个答案
django 1.5 仍然是真的吗? 有没有办法避免对列表的每个对象进行 save() 调用?
这是我的实际视图代码:
def new_quote(request):
QuoteLineFormSet = modelformset_factory(QuoteLine, form=QuoteLineForm, extra=2)
if request.method == 'POST':
formset = QuoteLineFormSet(request.POST, request.FILES, queryset=QuoteLine.objects.none())
quote_form = QuoteForm(request.POST, request.FILES)
if formset.is_valid() and quote_form.is_valid():
quote_lines = formset.save(commit=False)
#quote_lines = formset.get_queryset()
quote = quote_form.save()
for quote_line in quote_lines:
quote_line.quote = quote
quote_line.save()
request.session['quote_id'] = quote.id
return HttpResponseRedirect(reverse('new_client'))
else:
formset = QuoteLineFormSet(queryset=QuoteLine.objects.none())
quote_form = QuoteForm()
return render(request, 'request_quote_form.html',
'formset': formset,
'quote_form': quote_form,
)
我现在的解决方案
quote_line_ids = [item.pk for item in formset.save()]
quote_lines_qs = QuoteLine.objects.filter(pk__in=quote_line_ids)
quote = quote_form.save()
quote_lines_qs.update(quote=quote)
【问题讨论】:
【参考方案1】:您可以在查询集上使用update()
方法。
另见此问答:Django: form that updates X amount of models
【讨论】:
有用,但我不使用查询集 怎么样?我尝试了一些东西,但 formset.get_queryset() 总是返回一个空列表 谢谢。这是因为您在初始化QuoteLineFormSet
时设置了一个空查询集(请参阅docs)。所以,我的解决方案不适用于你的情况,抱歉。【参考方案2】:
也看看这个link。非常简单易用的方法。来自博客:
for x in seq:
o = SomeObject()
o.foo = x
o.save()
变成
l = []
for x in seq:
o = SomeObject()
o.foo = x
l.append(o)
insert_many(l)
【讨论】:
如果可能的话,我想避免使用一些第三方代码【参考方案3】:当您执行formset.save()
时,它访问数据库的次数与表单集中的表单数量一样多。因此,如果表单集中的元素数为n
,则其n
命中。
因此,您可以在表单集上使用commit=False
,它根本不会访问数据库。然后您可以更新对象并在每个对象上调用save()
。因此,您的数据库调用仍为 n
次。
#doesn't hit the database at all
quotes = formset.save(commit=False)
user = client_form.save()
for quote in quotes:
quote.client = user
#hits the db
quote.save()
不确定是否可以在一次调用 db 中完成整个操作。
【讨论】:
以上是关于在 django 中保存对象列表的主要内容,如果未能解决你的问题,请参考以下文章
在 postgres,Django 中保存大型 json 对象