Django Code Lab
Jacob / James / Adrian
James = release manager
Practical Django Projects
Adrian = everyblock founder
Benevolant Dictators of Life
Def. Guide to Django
Jacob
Code Lab, part 1
Pim Van Heuvan, URL Design
Justin Lilly, unit testing
Richard House, model design
Peter Herndone, searching, optimizing
J Clifford Dyer, next/previous links
Part 2
Bob Haugen, preparing for deployment
Wiley Kestner, sginals
Eric St-Jean, REST APIs
Sean O Connor, order_by(”?”)
Honza Kral, many questions, many answers
Url Design
—————
Questions by Pim van Heuven, Belgium
The case of the URLconf monster
urls.py 2032 lines long
600+URL patterns
94 dicts of keyword arguments
generated dynamically
Worst-case matching
everytime u try to match a regex and fail, it takes time
worst case is a 404
600 regex matches before u get to 404
Break things up
They are already logically separated
Split into multiple files and use include with prefixes.
Drill down into smaller and smaller urlconfs.
Forms taking etra parameters.
Use cases
pass in an existing object to a form and derive
Getting Initial data
django.newforms.models.model_to_dict()
Passing extra parameters into a form
override init()
take extra arguments u want *args, **kwargs
call superclass init()
super() is important
Other Tricks
after super() call
Testing Django
——————
Justin Lilly
Unit tests
Model Design, Richard House
—————————————
“We just need one more field…”
EventType
EventTypeOption
Event
EventOption
Let’s build a form
pass in event_type
No more schema changes.
Peter Herndon
——————-
Searching: query optimization, executing raw SQL, and choosing the right tool for the job.
Works for research library.
synapse.mxkcc.org
synapse google code
The problem
/people/
Raw SQL
Django’s ORM is by far the weakest ORM available. There’s a certain point at which you will have to write SQL.
from django import db
sql = “SELECT… FROM… WHERE end = %s…”
params = [end_date,…]
cursor = db.connection.cursor()
cursor.execute(sql,params)
for row in coursor:
…
Read your db optimizer docs.
“Bad programmers worry about the code. Good programmers worry about data structures.”
Fulltext search has been done.
Google Coop, Lucene, Solar, Sphinx
Search Integration with Django
djapian, django-sphinx, djangosearch (developed at LJWorld)
from djangosearch.indexer import ModelIndex
results = Document.index.search(query)
Searching over a flat structure is faster than nested.
J. Clifford Dyer
————————
Handling Previous/Next Links
Dave Lowe
————-
When not to use the admin
Moving from Cold Fusion to Django
Apps don’t need to be part of the project.
Multiple sites that share apps/content
Use Site object to
Editor in Site A should not be allowed to Site B.
new forms admin will help that but for now just write your own views.
Get away from having applications inside a project.
Bob Haugen
——————
Prepping for deployment
Coding defensively.
serving media using builtin static server when DEBUG is true.
template dirs based on
urlresolvers.reverse() in a deployed site
raise Http404(“Invalid order ID”) shows up in debug mode
Develop and Deploy
manage.py runserver
Apache + mod_python or mod_wsgi
Pieces of the rest of the stack that
reverse proxy load balancer
Perlbal
(from livejournal)
Apache mod_proxy
spoonfeeding (reverse proxying)
mod_python is moving fast but webserver is slowly moving bits.
load is 0 but new requests are waiting on IO
allow perlbal to handle trickling of data
abstraction of hardware resources
add and remove servers without downtime
perlbal docs kind of suck/non-existent.
ask questions on the list.
Use Memcached
livejournal
Wiley Kestner
——————-
Signals
Notifications
User subscribes to object
When this object changes i want different ways of being notified
User chooses method of notification
Design Pattern (Observer
dispatcher, django has one built in
Dispatcher 101
some piece of code sends a “signal”
just a predefined python obj
django defines some useful signals
django.dispatch.dispatcher.send()
def save_callback():
print “Something just go saved”
dispatcher.connect(save_callback, signal=…)
need to guarantee it gets excecuted
put in models.py
Let’s write a simple listener
…
No documentation yet (Jacob’s fault, he’ll finish it during the sprint)
http://toys.jacobian.org/presentations/