A guide, by Aron Pilhofer.
01. Create your Django project
django-admin.py startproject ire2010
02. Test it
python manage.py runserver
03. After you configure, syncdb
python manage.py syncdb
04. create an application, call it polls
python manage.py startapp polls
05. 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()
06. add line to settings.py as an installed app
'polls',
07. sync your db
python manage.py syncdb
08. add a string representation of your object to the model project
def __unicode__(self):
return self.title
09. add to settings.py as an installed app
django.contrib.admin
10. sync db
python manage.py syncdb
11. enable admin. in urls.py, uncomment
from django.contrib import admin
admin.autodiscover()
…and…
(r'^admin/', include(admin.site.urls)),
12. fire up the server, and log in
python manage.py runserver
13. 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)
14. add vote to the admin.py file so we can see associations
from polls.models import Vote
admin.site.register(Vote)
15. Add the urls we need for the rest of our app urls.py
(r'^admin/', include(admin.site.urls)),
(r'^polls/$', 'polls.views.index'),
(r'^polls/(?P<poll_id>\d+)/$', 'polls.views.detail'),
(r'^polls/(?P<poll_id>\d+)/vote/$', 'polls.views.vote'),
(r'^polls/(?P<poll_id>\d+)/data.xml$', 'polls.views.data'),
(r'^crossdomain.xml$', 'polls.views.crossdomain'),
(r'^local-media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': settings.STATIC_DOC_ROOT }),
16. create a view. in views.py
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello, world. You're at the poll index.")
17 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)
18. 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
19. In sttings.py, let’s set a path to our templates folder and add a setting for our static pages
TEMPLATE_DIRS = "/Path/to/your/stuff"
STATIC_DOC_ROOT = "/Path/to/your/stuff"
20. 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})
21. and create an index.html file
{% if projects %}
<ul>
{% for project in projects %}
<li>{{ project.title }}</li>
{% endfor %}
</ul>
{% else %}
<p>No projects are available.</p>
{% endif %}
22. 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, })
23. 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)
24. 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")
25. create a data.xml file
<?xml version="1.0" encoding="UTF-8"?>
<results>
<project>{{ project }}</project>
<totals>{{ vote_total }}</totals>
</results>
26. create a crossdomain.xml method
def crossdomain(request):
return HttpResponse('<?xml version=\"1.0\"?><cross-domain-policy><allow-access-from domain=\"*\" /></cross-domain-policy>', mimetype="text/xml")
27. 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>
28. Download votinator.swf and put in in the “media” directory
http://github.com/downloads/palewire/ire2010/voteinator.swf
29. 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)
30. create a test.py script
import sys, urllib2, urllib
url = 'http://localhost:8000/polls/1/vote/'
recommend = "1"
data = urllib.urlencode([('data', recommend)])
req = urllib2.Request(url)
fd = urllib2.urlopen(req, data)
while 1:
data = fd.read(1024)
if not len(data):
break
sys.stdout.write(data)