Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Django Forms Inlines and Media Save a Valid Formset

Nathan Magyar
Nathan Magyar
11,332 Points

DigitalFormset bulk create in view

Hello, When I run the following code I receive this error: "Didn't find any 'Digital' records." I have also tried looping through the products in formset after formset.is_valid(), and saving each product individually. But then I get an error stating the formset isn't found in the HTML.

The prompt for this challenge is: "Now that we have a solid formset factory, we need to use it in a view. I've already set up a view, bulk_create_product, but it doesn't do anything on POST requests. Update the view so that POST requests, if valid, populate and save the formset. After saving, it should return a redirect to the URL named "products:bulk_create"."

Since I'm not modifying the products after the validation process (no formset.save(commit=False) seems necessary this time), I'm confused as to whether I need to save each product individually or if I can save the whole formset as-is.

Thanks in advance for any help!

products/views.py
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.shortcuts import render

from . import forms


def product_form(request):
    form = forms.DigitalProductForm()
    if request.method == 'POST':
        form = forms.DigitalProductForm(request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse('products:create'))
    return render(request, 'products/product_form.html', {'form': form})


def bulk_create_products(request):
    formset = forms.DigitalFormset()

    if request.method == 'POST':
        formset = forms.DigitalFormset(request.POST)

        if formset.is_valid():

            formset.save()

            return HttpResponseRedirect('products:bulk_create')

    return render(request, 'products/bulk_create.html', {'formset': formset})

1 Answer

Jeff Muday
MOD
Jeff Muday
Treehouse Moderator 28,722 Points

Nathan, you have the right idea. It has been awhile since I took the course, so I am not sure if formset has a save method. So your idea of looping through the formset and checking the validity of each form is a good approach.

Good luck with Django! Formsets are pretty challenging to work with at first, but are very powerful and can save time.

See the solution below that I got to work:

def bulk_create_products(request):
    formset = forms.DigitalFormset()
    if request.method == 'POST':
        formset = forms.DigitalFormset(request.POST)
        if formset.is_valid():
            for form in formset:
                if form.is_valid(): # check if the individual form is valid
                    form.save()
            return HttpResponseRedirect(reverse('products:bulk_create')) 
    return render(request, 'products/bulk_create.html', {'formset': formset})
Nathan Magyar
Nathan Magyar
11,332 Points

Hi Jeff, thanks for your help! Your solution worked for me. It makes sense to have to loop through the formset, as it is comprised of individual model forms that should be validated on their own before being added to the database individually. I also noticed that I wasn't reversing the URL name in my previous attempt, which was further adding to my struggle. Thanks again!