在django中保存对象列表

时间:2013-04-17 10:50:00

标签: python django django-views django-orm django-1.5

我正在使用django 1.5,我正在尝试这样做:

    quotes = formset.save()
    user = client_form.save()
    for quote in quotes:
        quote.client = user
    quotes.save()

但是list没有save()方法,所以有一些内置的功能可以做类似的事情吗?

我在SO Question about batch save objects in Django

上找到了这个nswer

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)

3 个答案:

答案 0 :(得分:5)

您可以在查询集上使用update()方法。

另请参阅此问题和答案:Django: form that updates X amount of models

答案 1 :(得分:2)

执行formset.save()时,它会在表单集中的表单数量上多次访问数据库。因此,如果formset中的元素数为n,则n会点击。

所以,你可以在formset上拥有commit=False,它根本不会命中db。然后,您可以更新对象并在每个对象上调用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中执行整个操作。

答案 2 :(得分:0)

另请查看此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)