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'),
)
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.
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.
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/ .
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.
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'))
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'))
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">
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With