I made a simple blog and the django polls tutorial. Im trying to get them to work together. When I load a post, the poll associated with it loads, the Vote again works but when I click a choice and then the vote button, it loads the post with the id of the poll id. Im not sure if its my “vote” function in views, my “vote” url, or my template thats messed up? Here is my code:
models.py:
# Post class
class Post(models.Model):
title = models.CharField(max_length=60)
description = models.CharField(max_length=200)
body = models.TextField()
created = models.DateTimeField(auto_now_add=True)
def display_mySafeField(self):
return mark_safe(self.body)
def __unicode__(self):
return self.title
# Poll for the Post
class Poll(models.Model):
question = models.CharField(max_length=200)
total_votes = models.IntegerField(default=0)
post = models.ForeignKey(Post)
voted = models.BooleanField(default=False)
def __unicode__(self):
return self.question
# Choice for the poll
class Choice(models.Model):
poll = models.ForeignKey(Poll)
choice = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
percentage = models.DecimalField(default=0.0, max_digits=5, decimal_places=2)
def __unicode__(self):
return self.choice
urls.py:
urlpatterns = patterns('',
### main/index page
url(r'^$', 'blog.views.main', name='index'),
### url for the post.html
url(r'^post/(\d+)', 'blog.views.post'),
### polls
url(r'^polls/(\d+)/results/$', 'blog.views.results'),
url(r'^polls/(\d+)/vote/$', 'blog.views.vote'),
url(r'^revote/(\d+)/$', 'blog.views.vote_again'),
)
views.py:
# main view for the posts
def main(request):
posts = Post.objects.all().order_by("-created")
paginator = Paginator(posts, 5)
try: page = int(request.GET.get("page", '1'))
except ValueError: page = 1
try:
posts = paginator.page(page)
except (InvalidPage, EmptyPage):
posts = paginator.page(paginator.num_pages)
d = dict(posts=posts, user=request.user,
post_list=posts.object_list, months=mkmonth_lst())
return render_to_response("list.html", d)
def post(request, pk):
post = Post.objects.get(pk=int(pk))
comments = Comment.objects.filter(post=post)
try:
poll = Poll.objects.get(post=post)
except Poll.DoesNotExist:
poll = None
d = dict(post=post, comments=comments, form=CommentForm(), user=request.user,
months=mkmonth_lst(), poll=poll)
d.update(csrf(request))
return render_to_response("post.html", d)
#view to vote on the poll
def vote(request, post_id):
global choice
p = get_object_or_404(Poll, pk=post_id)
try:
selected_choice = p.choice_set.get(pk=request.POST['choice'])
except (KeyError, Choice.DoesNotExist):
# Redisplay the poll voting form.
return render_to_response('post.html', {
'poll': p,
'error_message': "You didn't select a choice.",
}, context_instance=RequestContext(request))
else:
selected_choice.votes += 1
p.total_votes += 1
selected_choice.save()
p.voted = True
p.save()
choices = list(p.choice_set.all())
for choice in choices:
percent = choice.votes*100/p.total_votes
choice.percentage = percent
choice.save()
return HttpResponseRedirect(reverse("blog.views.post", args=[post_id ]))
def vote_again(request, post_pk):
try:
p = get_object_or_404(Poll, post_id=post_pk)
except (KeyError, Poll.DoesNotExist):
pass
else:
p.voted = False
p.save()
return HttpResponseRedirect(reverse("blog.views.post", args=[post_pk]))
this is what is happening:
post1 - linked to - poll1
post2 - not linked
post3 - linked to - poll2
when I vote on poll2 which is linked to post3, it updates the database for poll2 but it reloads post2 instead of post3.
In your HTML form your action is set to
/polls/{{ poll.id }}/vote/. However, it’s looking for thepost.pkvalue, notpoll.pk. It uses that value to reload the page after committing the data. That should be your problem right there.EDIT