ploo
ploo

Reputation: 667

Redirecting after saving form on Django

I am working on extending the webapp we're left off with after completing the official Django Tutorial.

One of the functionalities I am looking to add is the ability for users to add polls themselves.

I am struggling with getting the page to process the data and then redirect to the index page ('/polls').

When I submit a new poll as a logged in user, I am returned to my index page, which is supposed to show most recently published polls, or in the event of no polls, the message "No polls are available."

For some reason, I always see "No polls are available", but once I click to the index page via a link on the site, it displays all of my polls, including my most recently created one, data intact!

Any thoughts here? I think I have included the relevant info below but happy to supply more. Thanks in advance for any help/advice.

views.py

class IndexView(generic.ListView):
    template_name = 'polls/index.html'
    context_object_name = 'latest_question_list'

    def get_queryset(self):
        """Return the last five published questions."""
        return Poll.objects.order_by('-pub_date')[:15]

@login_required
def add_poll(request):
    ChoiceFormSet = formset_factory(ChoiceForm, extra=3, min_num=2, validate_min=2)

    if request.method == 'POST':
        form = PollForm(request.POST)
        formset = ChoiceFormSet(request.POST)
        if all([form.is_valid(), formset.is_valid()]):
            poll = form.save()
            for inline_form in formset:
                if inline_form.cleaned_data:
                    choice = inline_form.save(commit=False)
                    choice.question = poll
                    choice.save()
            return render(request, 'polls/index.html', {})
    else:
        form = PollForm()
        formset = ChoiceFormSet()

    return render(request, 'polls/add_poll.html', {'form': form, 'formset': formset})

add_poll.html

{% extends 'polls/base.html' %}

{% block title %}Add Poll{% endblock %}

{% block body_block %}
<form role="form"  id="poll_form" method="post" action="{% url 'polls:add_poll' %}">
<h2 class="form-signin-heading">Add a Poll</h2>

  {% csrf_token %}

  <table>
    {{ form }}
    {{ formset }}
  </table>

<br/>

<button class="btn btn-primary" type="submit" name="submit">Create Poll</button>

</form>

{% endblock %}

index.html

{% extends 'polls/base.html' %}

{% block body_block %}
{% if latest_question_list %}
<ul>
  {% for poll in latest_question_list %}
  <li><a href="{% url 'polls:detail' poll.id %}">{{ poll.question_text }}</a></li>
  {% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
{% endblock %}

urls.py

from django.conf.urls import patterns, url

from . import views

urlpatterns = patterns('',
    url(r'^$', views.IndexView.as_view(), name='index'),
    url(r'^(?P<pk>\d+)/$', views.DetailView.as_view(), name='detail'),
    url(r'^(?P<pk>\d+)/results/$', views.ResultsView.as_view(), name='results'),
    url(r'^add_poll/$', views.add_poll, name='add_poll'),
    url(r'^(?P<question_id>\d+)/vote/$', views.vote, name='vote'),
    url(r'^profile_page/$', views.ProfileView.as_view(), name='profile_page'),
    url(r'^edit_profile/$', views.edit_profile, name='edit_profile'),
)

Upvotes: 7

Views: 16340

Answers (3)

Todor
Todor

Reputation: 16050

When you save your form you are not redirecting.

Your are returning 'polls/index.html' with empty polls data, that's why you always get "No polls are available". But this is very incorrect, you must follow the Post/Redirect/Get (PRG) pattern, so instead of:

return render(request, 'polls/index.html', {})

do this:

return HttpResponseRedirect(reverse('polls:index'))

Upvotes: 12

Mphoza
Mphoza

Reputation: 117

I finally figured it out. I had to change my html form to this:

<form method="POST" action="{% url 'new_beam:beam_diagram' beam_id=1 %}" enctype="multipart/form-data">

Upvotes: 1

Serafeim
Serafeim

Reputation: 15104

You don't do any redirect right now, you are just rendering your index template with an empty context (that's why you don't see anything). To redirect, you need to use HttpResponseRedirect when your form is valid.

So, please change line:

return render(request, 'polls/index.html', {})

(just over the else) to

return HttpResponseRedirect(reverse('index'))

Upvotes: 1

Related Questions