1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect, Http404
from django.contrib.auth.decorators import login_required
from django.db import connection
from .models import Election, Member, Candidate, Vote
from .forms import VoteForm
from datetime import date, timedelta
def home(request):
elections = Election.objects.filter(isopen=True).order_by('startdate')
open_elections = [e for e in elections if e.startdate <= date.today() and e.enddate >= date.today()]
past_elections = [e for e in elections if e.startdate < date.today() and e.enddate < date.today()]
upcoming_elections = [e for e in elections if e.startdate > date.today()]
return render(request, 'elections/home.html', {
'open': open_elections,
'past': past_elections,
'upcoming': upcoming_elections,
})
def election(request, electionid):
election = get_object_or_404(Election, pk=electionid)
if not election.isopen:
raise Http404("This election is not open (yet)")
if election.startdate > date.today():
raise Http404("This election has not started yet")
if election.enddate < date.today():
# Election is closed, consider publishing the results
if not election.resultspublic:
# If user is an admin, show anyway, otherwise throw an error
if not request.user.is_superuser:
raise Http404("The results for this election aren't published yet.")
# Ok, so we do have the results. Use a custom query to make sure we get decently formatted data
# and no client-side ORM aggregation
curs = connection.cursor()
curs.execute("SELECT c.name, sum(v.score) AS score FROM elections_candidate c INNER JOIN elections_vote v ON c.id=v.candidate_id WHERE v.election_id=%(election)s AND c.election_id=%(election)s GROUP BY c.name ORDER BY 2 DESC", {
'election': election.pk,
})
res = curs.fetchall()
if len(res) == 0:
raise Http404('No results found for this election')
return render(request, 'elections/results.html', {
'election': election,
'topscore': res[0][1],
'scores': [{'name': r[0], 'score': r[1], 'width': 300 * r[1] // res[0][1]} for r in res],
})
if len(election.candidate_set.all()) <= 0:
raise Http404("This election has no candidates!")
# Otherwise, we show up the form. This part requires login
if not request.user.is_authenticated():
return HttpResponseRedirect("/login/?next=%s" % request.path)
try:
member = Member.objects.get(user=request.user)
# Make sure member has paid
if not member.paiduntil:
return render(request, 'elections/mustbemember.html', {})
# Make sure that the membership hasn't expired
if member.paiduntil < date.today():
return render(request, 'elections/mustbemember.html', {})
# Verify that the user has been a member for at least 28 days.
if member.membersince > election.startdate - timedelta(days=28):
return render(request, 'elections/memberfourweeks.html', {
'registered_at': member.paiduntil - timedelta(days=365),
'mustregbefore': election.startdate - timedelta(days=28),
'election': election,
})
except Member.DoesNotExist:
return render(request, 'elections/mustbemember.html', {})
if request.method == "POST":
form = VoteForm(election, member, data=request.POST)
if form.is_valid():
# Save the form
form.save()
else:
# Not a POST, so generate an empty form
form = VoteForm(election, member)
return render(request, 'elections/form.html', {
'form': form,
'election': election,
})
def candidate(request, election, candidate):
candidate = get_object_or_404(Candidate, election=election, pk=candidate)
return render(request, 'elections/candidate.html', {
'candidate': candidate,
})
@login_required
def ownvotes(request, electionid):
election = get_object_or_404(Election, pk=electionid)
if not election.isopen:
raise Http404("This election is not open (yet)")
if election.enddate >= date.today():
raise Http404("This election has not ended yet")
member = get_object_or_404(Member, user=request.user)
votes = Vote.objects.select_related().filter(voter=member, election=election).order_by('-score')
return render(request, 'elections/ownvotes.html', {
'election': election,
'votes': votes,
})
|