Skip to content

Commit a71690e

Browse files
author
niekas
committed
Merge pull request #49 from python-dirbtuves/voting-poll
This closes #44 and closes #45.
2 parents 9e15f29 + 8dacaf3 commit a71690e

20 files changed

Lines changed: 392 additions & 11 deletions

config/assets.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ hash-name = false
1212

1313
[bootstrap]
1414
recipe = hexagonit.recipe.download
15-
url = https://github.com/twbs/bootstrap/releases/download/v3.3.1/bootstrap-3.3.1-dist.zip
15+
url = https://github.com/twbs/bootstrap/releases/download/v3.3.5/bootstrap-3.3.5-dist.zip
1616
hash-name = false
1717
strip-top-level-dir = true
1818

pylab/core/migrations/0001_initial.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class Migration(migrations.Migration):
1212

1313
dependencies = [
1414
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
15+
('website', '0002_auto_20150728_0303'),
1516
]
1617

1718
operations = [
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# -*- coding: utf-8 -*-
2+
from __future__ import unicode_literals
3+
4+
from django.db import models, migrations
5+
from django.conf import settings
6+
import django_extensions.db.fields
7+
import django.utils.timezone
8+
import autoslug.fields
9+
10+
11+
class Migration(migrations.Migration):
12+
13+
dependencies = [
14+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
15+
('core', '0005_auto_20150730_0231'),
16+
]
17+
18+
operations = [
19+
migrations.CreateModel(
20+
name='Vote',
21+
fields=[
22+
('id', models.AutoField(serialize=False, verbose_name='ID', primary_key=True, auto_created=True)),
23+
('created', django_extensions.db.fields.CreationDateTimeField(editable=False, default=django.utils.timezone.now, blank=True)),
24+
('modified', django_extensions.db.fields.ModificationDateTimeField(editable=False, default=django.utils.timezone.now, blank=True)),
25+
('vote_time', models.DateTimeField(null=True)),
26+
('points', models.IntegerField(verbose_name='Points', null=True)),
27+
('project', models.ForeignKey(to='core.Project')),
28+
('voter', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
29+
],
30+
),
31+
migrations.CreateModel(
32+
name='VotingPoll',
33+
fields=[
34+
('id', models.AutoField(serialize=False, verbose_name='ID', primary_key=True, auto_created=True)),
35+
('created', django_extensions.db.fields.CreationDateTimeField(editable=False, default=django.utils.timezone.now, blank=True)),
36+
('modified', django_extensions.db.fields.ModificationDateTimeField(editable=False, default=django.utils.timezone.now, blank=True)),
37+
('slug', autoslug.fields.AutoSlugField(editable=False)),
38+
('title', models.CharField(verbose_name='Title', max_length=255)),
39+
('description', models.TextField(blank=True, verbose_name='Description')),
40+
('author', models.ForeignKey(to=settings.AUTH_USER_MODEL)),
41+
],
42+
),
43+
migrations.AddField(
44+
model_name='vote',
45+
name='voting_poll',
46+
field=models.ForeignKey(to='core.VotingPoll'),
47+
),
48+
]
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# -*- coding: utf-8 -*-
2+
from __future__ import unicode_literals
3+
4+
from django.db import models, migrations
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('core', '0006_auto_20150806_0437'),
11+
]
12+
13+
operations = [
14+
migrations.AlterField(
15+
model_name='vote',
16+
name='points',
17+
field=models.PositiveIntegerField(verbose_name='Points', null=True, blank=True),
18+
),
19+
]
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# -*- coding: utf-8 -*-
2+
from __future__ import unicode_literals
3+
4+
from django.db import models, migrations
5+
6+
7+
class Migration(migrations.Migration):
8+
9+
dependencies = [
10+
('core', '0007_auto_20150808_1812'),
11+
]
12+
13+
operations = [
14+
migrations.RenameField(
15+
model_name='vote',
16+
old_name='vote_time',
17+
new_name='voted',
18+
),
19+
]

pylab/core/models.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,28 @@ def __str__(self):
5656

5757
def get_absolute_url(self):
5858
return reverse('event-details', args=[self.starts.year, self.starts.month, self.starts.day, self.slug])
59+
60+
61+
class VotingPoll(models.Model):
62+
created = CreationDateTimeField()
63+
modified = ModificationDateTimeField()
64+
author = models.ForeignKey(User)
65+
slug = AutoSlugField(populate_from='title')
66+
title = models.CharField(_("Title"), max_length=255)
67+
description = models.TextField(_("Description"), blank=True)
68+
69+
def __str__(self):
70+
return self.title
71+
72+
73+
class Vote(models.Model):
74+
created = CreationDateTimeField()
75+
modified = ModificationDateTimeField()
76+
voted = models.DateTimeField(null=True)
77+
voting_poll = models.ForeignKey(VotingPoll)
78+
voter = models.ForeignKey(User)
79+
project = models.ForeignKey(Project)
80+
points = models.PositiveIntegerField(_("Points"), null=True, blank=True)
81+
82+
def __str__(self):
83+
return '%s, %s' % (self.voting_poll.title, self.voter.get_full_name() or self.voter.get_username())

pylab/website/admin.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
import allauth.socialaccount.admin as allauth
1212

13-
from pylab.core.models import Project, Event
13+
import pylab.core.models as core_models
1414

1515

1616
class AdminSite(admin.AdminSite):
@@ -50,8 +50,10 @@ def get_changeform_initial_data(self, request):
5050
site = AdminSite()
5151

5252
site.register(auth_models.User, auth_admin.UserAdmin)
53-
site.register(Project)
54-
site.register(Event, EventAdmin)
53+
54+
site.register(core_models.Project)
55+
site.register(core_models.Event, EventAdmin)
56+
site.register(core_models.VotingPoll)
5557

5658
site.register(allauth.SocialApp, allauth.SocialAppAdmin)
5759
site.register(allauth.SocialToken, allauth.SocialTokenAdmin)

pylab/website/forms.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1+
import datetime
2+
13
from django import forms
4+
from django.forms.models import BaseModelFormSet
25
from django.utils.translation import ugettext
36
from django.utils.translation import ugettext_lazy as _
47

5-
from pylab.core.models import Project, Event
8+
from pylab.core.models import Project, Event, Vote
69

710

811
class ProjectForm(forms.ModelForm):
@@ -49,3 +52,32 @@ def clean(self):
4952

5053
if title and starts:
5154
self.check_existing_events(title, starts)
55+
56+
57+
class VotePointsForm(forms.ModelForm):
58+
class Meta:
59+
model = Vote
60+
fields = ('points',)
61+
widgets = {
62+
'points': forms.NumberInput(attrs={'max': 99, 'class': 'vote-points-input'}),
63+
}
64+
65+
def save(self, commit=True, *args, **kwargs):
66+
vote = super(VotePointsForm, self).save(commit=False, *args, **kwargs)
67+
vote.voted = datetime.datetime.now()
68+
vote.save()
69+
70+
71+
class BaseTotalPointsFormset(BaseModelFormSet):
72+
def clean(self, *args, **kwargs):
73+
super(BaseTotalPointsFormset, self).clean(*args, **kwargs)
74+
total_points = 0
75+
76+
for form in self.forms:
77+
if form.cleaned_data['points']:
78+
total_points += form.cleaned_data['points']
79+
80+
if total_points < 0 or total_points > 15:
81+
raise forms.ValidationError(ugettext(
82+
"Sum of voting points is out of bounds. Expected from 0 to 15, but got %s."
83+
) % total_points)

pylab/website/models.py

Whitespace-only changes.

pylab/website/static/css/main.scss

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,23 @@
5050
.event-time {
5151
padding-left: 16px;
5252
}
53+
54+
.vote-points-input {
55+
width: 38px;
56+
text-align: right;
57+
font-weight: bold;
58+
}
59+
60+
.vote-points-form {
61+
padding-top: 10px;
62+
padding-left: 30px;
63+
padding-bottom: 30px;
64+
}
65+
66+
.vote-button {
67+
margin-top: 15px;
68+
}
69+
70+
#total-points {
71+
display: none;
72+
}

0 commit comments

Comments
 (0)