Handle multiple modelforms in one html form

31 views
Skip to first unread message

Kakar Nyori

unread,
Jan 17, 2015, 3:12:52 AM1/17/15
to django...@googlegroups.com
A user will have photos which will be related with their specific album.

So this was the model for that:

    class Album(models.Model):
        user = models.ForeignKey(User)
        title = models.CharField(max_length=200)
        pub_date = models.DateTimeField(auto_now_add=True, auto_now=False)
        update = models.DateTimeField(auto_now_add=False, auto_now=True)
    class Photo(models.Model):
        photo_privacy = models.CharField(max_length=1,choices=PRIVACY, default='F')
        user = models.ForeignKey(User)
        caption = models.TextField()
        image = models.ImageField(upload_to=get_upload_file_name)
        pub_date = models.DateTimeField(auto_now_add=True, auto_now=False)


Views.py:

    def create_album(request, user_name):
        user = User.objects.get(username=unquote(user_name))
        if request.method=='POST':
            pform = AlbumPhotoForm(request.POST, request.FILES)
            aform = AlbumForm(request.POST)
            p_valid = pform.is_valid()
            a_valid = aform.is_valid()
            if p_valid and a_valid:
                photo = pform.save(commit=False)
                album = aform.save(commit=False)
                photo.user = user
                album.user = user
                album.save()
                photo.album = album
                photo.save()
                return HttpResponseRedirect('/'+user.username+'/photos')
            else:
                return render(request, 'create_album.html',{
                    'pform':pform,
                    'aform':aform
                })
        else:
            pform = AlbumPhotoForm()
            aform = AlbumForm()
            return render(request, 'create_album.html', {
                'pform':pform,
                'aform':aform
            })

And the form:

    <form action="/{{ user.username }}/create_album/" method="post" enctype="multipart/form-data">
    {% csrf_token %}
        {{ aform.as_p }}
        {{ pform.as_p }}
        <input type="submit" value="Create and Upload Album"/>
    </form>

This works fine if I only have to upload one file (photo) with that form.

However what I want to do is, show minimum of three input for uploading photos to the new album:

    <form action="/{{ user.username }}/create_album/" method="post" enctype="multipart/form-data">
    {% csrf_token %}
        {{ aform.as_p }}
        {{ pform.as_p }}
        {{ pform.as_p }}
        {{ pform.as_p }}
        <input type="submit" value="Create and Upload Album"/>
    </form>

When doing so, only the last pform is gets saved. And the other two pforms are ignored. How do I get to save all the three forms of photo (pforms) accordingly?

Or is there any other way around? Your help will be much appreciated! Thank you.

James Schneider

unread,
Jan 17, 2015, 4:34:37 AM1/17/15
to django...@googlegroups.com

I'm guessing that if you look at the generated source code in the browser, all of the names for the fields in the pform form's are the same, which likely collide on the Django side (if the browser actually posts all the copies with the same field names, not sure what the typical browser behavior is), which means the last set of form fields will overwrite the values of the previous form fields with the same names.

Either way, this is a case where Django formsets should be used, that way your form fields don't end up with the same name and Django knows how to intelligently handle the multiple submissions.

https://docs.djangoproject.com/en/1.7/topics/forms/formsets/

-James

Eric Abrahamsen

unread,
Jan 17, 2015, 5:04:33 AM1/17/15
to django...@googlegroups.com
Kakar Nyori <nyori...@gmail.com> writes:

> When doing so, only the last pform is gets saved. And the other two
> pforms are ignored. How do I get to save all the three forms of photo
> (pforms) accordingly?
>
> Or is there any other way around? Your help will be much appreciated!
> Thank you.

James is right that a formset is probably the best solution. If for some
reason you actually need three separate forms, you can use different
"prefix" arguments to the separate forms. See:

http://stackoverflow.com/questions/17421981/django-form-prefix-vs-form-set

Reply all
Reply to author
Forward
0 new messages