annotate polls/views.py @ 1090:71685387dd11

Reduce database usage on poll index page.
author Brian Neal <bgneal@gmail.com>
date Mon, 09 May 2016 19:48:51 -0500
parents ee87ea74d46b
children f7554fb88727
rev   line source
bgneal@439 1 """
bgneal@439 2 Views for the polls application.
gremmie@1 3
bgneal@439 4 """
bgneal@447 5 import datetime
bgneal@447 6
bgneal@439 7 from django.shortcuts import render
gremmie@1 8 from django.contrib.auth.decorators import login_required
gremmie@1 9 from django.shortcuts import get_object_or_404
gremmie@1 10 from django.http import Http404
gremmie@1 11 from django.http import HttpResponseRedirect
gremmie@1 12 from django.core.urlresolvers import reverse
bgneal@439 13 from django.views.decorators.http import require_POST
bgneal@439 14 from django.db.models import F
gremmie@1 15
gremmie@1 16 from polls.models import Poll
gremmie@1 17 from polls.models import Choice
gremmie@1 18 from polls.forms import VoteForm
gremmie@1 19
gremmie@1 20 #######################################################################
gremmie@1 21
bgneal@439 22 def get_user_choice(user, poll):
bgneal@439 23 """
bgneal@447 24 Return the Choice object the given user voted for from the given poll,
bgneal@447 25 or None if no vote has been recorded (or the user is not authenticated.
bgneal@439 26
bgneal@439 27 """
bgneal@439 28 user_choice = None
bgneal@439 29 if user.is_authenticated():
bgneal@439 30 user_choices = user.choice_set.filter(poll=poll)
bgneal@439 31 if user_choices:
bgneal@439 32 user_choice = user_choices[0]
bgneal@439 33
bgneal@439 34 return user_choice
bgneal@439 35
bgneal@439 36 #######################################################################
bgneal@439 37
gremmie@1 38 def poll_index(request):
bgneal@1090 39
bgneal@1090 40 # Do some stuff manually to avoid cascading hits to the database
bgneal@1090 41 now = datetime.datetime.now()
bgneal@1090 42 qs = Poll.objects.filter(is_enabled=True)
bgneal@1090 43 poll_dict = {}
bgneal@1090 44 current_polls = []
bgneal@1090 45 old_polls = []
bgneal@1090 46 for poll in qs:
bgneal@1090 47 poll.total_votes_ = 0
bgneal@1090 48 poll_dict[poll.pk] = poll
bgneal@1090 49 if (poll.start_date <= now and
bgneal@1090 50 (poll.end_date is None or poll.end_date >= now)):
bgneal@1090 51 current_polls.append(poll)
bgneal@1090 52 elif (poll.start_date < now and
bgneal@1090 53 (poll.end_date is not None and poll.end_date < now)):
bgneal@1090 54 old_polls.append(poll)
bgneal@1090 55
bgneal@1090 56 for choice in Choice.objects.iterator():
bgneal@1090 57 poll = poll_dict.get(choice.poll_id)
bgneal@1090 58 if poll:
bgneal@1090 59 poll.total_votes_ += choice.votes
bgneal@1090 60
bgneal@439 61 return render(request, 'polls/index.html', {
bgneal@439 62 'current_polls': current_polls,
bgneal@439 63 'old_polls': old_polls,
bgneal@439 64 })
gremmie@1 65
gremmie@1 66 #######################################################################
gremmie@1 67
gremmie@1 68 def poll_detail(request, poll_id):
bgneal@439 69 poll = get_object_or_404(Poll, pk=poll_id)
bgneal@447 70 if not poll.is_enabled or poll.start_date > datetime.datetime.now():
bgneal@439 71 raise Http404
gremmie@1 72
bgneal@447 73 total_votes, choices = poll.results()
bgneal@447 74
bgneal@447 75 return render(request, 'polls/poll_detail.html', {
bgneal@439 76 'poll': poll,
bgneal@447 77 'total_votes': total_votes,
bgneal@447 78 'choices': choices,
bgneal@439 79 'user_choice': get_user_choice(request.user, poll),
bgneal@439 80 })
gremmie@1 81
gremmie@1 82 #######################################################################
gremmie@1 83
gremmie@1 84 @login_required
gremmie@1 85 def poll_vote(request, poll_id):
bgneal@439 86 poll = get_object_or_404(Poll, pk=poll_id)
bgneal@439 87 if not poll.is_enabled:
bgneal@439 88 raise Http404
bgneal@439 89 if not poll.is_open():
bgneal@447 90 return HttpResponseRedirect(reverse('polls-detail',
bgneal@447 91 kwargs={'poll_id': poll_id}))
gremmie@1 92
bgneal@439 93 user_choice = get_user_choice(request.user, poll)
gremmie@1 94
bgneal@439 95 if request.method == "POST":
bgneal@447 96 vote_form = VoteForm(poll, request.POST, user=request.user,
bgneal@447 97 user_choice=user_choice)
bgneal@439 98 if vote_form.is_valid():
bgneal@439 99 vote_form.save()
bgneal@447 100 return HttpResponseRedirect(reverse('polls-detail',
bgneal@447 101 kwargs={'poll_id': poll_id}))
bgneal@439 102 else:
bgneal@439 103 vote_form = VoteForm(poll)
bgneal@439 104
bgneal@439 105 return render(request, 'polls/poll_vote.html', {
bgneal@439 106 'poll': poll,
bgneal@439 107 'vote_form': vote_form,
bgneal@439 108 'user_choice': user_choice,
bgneal@439 109 })
gremmie@1 110
gremmie@1 111 #######################################################################
gremmie@1 112
bgneal@439 113 @require_POST
bgneal@439 114 @login_required
bgneal@439 115 def poll_delete_vote(request):
bgneal@439 116 poll = get_object_or_404(Poll, pk=request.POST.get('poll_id'))
bgneal@439 117 user_choice = get_user_choice(request.user, poll)
bgneal@439 118 if user_choice:
bgneal@439 119 Choice.objects.filter(id=user_choice.id).update(votes=F('votes') - 1)
bgneal@439 120 user_choice.voters.remove(request.user)
bgneal@439 121
bgneal@447 122 return HttpResponseRedirect(reverse('polls-detail', kwargs={'poll_id': poll.id}))