Commit 65a56743 authored by chris's avatar chris

Serlize results for faster retrieving.

parent c16ad5bb
from django.core.management.base import BaseCommand, CommandError
from meetingpoll.models import Poll
class Command(BaseCommand):
help = 'Compile results to jsonfield'
def handle(self, *args, **options):
for p in Poll.objects.all():
p.compile()
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding field 'Poll.result'
db.add_column(u'meetingpoll_poll', 'result',
self.gf('jsonfield.fields.JSONField')(default={}),
keep_default=False)
def backwards(self, orm):
# Deleting field 'Poll.result'
db.delete_column(u'meetingpoll_poll', 'result')
models = {
u'auth.group': {
'Meta': {'object_name': 'Group'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': u"orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
},
u'auth.permission': {
'Meta': {'ordering': "(u'content_type__app_label', u'content_type__model', u'codename')", 'unique_together': "((u'content_type', u'codename'),)", 'object_name': 'Permission'},
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['contenttypes.ContentType']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
},
u'auth.user': {
'Meta': {'object_name': 'User'},
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Group']"}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "u'user_set'", 'blank': 'True', 'to': u"orm['auth.Permission']"}),
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
},
u'contenttypes.contenttype': {
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
},
u'meetingpoll.bulletin': {
'Meta': {'object_name': 'Bulletin'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'poll': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['meetingpoll.Poll']"}),
'voter': ('django.db.models.fields.CharField', [], {'max_length': '40'})
},
u'meetingpoll.choice': {
'Meta': {'ordering': "['choice']", 'object_name': 'Choice'},
'choice': ('django.db.models.fields.DateTimeField', [], {}),
'details': ('django.db.models.fields.CharField', [], {'max_length': '200', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'poll': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['meetingpoll.Poll']"}),
'votecount': ('django.db.models.fields.IntegerField', [], {'default': '0', 'blank': 'True'})
},
u'meetingpoll.poll': {
'Meta': {'object_name': 'Poll'},
'description': ('django.db.models.fields.CharField', [], {'max_length': '300'}),
'id': ('django.db.models.fields.CharField', [], {'default': "'fNLPA'", 'max_length': '8', 'primary_key': 'True'}),
'pub_date': ('django.db.models.fields.DateField', [], {'default': 'datetime.datetime.now'}),
'result': ('jsonfield.fields.JSONField', [], {'default': '{}'}),
'title': ('django.db.models.fields.CharField', [], {'max_length': '80'}),
'upd_date': ('django.db.models.fields.DateField', [], {'auto_now': 'True', 'blank': 'True'}),
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['auth.User']", 'null': 'True'})
},
u'meetingpoll.userprofile': {
'Meta': {'object_name': 'UserProfile'},
'email_notifications': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'user': ('django.db.models.fields.related.OneToOneField', [], {'to': u"orm['auth.User']", 'unique': 'True'})
},
u'meetingpoll.vote': {
'Meta': {'ordering': "['choice']", 'object_name': 'Vote'},
'bulletin': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['meetingpoll.Bulletin']"}),
'choice': ('django.db.models.fields.related.ForeignKey', [], {'to': u"orm['meetingpoll.Choice']"}),
'comment': ('django.db.models.fields.CharField', [], {'max_length': '80', 'blank': 'True'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'voice': ('django.db.models.fields.BooleanField', [], {})
}
}
complete_apps = ['meetingpoll']
\ No newline at end of file
......@@ -8,7 +8,7 @@ from django.utils.translation import ugettext_lazy as _
import datetime
import string
import random
import jsonfield
def createId(length):
firstchar = string.ascii_letters
......@@ -45,6 +45,40 @@ class Poll(models.Model):
upd_date = models.DateField(auto_now=True)
description = models.CharField(max_length=300)
user = models.ForeignKey(User, null=True)
result = jsonfield.JSONField()
def compile(self):
self.result = {'voters': self.compile_voters(),
'choices': self.compile_choices()}
self.save()
def compile_voters(self):
'''Return a list of votes by voter'''
voters = []
for b in self.bulletin_set.all():
say = []
for c in self.choice_set.all():
try:
v = b.vote_set.get(choice=c)
say.append((v.voice, v.comment))
except:
say.append((None, None))
voters.append({b.voter: say})
return voters
def compile_choices(self):
'''Return a list of choices'''
choices = []
for c in self.choice_set.all():
t = 0
l = []
for v in c.vote_set.filter(choice=c):
if v.voice:
t += 1
if v.comment:
l.append([v.bulletin.voter, v.comment])
choices.append((c.choice, c.details, t, l))
return choices
def __unicode__(self):
return self.title
......
{% extends "base.html" %}
{% load url from future %}
{% load i18n %}
{% load bulletin_results %}
{% block menu %}
{% if has_voted %}
<a title=" {% trans 'Clear cookie, you will not be able to change your vote.' %} " href="{% url 'clearcookie' object.id %}">{% trans "Forget me" %}</a>
{% endif %}
<a title=" {% trans 'Export as csv spreadsheet' %} " href="{% url 'csv' object.id %}">{% trans "Export" %}</a>
{% endblock %}
{% block title %}nuages - {{object}}{% endblock %}
{% block main %}
<h1>{{object}}</h1>
<div>
<blockquote>
<p>{{object.description}}</p>
<small>{% trans "Posted by" %} <em>{% if object.user %}{{object.user}}{% else %}{% trans 'Anonymous' %}{% endif %}</em> {% trans "on" %} {{object.pub_date|date:"d F"}}.</small>
</blockquote>
</div>
<table class="bigtable">
<tr>
<td class='names'></td>
{% for choice in object.choice_set.all %}
<td class='cell-header'>{{ choice.choice|date:"d/m" }}<br />
<font class="grey">{{ choice.choice|date:'H:i' }}</font><br />
<span class="tip tip-header"><b> {{ choice.choice|date:'l d F'}} </b> <br />
{{ choice.choice|date:'H:i a'}} <br />
<font class="blue">{{ choice.details }} </font>
</span>
<div class="subl"><!-- --></div>
</td>
{% endfor %}
</tr>
{% for bulletin in object.bulletin_set.all %}
<tr >
<td class='names'>{{ bulletin.voter }}</td>
{% for vote in bulletin|bulletin_results:object.choice_set.all %}
<td class='cell'><div class="{{ vote.voice }}">{% if vote.comment %} <div class="msg"><!-- --></div><span class="tip"><font class="white">{{ vote.comment }}</font></span>{% endif %}</div></td>
{% endfor %}
</tr>
{% endfor %}
<tr>
<td class='names'></td>
{% for choice in object.choice_set.all %}
<td class='cell' title=" {{ choice }} ">{{ choice.votecount }}</td>
{% endfor %}
</tr>
<tr>
<form action="." method="post"> {% csrf_token %}
<td class='names' title=" Fill in your name ">
<div class="blue">{% trans "Your name:" %}</div>
{{ form.as_p }}
<input type="text" name="trap" style="display:none;"/>
</td>
{% for forms in vforms %}
{{ vforms.management_form }}
{% for form in forms %}
<td class='cell' title='{% trans " Check the little boxes to add positive answers " %}' />
{{ form.voice }} <br />
{{ form.comment }}
<div class="hide">
{{ form.choice }}
{% for hidden in form.hidden_fields %}{{ hidden }}{% endfor %}
</div>
{{ field.errors }}
</td>
{% endfor %}
{% endfor %}
</tr>
</table>
<br />
<h3>{% trans "Instructions" %}</h3>
<table class="instructions">
<tr>
<td>1. {% trans "Point columns to see choice details and comments" %} </td>
<td>2. {% trans "Check the boxes for positive answers. " %} {%trans "You may provide a comment for each choice." %}</td>
<td>3. <div style="text-align:center;"><input type="submit" value='{% trans "Vote" %}' class="btn btn-primary" /></td><td style="width:1px"></td>
</tr>
</table>
</form>
<br />
<h3>{% trans "Details" %}</h3>
{% for choice in object.choice_set.all %}
<p class="indent" id='info-{{ choice }}'>
<span class="da">{{ choice.choice|date:"l d F, H:i a"}} </span> -
<span class="blue">{{ choice.details }}</span>&nbsp; ({{ choice.votecount }})<br />
{% for bulletin in object.bulletin_set.all %}
{% for vote in bulletin.vote_set.all %}
{% ifequal choice vote.choice %}
{% if vote.comment %}
<span class="text-info">{{ bulletin.voter }}</span>: {{ vote.comment }} <br />
{% endif %}
{% endifequal %}
{% endfor %}
{% endfor %}
</p>
{% endfor %}
<!--[if lt IE 8]>
<script src="http://ie7-js.googlecode.com/svn/version/2.0(beta3)/IE8.js" type="text/javascript"></script>
<![endif]-->
{% endblock %}
{% block footer %}
<p><em>{{ object }}</em>
{% trans "Shared address" %} <a href="{{ object.link }}"> &rarr; {{ object.link }}</a></span></p>
{% endblock %}
......@@ -2,6 +2,7 @@
{% load url from future %}
{% load i18n %}
{% load bulletin_results %}
{% load parse_date %}
{% block menu %}
{% if has_voted %}
......@@ -13,6 +14,7 @@
{% block title %}nuages - {{object}}{% endblock %}
{% block main %}
{% with result=object.result %}
<h1>{{object}}</h1>
<div>
......@@ -24,31 +26,35 @@
<table class="bigtable">
<tr>
<td class='names'></td>
{% for choice in object.choice_set.all %}
<td class='cell-header'>{{ choice.choice|date:"d/m" }}<br />
<font class="grey">{{ choice.choice|date:'H:i' }}</font><br />
<span class="tip tip-header"><b> {{ choice.choice|date:'l d F'}} </b> <br />
{{ choice.choice|date:'H:i a'}} <br />
<font class="blue">{{ choice.details }} </font>
{% for choice, details, total, data in result.choices %}
{% with choice_p=choice|parse_date %}
<td class='cell-header'>{{ choice_p|date:"d/m" }}<br />
<font class="grey">{{ choice_p|date:'H:i' }}</font><br />
<span class="tip tip-header"><b> {{ choice_p|date:'l d F'}} </b> <br />
{{ choice_p|date:'H:i a'}} <br />
<font class="blue">{{ details }} </font>
</span>
<div class="subl"><!-- --></div>
</td>
{% endwith %}
{% endfor %}
</tr>
{% for bulletin in object.bulletin_set.all %}
{% for voterdict in result.voters %}
{% for voter, data in voterdict.iteritems %}
<tr >
<td class='names'>{{ bulletin.voter }}</td>
{% for vote in bulletin|bulletin_results:object.choice_set.all %}
<td class='cell'><div class="{{ vote.voice }}">{% if vote.comment %} <div class="msg"><!-- --></div><span class="tip"><font class="white">{{ vote.comment }}</font></span>{% endif %}</div></td>
<td class='names'>{{ voter }}</td>
{% for voice, comment in data %}
<td class='cell'><div class="{{ voice }}">{% if comment %} <div class="msg"><!-- --></div><span class="tip"><font class="white">{{ comment }}</font></span>{% endif %}</div></td>
{% endfor %}
</tr>
{% endfor %}
{% endfor %}
<tr>
<td class='names'></td>
{% for choice in object.choice_set.all %}
<td class='cell' title=" {{ choice }} ">{{ choice.votecount }}</td>
{% for choice, details, total, data in result.choices %}
<td class='cell' title=" {{ choice }} ">{{ total }}</td>
{% endfor %}
</tr>
......@@ -91,27 +97,21 @@
<br />
<h3>{% trans "Details" %}</h3>
{% for choice in object.choice_set.all %}
{% for choice, details, total, comments in result.choices %}
<p class="indent" id='info-{{ choice }}'>
<span class="da">{{ choice.choice|date:"l d F, H:i a"}} </span> -
<span class="blue">{{ choice.details }}</span>&nbsp; ({{ choice.votecount }})<br />
<span class="da">{{ choice|parse_date|date:"l d F, H:i a"}} </span> -
<span class="blue">{{ details }}</span>&nbsp; ({{ total }})<br />
{% for bulletin in object.bulletin_set.all %}
{% for vote in bulletin.vote_set.all %}
{% ifequal choice vote.choice %}
{% if vote.comment %}
<span class="text-info">{{ bulletin.voter }}</span>: {{ vote.comment }} <br />
{% endif %}
{% endifequal %}
{% endfor %}
{% for voter, comment in comments %}
<span class="text-info">{{ voter }}</span>: {{ comment }} <br />
{% endfor %}
</p>
{% endfor %}
<!--[if lt IE 8]>
<!--[if lt IE 8]>
<script src="http://ie7-js.googlecode.com/svn/version/2.0(beta3)/IE8.js" type="text/javascript"></script>
<![endif]-->
{% endwith %}
{% endblock %}
{% block footer %}
......
import datetime
from django.template import Library
from django.template.defaultfilters import stringfilter
register = Library()
@stringfilter
def parse_date(date_string, format="%Y-%m-%dT%H:%M:%S"):
"""
Return a datetime corresponding to date_string, parsed according to format.
For example, to re-display a date string in another format::
{{ "01/01/1970"|parse_date:"%m/%d/%Y"|date:"F jS, Y" }}
"""
try:
return datetime.datetime.strptime(date_string, format)
except ValueError:
return None
@stringfilter
def parse_date_fancy(date_string):
try:
return parse_date(date_string).strftime("%l %d %F, %H:%i %a")
except ValueError:
return None
register.filter(parse_date)
register.filter(parse_date_fancy)
......@@ -184,6 +184,8 @@ def vote(request, poll_id):
old.comment = vorm.cleaned_data['comment']
old.save()
is_updated = True
poll.compile()
if has_voted:
messages.success(request, _("Your vote has been counted, thank you."))
if is_updated:
......
......@@ -143,7 +143,7 @@ input:focus, textarea:focus {
.msg {
width: 4px;
height: 4px;
background-color: #fefeff;
background-color: #ffffff;
border: 1px solid #999;
border-radius: 3px;
border-radius: 3px;
......
......@@ -12,17 +12,17 @@
{% trans "Create polls easily, and publish them for your mates, in order to plan meetings and activities." %}
</p>
<p>
<a href="{% url 'new' %}" title='{% trans "Make an event" %}'>{% trans "Shedule an event" %}</a>
<a href="{% url 'new' %}" title='{% trans "Make an event" %}'>&#9999; {% trans "Shedule an event" %}</a>
</p>
</div>
<div class="indent">
</div>
<br />
<div >
<p>
{% trans "Examples" %}:
<a href="{% url 'meetingpoll' 'db3a' %}">Quand allons nous au potager?</a>
</p>
</div>
</div>
<br />
{% block userspecific %}
......
{% load i18n %}
{% load staticfiles %}
{% block main %}
{% load i18n %} {% load staticfiles %} {% block main %}
<div style="margin-left: 6px;">
<h2>{% trans "About Nuages" %}</h2>
......@@ -23,8 +20,8 @@
<div id="notify" class="span9 blue">
<ol> <span style="font-size:32px;">nuage</span>&nbsp; /ny.aʒ/<br /><br />
<h2>nuage</span>&nbsp; /ny.aʒ/</h2>
<ol>
<li> (Météorologie) Amas de gouttelettes d’eau maintenues en suspension dans l’atmosphère et qui se résolvent ordinairement en pluie.
<ul>
<li> La nuit était sombre, pas une étoile ne brillait au ciel, des nuages lourds et chargés de pluie glissaient au-dessus de la tête de nos voyageurs, comme les vagues d’une mer aérienne. — (Alexandre Dumas, Othon l’archer, 1839)</li>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment