msampaio
msampaio

Reputation: 3433

Multiple views call and template inclusion

I'd like to create a form to insert in multiple pages. In the example below I created a template "form.html" and tried to input in "index.html". I already have a view for index (simplified in this example). Thus, I don't know how to call myform view to include the form in index.

# urls.py
urlpatterns = patterns('',
    url(r'^$', 'index'),
    url(r'^form$', 'myform'),
)

# views.py
def index(request):
    return render(request, 'index.html')

def myform(request):
    if request.method == "POST":
        form = MyForm(request.POST)
        if form.is_valid():
            request.session['name'] = form.cleaned_data['name']
            return HttpResponseRedirect('/form')
    else:
        form = MyForm()

    args = {'form': form}
    return render(request, 'form.html', {'form': form})

# form.html
<form action="/form/ok" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>

# index.html
....
{% include "form.html" %}
....

Upvotes: 0

Views: 592

Answers (2)

msampaio
msampaio

Reputation: 3433

This is an expansion of @rockingskier's answer. I changed myform view to return the variable form and called it in the index view.

# urls.py
urlpatterns = patterns('',
    url(r'^$', 'index'),
)

# views.py
def myform(request):
    if request.method == "POST":
        form = MyForm(request.POST)
        if form.is_valid():
            request.session['name'] = form.cleaned_data['name']
            return HttpResponseRedirect('/ok')
    else:
        form = MyForm()

    return form

def index(request):
    args['form'] = myform
    return render(request, 'index.html')

Upvotes: 1

rockingskier
rockingskier

Reputation: 9346

{% include %}ing is a way including additional html in your template. It does not route the user through various different views

In your code the user will come into index and be given index.html. index.html will then {% include %} the contents of form.html inside itself but have nothing to do with the myform view. Within form.html the template will expect a variable called form. form has not been set in this context as it is not created in index and thus no form contents will get rendered. (The tags will be as they are not dependant on the form variable).

All variables should be set within the view you are using. As such you need to create a form object and pass it all within index. At that point form.html within index.html will receive the form variable it is expecting.

If you decide that in index you do not wish to call your form form (say you have multiple forms so want more helpful names). Then you can {% including "form.html" with form=form_variable_from_index %}. This will essentially rename the form variable but only within that `{% include %}'d file.

https://docs.djangoproject.com/en/1.4/ref/templates/builtins/#include

# views.py
def index(request):

    # Need to create the form here
    form = MyForm()

    args = {'form': form}
    return render(request, 'form.html', args)

def myform(request):
    if request.method == "POST":
        form = MyForm(request.POST)
        if form.is_valid():
            request.session['name'] = form.cleaned_data['name']
            return HttpResponseRedirect('/form')
    else:
        form = MyForm()

    args = {'form': form}
    return render(request, 'form.html', args)

Views know about the one template they reference. Templates have no idea about views, just the context/variables you hand them.

Upvotes: 3

Related Questions