Three Django forms in different tabs in one template?

3,426 views
Skip to first unread message

Stodge

unread,
Sep 13, 2010, 11:48:21 AM9/13/10
to Django users
I'm working through a nice little feature for my website that will
bring all user editable preferences/profile options together into a
single web page using tabs. I have the tabs working and I can display
a different Django form on each tab but I'm confused how to tie it all
together using a view.

Typically each form would be on a separate page using different views.
But how would I support say three forms on one page (in three tabs)? I
need one view to generate all of the tabs but one view can't support
three forms? What's the best way to implement this?

Should I have three views to handle the POST requests for the three
forms and then a reusable function that renders the template?

Thanks

bruno desthuilliers

unread,
Sep 13, 2010, 12:13:22 PM9/13/10
to Django users
On 13 sep, 13:48, Stodge <sto...@gmail.com> wrote:
> I'm working through a nice little feature for my website that will
> bring all user editable preferences/profile options together into a
> single web page using tabs. I have the tabs working and I can display
> a different Django form on each tab but I'm confused how to tie it all
> together using a view.
>
> Typically each form would be on a separate page using different views.
> But how would I support say three forms on one page (in three tabs)? I
> need one view to generate all of the tabs but one view can't support
> three forms?

Yes it does. You just need to have a way to know wich form was
actually submitted.

> What's the best way to implement this?

The simplest way is to add an hidden field in each form, with a value
identyfing the form. Then in your view you just have to select the
appropriate form class based on this identifier (using a
identifier:form_class dict being the obvious solution).

Stodge

unread,
Sep 13, 2010, 12:24:33 PM9/13/10
to Django users
Ah cunning! Thanks - that's a great idea.

On Sep 13, 8:13 am, bruno desthuilliers

David De La Harpe Golden

unread,
Sep 13, 2010, 12:30:29 PM9/13/10
to django...@googlegroups.com
On 13/09/10 12:48, Stodge wrote:


> one view can't support
> three forms?

Uh, it certainly can if you want to write it that way: Multiple django
"form" objects can validate different parts of some request.POST
dataset, you're not limited to one post one form. You can even use
multiple instances of the same form (with different prefixes, but see
also "formsets", no need to reinvent the wheel there either)

Telling which one to actually use could just be a matter of the name of
the submit field used (beware breakage on ancient IE - in certain
situations it presented the submit field value where the standard was to
present the name or something like that, but that's now in the distant
and horrible past for most people), or a hidden field.

> What's the best way to implement this?

That depends, probably. If you're already invested in ajaxy stuff, then
it probably _is_ most manageable to make three separate views, and embed
them into tabs in a page returned by a fourth simple view. That would
be straightforward with e.g. jquery-ui's tabs (and presumably several
other javascript frameworks').

In the jquery case, you could consider the e.g. the very handy
jquery-form [1] plugin to convert your form posts to ajax requests.

[1] http://jquery.malsup.com/form/


Faridul Islam

unread,
Oct 24, 2013, 6:56:29 PM10/24/13
to django...@googlegroups.com
Hello Stodge,
 
I was searching for an example of mutli-tab pages within a single view using Django and found your post which almost three years old. I am not sure whether you still work with Django or not. If you do, I will appreciate if you can share one example of it with me. FYI, this is my first time working with Django.
 
Thanks.

Joey Chang

unread,
Oct 25, 2013, 2:25:08 AM10/25/13
to django...@googlegroups.com
I think you can try to use a base view to handle the request and distribute to sub functions. like:

def base_view(request):
    form_type = request.REQUEST.get("form_type", "1")
    if form_type == "1":
        result = sub_view1(request)
    ...
    else:
        result = sub_viewn(request)

    return http_response_obj

def sub_view1(request):
    ...
    return {"form": form1, "other_param": other}

def sub_viewn(request):
    ....

the `result` contains the `form` what the particular template form needs.
And the sub view has the `request`, so you can do almost everything like real `view`.



2013/10/25 Faridul Islam <faridul....@gmail.com>

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/bc38f4c1-0534-4adf-afd7-e53b9715b3bb%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Franco H

unread,
Sep 11, 2014, 1:59:31 PM9/11/14
to django...@googlegroups.com
Hi im from Argentina im in the same situation, do u find a answer? can u shared it with me?

Andrew Pinkham

unread,
Sep 11, 2014, 6:11:56 PM9/11/14
to django...@googlegroups.com
Hi Franco, Faridul, Stodge,

There are actually quite a few problems being asked. I've split them up into discrete questions.

1. Can a single view function print three forms in a template?

Yes.

WARNING: I am coding all of this off the top of my head. The code is likely riddled with typos and errors. Sorry. Hopefully the example will demonstrate enough of the idea.

# VIEW FUNCTION
# Start by invoking the forms you want
# remember to pass POST or initial data if necessary
form1 = FormClassOne()
# etc for as many forms as you'd like.

# Create a Context or Request Context
c = Context({"foo": [form1, form2, form3]})

# or, more easily, use the `render` shortcut
render(
request,
template_name_vsr,
{'forms' : [form1, form2, form3]})

# TEMPLATE
<div id="tabs-set">
{% for form in forms %}
<div class="tab">
<form action="{# this depends on the next answers! #}" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
</div>
{% endfor %}
</div>

2. How should I handle the submission process (POST data)? With one view function, or with three view functions?

Both are valid ways of doing it, but I heavily favor the method with three POST processing views. The reason is that by combining all this logic in one location, you are increasing the complexity of your site drastically. Debugging that will be no fun in the event of a problem. Having a place where the forms are as simple as possible is quite desirable. Remember to write tests.

I would recommend starting with the three view method, and then moving into the single view function method, if so desired.

3. How do I program three view functions to handle POST requests from forms in a single view function?

Start by creating a basic view function that handles both the GET (display of form) and POST (submission of data) for all of the forms (just as you would regularly). A Generic Class Based View might be all you need here, but it might be wise to start with a simple Class Based View.

Now, simply point the forms above to these webpage urls. There are many ways to do this. I would consider: (1) adding the action URL to the form class as an instance variable, or else (2) simply building the URL in the single form view and passing it to the URL.

Note: you may have/want to account for the URL referring to these forms. I am fuzzy on the details

Consider that having a separate view/page for each form will help debug any issues, as you have a place where the complexity of the form/view is as low as possible.

4. How do I program a single view function to handle POST requests from all three forms?

The first problem is that you need to know which form has been submitted from the single view page. Using a hidden form field may provide that information, or checking the keys of the POST querydict may also work. However, in both cases, you are relying on information provided by the user, which is a Bad Idea. This is the biggest reason not to follow this method.

However, once you know which form is being submitted, you may then process it according to the rules set forth in the three views your previously programmed. Remember to adhere to DRY (ie: split the functionality into small, reusable pieces)!

I realize that's a lot of info, but again, there was quite a lot being asked. I hope that helps clarify the issue.

Andrew

Mario Gudelj

unread,
Sep 11, 2014, 7:34:05 PM9/11/14
to django...@googlegroups.com
K. Another option would be to render all the forms in GET and then use Ajax and 3 different views to process POST requests from those forms.

Or you can add different values to each of the form's submit button and check which form form is being submitted by that value. That's if you want to use the same view to process all 3 forms. Example:

if request.method == "POST":
        if request.POST['submit_button_name'] == "Submit Button Value":


--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
Reply all
Reply to author
Forward
0 new messages