Home > nicar2011

nicar2011

Nicar2011 is a project mainly written in ..., it's free.

An example Django app

 ______  _____  ______  ______   ______    2011
| |     | |  | |     | |  | | | |  |        
| |  | |  | |  | |     | |__| | | |__| |       
|_|  |_| _|_|_ |_|____ |_|  |_| |_|  _       

A example Django app, by "Aron Pilhofer":http://github.com/pilhofer.

h3. Instructions

Create your Django project

$ django-admin.py startproject nicar2011

Start it up for the first time

$ cd nicar2011
$ python manage.py runserver

Set your database connection and syncdb

In settings.py...

DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = 'nicar2011.db'

Then back on the shell...

$ python manage.py syncdb

Create an application, call it polls

$ python manage.py startapp polls

Define two models in models.py

class Project(models.Model):
    title = models.CharField(max_length=200)
    pub_date = models.DateTimeField('date published')
    active_flag = models.BooleanField()

class Vote(models.Model):
    project = models.ForeignKey(Project)
    choice = models.IntegerField()
    

Add line to settings.py as an installed app

'polls',

Sync your db again

$ python manage.py syncdb

Add a string representation of your object to the model Project in models.py

def __unicode__(self):
    return self.title

Add your app to settings.py in INSTALLED_APPS

'django.contrib.admin',

Sync db to create admin tables

$ python manage.py syncdb

Enable admin. in urls.py by uncommenting the following

from django.contrib import admin
admin.autodiscover()

...and...

(r'^admin/', include(admin.site.urls)),

Fire up the server, and log in at http://localhost:8000/admin/

$ python manage.py runserver

Add your app to the admin. create a file called admin.py in your project (make joke about conventions), and add:

from polls.models import Project
from django.contrib import admin

admin.site.register(Project)

Add vote to the admin.py file so we can see associations

from polls.models import Vote
admin.site.register(Vote)

Configure your templates and dump the urls for our app into urls.py

First add this to settings.py

import os
settings_dir = os.path.dirname(__file__)
STATIC_DOC_ROOT = os.path.join(settings_dir, 'media')
TEMPLATE_DIRS = (
    os.path.join(settings_dir, 'templates'),
)

Then replace all of urls.py with the following

from django.conf.urls.defaults import *
from django.conf import settings
from django.contrib import admin
admin.autodiscover()

urlpatterns = patterns('',
    (r'^admin/', include(admin.site.urls)),
    (r'^polls/$', 'polls.views.index'),
    (r'^polls/(?Pd+)/$', 'polls.views.detail'),
    (r'^polls/(?Pd+)/vote/$', 'polls.views.vote'),
    (r'^polls/(?Pd+)/data.xml$', 'polls.views.data'),
    (r'^crossdomain.xml$', 'polls.views.crossdomain'),
    (r'^local-media/(?P.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_DOC_ROOT }),
)

Create a view. in views.py

from django.http import HttpResponse

def index(request):
    return HttpResponse("Hello, world. You're at the poll index.")

Add a new method to your views.py, to see how django passes parameters

def detail(request, poll_id):
    return HttpResponse("You're looking at poll %s." % poll_id)

Add a bunch of stuff up at the top of views.py we will need later

from django.shortcuts import get_object_or_404, render_to_response
from polls.models import Project, Vote
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse
from django.db.models import Sum

In our views.py, let's change our index view to pull some real data

def index(request):
    projects = Project.objects.all().order_by('-pub_date')[:5]
    return render_to_response('polls/index.html', {'projects': projects})

Create an index.html file

{% if projects %}
    
    {% for project in projects %}
  • {{ project.title }}
  • {% endfor %}
{% else %}

No projects are available.

{% endif %}

Tweak our details method in views.py

def detail(request, poll_id):
    p = Project.objects.get(pk=poll_id)
    total = p.vote_set.count()
    return render_to_response('polls/detail.html', {'project': p, 'vote_total': total, })

Add a votes method to views.py

def vote(request, poll_id):
    p = get_object_or_404(Project, pk=poll_id)
    v = p.vote_set.create(choice = request.POST['data'])
    v.save()
    return HttpResponse(status=200)

Add a data method to views.py

def data(request, poll_id):
    p = Project.objects.get(pk=poll_id)
    total = p.vote_set.aggregate(Sum('choice'))
    return render_to_response('polls/data.xml', {'project': p, 'vote_total': total['choice__sum'], }, mimetype="text/xml")

Create a data.xml file



{{ project }}
{{ vote_total }}

Create a crossdomain.xml method

def crossdomain(request):
    return HttpResponse('', mimetype="text/xml")

Create a detail.html template where it all comes together

<div align="center" class="left">
    <object type="application/x-shockwave-flash" data="/local-media/voteinator.swf" width="592" height="333">
        <param name="movie" value="/local-media/voteinator.swf"/>
        <param name="FlashVars" value="xml_path=http://localhost:8000/polls/{{ project.id }}/data.xml&post_path=http://localhost:8000/polls/{{ project.id }}/vote/"/>
        <param name="bgcolor" value="#FFFFFF"/>
        <param name="allowScriptAccess" value="always"/>
        <param name="allowFullScreen" value="true"/>
        <param name="wmode" value="opaque"/>
        <embed src="/local-media/voteinator.swf" FlashVars="xml_path=http://localhost:8000/polls/{{ project.id }}/data.xml&post_path=http://localhost:8000/polls/{{ project.id }}/vote/" bgcolor="#FFFFFF" width="592" height="333" wmode="opaque" allowScriptAccess="always" allowFullScreen="true" type="application/x-shockwave-flash"></embed>
    </object>
</div>

Download votinator.swf and put in in the "media" directory

https://github.com/palewire/nicar2011/blob/master/nicar2011/media/voteinator.swf

Extra credit... it votes up, but not down. how to fix?

def vote(request, poll_id):
    p = get_object_or_404(Project, pk=poll_id)
    if request.POST['data'] == "0":
        value = -1
    else:
        value = 1
    v = p.vote_set.create(choice = value)
    v.save()
    return HttpResponse(status=200)