Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Redirecting after saving form on Django

Tags:

python

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'),
)
like image 681
ploo Avatar asked Mar 03 '15 20:03

ploo


People also ask

How do I redirect a form after a submission?

If you want to redirect to another page after form submit html, Then you have to provide/Sign the Other pages path inside HTML Form tag's ACTION Attribute. Which will POST/Send your Form data to that Location and Open/Redirect your Users to That Given Web Page.

How do I redirect in Django?

In Django, redirection is accomplished using the 'redirect' method. The 'redirect' method takes as argument: The URL you want to be redirected to as string A view's name. In the above example, first we imported redirect from django.

How do I redirect one page to another in Django?

Django Redirects: A Super Simple Example Just call redirect() with a URL in your view. It will return a HttpResponseRedirect class, which you then return from your view. Assuming this is the main urls.py of your Django project, the URL /redirect/ now redirects to /redirect-success/ .

What is reverse redirect in Django?

the actual reverse function is used for performing the reverse happen. This method will be responsible for getting the new url value reversed. With the reverse function the name of the redirect url has to be specified. The name of url value specified here will for the redirect url name from the url's.py file.


3 Answers

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'))
like image 113
Todor Avatar answered Sep 21 '22 22:09

Todor


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'))
like image 35
Serafeim Avatar answered Sep 17 '22 22:09

Serafeim


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">
like image 31
Mphoza Avatar answered Sep 18 '22 22:09

Mphoza