4

I am using django 1.5 and i am trying to do something like this :

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

But lists dont have a save() method so is there some built in functionality to do something similar ?

I found this nswer on SO Question about batch save objects in Django

Is it still True with django 1.5 ? Is there no way to avoid the save() call on each object of the list ?

here is my actual view code:

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,
    })

My solution for now

    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)
Community
  • 1
  • 1
maazza
  • 7,016
  • 15
  • 63
  • 96

3 Answers3

5

You can use update() method on a queryset.

Also see this question and answer: Django: form that updates X amount of models

Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • useful but i don't use a queryset – maazza Apr 17 '13 at 11:59
  • 1
    how ? i tried a few things but formset.get_queryset() always return an empty list – maazza Apr 17 '13 at 12:23
  • Thank you. That's because you're setting an empty queryset while initializing `QuoteLineFormSet` (see [docs](https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#changing-the-queryset)). So, my solution won't work in your case, sorry. – alecxe Apr 17 '13 at 12:50
2

When you do formset.save(), it hits database as many times as number of forms in the formset. So, its n hits if the number of element in the formset is n.

So, you can have commit=False on the formset which will not hit the db at all. Then you can update the objects and call save() on each object. So, your database calls remain n times.

#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()

Not sure if you can do this entire operation in one call to db.

Akshar Raaj
  • 14,231
  • 7
  • 51
  • 45
0

Also have look at this link. Very straightforward easy-to-use approach. From the blog:

for x in seq:
   o = SomeObject()
   o.foo = x
   o.save()

becomes

l = []
for x in seq:
    o = SomeObject()
    o.foo = x
    l.append(o)
insert_many(l)
LarsVegas
  • 6,522
  • 10
  • 43
  • 67