Anda di halaman 1dari 50

Django

Dejan Lukan
evangeline.eleanor@gmail.com
August 3, 2010

1
1 Intoduction
1.1 Creating a project
If this is the first time you’re using django, you have to take care of initial setup (auto-generate some code that
establishes a django project):
# cd t o t h e d i r e c t o r y where you would l i k e t o s t o r e your c o d e
cd <d i r >

# c r e a t e new p r o j e c t
django−admin . py s t a r t p r o j e c t <p r o j e c t n a m e >

If your background is in PHP, you’re probably used to putting code under the web server’s document root
(/var/www/). With django, you don’t do that - it’s not a good idea to put any of this python code wihin your
web server’s document root, because it risks the possibility that people may be able to view your code over the
web. Put your code in some directory outside of the document root.

Startproject created:
−rw−r−−r−− 1 eleanor eleanor 0 Mar 7 15:08 init . py
−rw−r−−r−− 1 eleanor eleanor 546 Mar 7 1 5 : 0 8 manage . py
−rw−r−−r−− 1 eleanor e l e a n o r 2773 Mar 7 1 5 : 0 8 s e t t i n g s . py
−rw−r−−r−− 1 eleanor eleanor 542 Mar 7 1 5 : 0 8 u r l s . py

Explanation:
• init .py: empty file that tells python that this directory should be considered a python package
• manage.py: a command line utility that lets you interact with this django project in various ways
• settings.py: Settings/configuration for this django project
• urls.py: the url declarations for this django project (a table of contents)

1.2 The development server


Let’s verify that this worked. Change into the <dir> directory and run:
$ python manage . py r u n s e r v e r
V a l i d a t i n g models . . .
0 e r r o r s fo und

Django v e r s i o n 1 . 1 . 1 , using s e t t i n g s ’ e s t u d e n t . s e t t i n g s ’
Development s e r v e r i s r u n n i n g a t h t t p : // 1 2 7 . 0 . 0 . 1 : 8 0 0 0 /
Quit t h e s e r v e r w i t h CONTROL−C .

you’ve started the django development server, a lightweight web server written purely in python (you don’t
have to bother yourself with apache).

1.3 Changing the ip + port


By default, the runserver command starts the development server on the internal IP at port 8000. If you want
to change the server’s port, pass it as a command-line argument:
$ python manage . py r u n s e r v e r 8080

If you want to change the server’s ip, pass it along with the port (to listen on public IPs use):
python manage . py r u n s e r v e r 0.0.0.0:8000

1
1.4 Database setup
Edit setings.py:

• DATABASE ENGINE: [postgresql psycopg2, mysql, sqlite3]

• DATABASE NAME: the name of your database (if using sqlite the database will be a file in your computer:
a full absolute path. If the file doesn’t exist it will automatically be created when you sync the database for
the first time). If you’re using mysql create the database with ”CREATE DATABASE <database name>.

• DATABASE USER: your database user (not used in sqlite)

• DATABASE PASSWORD: your database password (not used in sqlite)

• DATABASE HOST: the host your database is on (empty string if database is on the same pysical machine
- not used for sqlite)

• INSTALLED APPS: the names of all django applications that are activated in this django instance. By
default it contains these apps:
– django.contrib.auth - an authentication system
– djando.contrib.contenttypes - a framework for content types
– djando.contrib.sessions - a session framework
– django.contrib.sites - a framework for managing multiple sites with one django installation

Each of these applications makes use of at least one database table, so we need to create the tables in the
database before we can use them:
python manage . py syncdb

this looks at the INSTALLED APPS setting and creates any necessary database tables according to the
database settings in your settings.py file.

Test if the database is setup correctly (start the shell):


>>> from d j a n g o . db i m p o r t c o n n e c t i o n
>>> c u r s o r = c o n n e c t i o n . c u r s o r ( )
>>>

1.5 Creating models


Now that your environment is set up, you can start doing work.

Each application you write in django consists of a python package, somewhere on your python path. Django
comes with a utility that automatically generates the basic directory structure of an app, so you can focus on
writing code rather than creating directories.

What’s the difference between a project and an app? An app is a Web application that does something –
e.g., a weblog system, a database of public records or a simple poll app. A project is a collection of configura-
tion and apps for a particular Web site. A project can contain multiple apps. An app can be in multiple projects.

To create your app, make sure you’re in the mysite directory and type this:
python manage . py s t a r t a p p <app name>

2
This will create:
−rw−r−−r−− 1 eleanor eleanor 0 Mar 7 15:41 init . py
−rw−r−−r−− 1 eleanor eleanor 57 Mar 7 1 5 : 4 1 models . py
−rw−r−−r−− 1 eleanor e l e a n o r 514 Mar 7 1 5 : 4 1 t e s t s . py
−rw−r−−r−− 1 eleanor eleanor 26 Mar 7 1 5 : 4 1 v i e w s . py

A model is the single, definitive source of data about your data. It contains the essential fields and behaviors
of the data you’re storing. The goal is to define your data model in one place and automatically derive things
from it.

First step in writing a database web app in django is to define your models - your database layout, with
additional metadata. In our simple app, we’ll create two models: polls and choices. Poll has a question and a
publication date, a choice has two fields: the text of the choice and a voite tally.

Edit the polls/models.py.


from d j a n g o . db i m p o r t models

c l a s s P o l l ( models . Model ) :
q u e s t i o n = models . C h a r F i e l d ( m a x l e n g t h =200)
p u b d a t e = models . D at e Ti meF i el d ( ’ d a t e p u b l i s h e d ’ )

c l a s s C h o i c e ( models . Model ) :
p o l l = models . ForeignKey ( P o l l )
c h o i c e = models . C h a r F i e l d ( m a x l e n g t h =200)
v o t e s = models . I n t e g e r F i e l d ( )

Explanation:
• each model is represented by a class that subclasses django.db.models.Model

• each model has a number of class variables, each of which represents a database field of the model

• each field is represented by an instance of a Field class - CharField for character fields and DateTimeField
for datetimes. This tells django what type of data each field holds.

• the name of each Field instance (question or pub date) is the field’s name. You’ll use this value in your
python code, and your database will use it as the column name.

• some Field classes have required elements. CharField, for example, requires that you give it a max length.
That’s used not only in the database schema, but in validation

• note a relationship is defined, using ForeignKey. That tells Django each Choice is related to a single Poll.
Django supports all the common database relationships: many-to-ones, many-to-manys and one-to-ones

1.6 Activating models


That small bit of model code gives django a lot of info - with it django is able to:

• create a database schema (CREATE TABLE statements) for this app

• create a python database access API for accessing Poll and Choice objects

But first we need to tell our project that the polls app is installed. Edit the settings.py file again and change
the INSTALLED APPS setting to include the string estudent.polls:

3
INSTALLED APPS = (
’ django . c o n t r i b . auth ’ ,
’ django . c o n t r i b . contenttypes ’ ,
’ django . c o n t r i b . sessions ’ ,
’ django . c o n t r i b . sites ’ ,
’ estudent . p o l l s ’,
)

now django knows project includes the polls app. Run:


$ python manage . py s q l polls

The sql command doesn’t actually run the SQL in your database - it just prints it to the screen so that you
can see what SQL Django thinks is required. If you wanted to, you could copy and paste this SQL into your
database prompt. However, as we will see shortly, Django provides an easier way of committing the SQL to the
database.
Also run these commands:

• check for any errors in the construction of your modules:


$ python manage . py v a l i d a t e
0 e r r o r s fo un d

• outputs any custom sql statements that are defined for the application:
$ python manage . py s q l c u s t o m p o l l s

• outputs the necessary DROP TABLE statements for this app:


$ python manage . py s q l c l e a r polls

• output the CREATE INDEX statements for this app:


$ python manage . py s q l i n d e x e s p o l l s
BEGIN ;
CREATE INDEX ” p o l l s c h o i c e p o l l i d ” ON ” p o l l s c h o i c e ” ( ” p o l l i d ” ) ;
COMMIT;

• combination of above statements:


python manage . py s q l a l l polls

Now run this to create those models in your database:


python manage . py syncdb

The syncdb command runs the sql from ’sqlall’ on your database for all apps in INSTALLED APPS that don’t
already exist in your database. This creates all the tables, initial data and indexes for any apps you have added
to your project since the last time you ran syncdb. syncdb can be called as often as you like, and it will only
ever create the tables that don’t exist.

1.7 Playing with the API


To invoke the python shell run (this sets up the project’s environment - putting project on sys.path ; setting
the DJANGO SETTINGS MODULE environment vairable, which gives django the path to your settings.py):
python manage . py s h e l l

4
Now explore the database API:
# i m p o r t t h e model c l a s s e s we j u s t w r o t e
>>> from e s t u d e n t . p o l l s . models i m p o r t P o l l

# no p o l l s a r e i n t h e s y s t e m y e t
>>> P o l l . o b j e c t s . a l l ( )
[]

# c r e a t e a new p o l l
>>> i m p o r t d a t e t i m e
>>> p = P o l l ( q u e s t i o n=”What ’ s up ? ” , p u b d a t e=d a t e t i m e . d a t e t i m e . now ( ) )

# s a v e t h e o b j e c t i n t o t h e d a t a b a s e − i t h as an ID
>>> p . s a v e ( )
>>> p . i d
1

# a c c e s s d a t a b a s e columns v i a python a t t r i b u t e s
>>> p . q u e s t i o n
”What ’ s up ? ”
>>> p . p u b d a t e
datetime . datetime (2010 , 3 , 7 , 9 , 4 , 22 , 674315)

# change v a l u e s ( you must c a l l s a v e )


>>> p . p u b d a t e = d a t e t i m e . d a t e t i m e ( 2 0 1 0 , 3 , 7 , 0 , 0 )
>>> p . s a v e ( )

# d i s p l a y a l l the p o l l s in the database


>>> P o l l . o b j e c t s . a l l ( )
[< P o l l : P o l l o b j e c t >]

This is unhelpful representation of this object. Edit polls.models.py and add unicode () method to both Poll
and Choice (let’s also add another function):
from d j a n g o . db i m p o r t models
import datetime

c l a s s P o l l ( models . Model ) :
q u e s t i o n = models . C h a r F i e l d ( m a x l e n g t h =200)
p u b d a t e = models . D at e Ti meF i el d ( ’ d a t e p u b l i s h e d ’ )

def unicode ( self ) :


return s e l f . q u e s t i o n

def was published today ( s e l f ) :


return s e l f . p u b d a t e . d a t e ( ) == d a t e t i m e . d a t e . t o d a y ( )

c l a s s C h o i c e ( models . Model ) :
p o l l = models . ForeignKey ( P o l l )
c h o i c e = models . C h a r F i e l d ( m a x l e n g t h =200)
v o t e s = models . I n t e g e r F i e l d ( )

def unicode ( self ) :


return s e l f . c h o i c e

Start the interactive shell again:


>>> from e s t u d e n t . p o l l s . models i m p o r t P o l l , C h o i c e

# make s u r e t h a t unicode ( ) works


>>> P o l l . o b j e c t s . a l l ( )
[< P o l l : What ’ s up? >]

# database lookups
>>> P o l l . o b j e c t s . f i l t e r ( i d =1)
[< P o l l : What ’ s up? >]
>>> P o l l . o b j e c t s . f i l t e r ( q u e s t i o n s t a r t s w i t h= ’ What ’ )
[< P o l l : What ’ s up? >]
>>> P o l l . o b j e c t s . g e t ( p u b d a t e y e a r =2010)
<P o l l : What ’ s up?>
>>> P o l l . o b j e c t s . g e t ( i d =2)
T r a ceback ( most r e c e n t c a l l l a s t ) :

5
F i l e ”<c o n s o l e >” , l i n e 1 , i n <module>
F i l e ” / u s r / l i b / python2 . 6 / s i t e −p a c k a g e s / d j a n g o /db/ models / manager . py ” , l i n e 1 2 0 , i n g e t
return s e l f . g e t q u e r y s e t ( ) . g e t ( ∗ a r g s , ∗∗ kwargs )
F i l e ” / u s r / l i b / python2 . 6 / s i t e −p a c k a g e s / d j a n g o /db/ models / q u e r y . py ” , l i n e 3 0 5 , i n g e t
% s e l f . model . meta . o b j e c t n a m e )
D o e s N o t E x i s t : P o l l matching q u e r y d o e s not e x i s t .

# give p o l l a couple of choices


>>> p = P o l l . o b j e c t s . g e t ( pk=1)
>>> p . c h o i c e s e t . c r e a t e ( c h o i c e= ’ Not much ’ , v o t e s =0)
<C h o i c e : Not much>
>>> p . c h o i c e s e t . c r e a t e ( c h o i c e= ’ The sky ’ , v o t e s =0)
<C h o i c e : The sky>
>>> c = p . c h o i c e s e t . c r e a t e ( c h o i c e= ’ J u s t h a c k i n g a g a i n ’ , v o t e s =0)

# c h o i c e o b j e c t s have API a c c e s s t o t h e i r related Poll objects


>>> c . p o l l
<P o l l : What ’ s up?>

# P o l l o b j e c t s get a c c e s s to Choice o b j e c t s
>>> p . c h o i c e s e t . a l l ( )
[< C h o i c e : Not much>, <C h o i c e : The sky >, <C h o i c e : J u s t h a c k i n g a g a i n >, <C h o i c e : J u s t h a c k i n g a g a i n >]
>>> p . c h o i c e s e t . c o u n t ( )
4

# t h e API a u t o m a t i c a l l y f o l l o w s r e l a t i o n s h i p s a s f a r a s you need


>>> C h o i c e . o b j e c t s . f i l t e r ( p o l l p u b d a t e y e a r =2010)
[< C h o i c e : Not much>, <C h o i c e : The sky >, <C h o i c e : J u s t h a c k i n g a g a i n >, <C h o i c e : J u s t h a c k i n g a g a i n >]

# d e l e t e one o f t h e c h o i c e s
>>> c = p . c h o i c e s e t . f i l t e r ( c h o i c e s t a r t s w i t h= ’ J u s t h a c k i n g ’ )
>>> c . d e l e t e ( )

1.8 Activate the admin site


To activate the admin site for your installation do:

• add django.contrib.admin to your INSTALLED APPS

• run python manage.py syncdb

• edit estudent/urls.py file and uncomment the lines that reference the admin

Start the development server:


python manage . py r u n s e r v e r

We need to tell the admin that Poll objects have an admin interface: create a file called admin.py in your polls
directory and edit it to look like this:
from e s t u d e n t . p o l l s . models i m p o r t P o l l
from d j a n g o . c o n t r i b i m p o r t admin

admin . s i t e . r e g i s t e r ( P o l l )

You’ll need to restart the development server to see your changes. Normally, the server auto-reloads code every
time you modify a file, but the action of creating a new file doesn’t trigger the auto-reloading logic.

By registering the Poll model with admin.site.register(Poll), django was able to construct a default form repre-
sentation. Often you’ll want to customize how the admin form looks and works. You’ll do this by telling django
the options you want when you register the object.

6
Example: replace the admin.site.register(Poll) with:
from e s t u d e n t . p o l l s . models i m p o r t P o l l
from d j a n g o . c o n t r i b i m p o r t admin

c l a s s PollAdmin ( admin . ModelAdmin ) :


f i e l d s = [ ’ pub date ’ , ’ quest ion ’ ]

admin . s i t e . r e g i s t e r ( P o l l , PollAdmin )

Explanation: create a model admin object, then pass it as the second argument to admin.site.register() - any
time you need to change the admin options for an object. This makes the ”Publication date” come before the
”Question” field. This isn’t impressive with only two fields, but for admin forms with dozens of fields, choosing
an intuitive order is an important usability detail.

You can also split the form up into fieldsets:


from e s t u d e n t . p o l l s . models i m p o r t P o l l
from d j a n g o . c o n t r i b i m p o r t admin

c l a s s PollAdmin ( admin . ModelAdmin ) :


f i e l d s e t s = [ ( None , { ’ f i e l d s ’ : [ ’ q u e s t i o n ’ ] } ) , ( ’ Date i n f o r m a t i o n ’ , { ’ f i e l d s ’ : [ ’ p u b d a t e ’ ] } ) , ]

admin . s i t e . r e g i s t e r ( P o l l , PollAdmin )

the first element of each tuple in fieldsets is the title of the fieldset.

You can assign arbitrary HTML classes to each fieldset. Django provides a ”collapse” class that displays a
particular fieldset initially collapsed. This is useful when you have a long form that contains a number of fields
that aren’t commonly used:
from e s t u d e n t . p o l l s . models i m p o r t P o l l
from d j a n g o . c o n t r i b i m p o r t admin

c l a s s PollAdmin ( admin . ModelAdmin ) :


f i e l d s e t s = [ ( None , { ’ f i e l d s ’ : [ ’ q u e s t i o n ’ ] } ) , ( ’ Date i n f o r m a t i o n ’ , { ’ f i e l d s ’ : [ ’ p u b d a t e ’ ] , ’
classes ’ : [ ’ collapse ’ ]}) ,]

admin . s i t e . r e g i s t e r ( P o l l , PollAdmin )

1.9 Adding related objects


We have out Poll admin page, but a Poll has multiple Choices, and the admin page doesn’t display choices. We
can register Choice with the admin just as we did with Poll:
from e s t u d e n t . p o l l s . models i m p o r t P o l l
from e s t u d e n t . p o l l s . models i m p o r t C h o i c e
from d j a n g o . c o n t r i b i m p o r t admin

c l a s s PollAdmin ( admin . ModelAdmin ) :


f i e l d s e t s = [ ( None , { ’ f i e l d s ’ : [ ’ q u e s t i o n ’ ] } ) , ( ’ Date i n f o r m a t i o n ’ , { ’ f i e l d s ’ : [ ’ p u b d a t e ’ ] , ’
classes ’ : [ ’ collapse ’ ]}) ,]

admin . s i t e . r e g i s t e r ( P o l l , PollAdmin )
admin . s i t e . r e g i s t e r ( C h o i c e )

if adding a new Choice, the ”Poll” field is a select box containing every poll in the database. Django knows
that a ForeignKey should be represented in the admin as a <select> box.

This is an inefficient way of adding Choice objects to the system. It’d be better if you could add a bunch
of Choices directly when you create the Poll object:

7
from e s t u d e n t . p o l l s . models i m p o r t P o l l
from e s t u d e n t . p o l l s . models i m p o r t C h o i c e
from d j a n g o . c o n t r i b i m p o r t admin

c l a s s C h o i c e I n l i n e ( admin . S t a c k e d I n l i n e ) :
model = C h o i c e
extra = 3

c l a s s PollAdmin ( admin . ModelAdmin ) :


fieldsets = [
( None , { ’ fields ’ : [ ’ question ’ ]}) ,
( ’ Date i n f o r m a t i o n ’ , { ’ f i e l d s ’ : [ ’ pub date ’ ] , ’ c l a s s e s ’ : [ ’ collapse ’ ]}) ,
]
inlines = [ ChoiceInline ]

admin . s i t e . r e g i s t e r ( P o l l , PollAdmin )

this tells django: Choice objects are edited on the Poll admin page.

With TabularInline (instead of StackedInline), the related objects are displayed in a more compact, table-based
format:
c l a s s C h o i c e I n l i n e ( admin . T a b u l a r I n l i n e ) :

1.10 Customizing the admin change list


Let’s change the ”change list” page: by default django displays the str() of each object, but sometimes it’d be
more helpful if we could display individual fields: use the list display admin option, which is a tuple of field
names to display, as columns for the object:
c l a s s PollAdmin ( admin . ModelAdmin ) :
# ...
l i s t d i s p l a y = ( ’ quest io n ’ , ’ pub date ’ , ’ was published today ’ )

Let’s add some filters to the PollAdmin:


l i s t f i l t e r = [ ’ pub date ’ ]

The type of filter displayed depends on the type of field you’re filtering on. Because pub date is a DateTime-
Field, Django knows to give the default filter options for DateTimeFields: ”Any date,” ”Today,” ”Past 7 days,”
”This month,” ”This year.”

Add search field (search box at the top - django will search the qiestion field):
s e a r c h f i e l d s = [ ’ question ’ ]

Add polles sorted by dates:


d a t e h i e r a r c h y = ’ pub date ’

That adds hierarchical navigation, by date, to the top of the change list page. At top level, it displays all
available years. Then it drills down to months and, ultimately, days.

1.11 Design your urls


Create a python module, called URLconf: this is how django associates a given URL with given python code.

When a user requests a django-powered page, the system looks at the ROOT URLCONF setting, which contains
a string in python syntax. Django loads that module and looks for a module-level variable called urlpatterns,
which is a sequence of tuples:

8
( r e g u l a r e x p r e s s i o n , Python c a l l b a c k f u n c t i o n [, optional dictionary ])

django starts at the first regular expression and makes its way down the list, comparing the requested URL
against each regular expression until it finds one that matches: then it calls the python function, with an
HttpRequest object as the first argument, any captured values from the RE as keyword arguments.

The default URLconf is located at estudent/urls.py, and the settings.py ROOT URLCONF variable is set
to point at that file. Edit urls.py:
from d j a n g o . c o n f . u r l s . d e f a u l t s i m p o r t ∗

from d j a n g o . c o n t r i b i m p o r t admin
admin . a u t o d i s c o v e r ( )

urlpatterns = patterns ( ’ ’ ,
( r ’ ˆ p o l l s /$ ’ , ’ estudent . p o l l s . views . index ’ ) ,
( r ’ ˆ p o l l s / ( ?P<p o l l i d >\d+)/ $ ’ , ’ e s t u d e n t . p o l l s . v i e w s . d e t a i l ’ ) ,
( r ’ ˆ p o l l s / ( ?P<p o l l i d >\d+)/ r e s u l t s / $ ’ , ’ e s t u d e n t . p o l l s . v i e w s . r e s u l t s ’ ) ,
( r ’ ˆ p o l l s / ( ?P<p o l l i d >\d+)/ v o t e / $ ’ , ’ e s t u d e n t . p o l l s . v i e w s . v o t e ’ ) ,
( r ’ ˆ admin / ’ , i n c l u d e ( admin . s i t e . u r l s ) ) ,
)

when somebody requests a page ”/polls/23/”, django loads this module (because it’s pointed to by the ROOT URLCONF),
it finds the variable urlpatterns and traverses the RE in order. When it finds the RE that matches it loads the
function detail() from estudent/polls/views.py and calls it like:
d e t a i l ( r e q u e s t=<HttpRequest o b j e c t >, p o l l i d = ’ 23 ’ )

the poll id=’23’ part comes from (?P<poll id>+ . ): using parentheses around a pattern captures the text matched
by that pattern and sends it as argument to the view function. the ?P<>poll id¿ defines the name that will be
used to identify the matched pattern; and +. is a regular expression to match a sequence of digits.

Because the URL patterns are RE there is no limit on what you can do with them (no need to add .php
extensions).

These RE do not search GET and POST parameters, or the domain name. The request to http://www.example.com/myapp/,
the URLconf will look for myapp/. In a request to http://www.example.com/myapp/?page=3, the URLconf
will look for myapp/

1.12 Write your first view


We just have the URLconf. We get an error:
Caught an e x c e p t i o n while r e n d e r i n g : T r i e d v o t e i n module e s t u d e n t . p o l l s . v i e w s . E r r o r was : ’ module ’
o b j e c t has no a t t r i b u t e ’ v o t e ’

this happens because you haven’t written a function vote() in the module estudent.polls.views.py:
from d j a n g o . h t t p i m p o r t HttpResponse

def vote ( request , p o l l i d ) :


return HttpResponse ( ”You ’ r e v o t i n g on p o l l %s . ” % p o l l i d )

def r e s u l t s ( request , p o l l i d ) :
return HttpResponse ( ”You ’ r e l o o k i n g a t t h e r e s u l t s of p o l l %s . ” % p o l l i d )

def d e t a i l ( request , p o l l i d ) :
return HttpResponse ( ”You ’ r e l o o k i n g a t p o l l %s . ” % p o l l i d )

def index ( request ) :


return HttpResponse ( ” H e l l o , w o r l d . You ’ r e a t t h e p o l l i n d e x . ” )

9
now visit this addresses (it will display the placeholder results and voting pages):
• /polls/34/
• /polls/34/result/
• /polls/34/vote/

1.13 Write views that actually do something


Each view is responsible for doing one of two things (what django requires):
• returning an HttpResponse object containing the content for the requested page
• raising an exception such as Http404
Your view can read records from a database. It can use a template system (django’s). It can generate a PDF
file, output XML, create a ZIP file on the fly, anything you want, using whatever python libraries you want.

Let’s change the index() function (display the latest 5 poll questions in the system, separated by commas):
def index ( request ) :
l a t e s t p o l l l i s t = P o l l . o b j e c t s . a l l ( ) . o r d e r b y ( ’−p u b d a t e ’ ) [ : 5 ]
output = ’ , ’ . j o i n ( [ p . q u e s t i o n for p i n l a t e s t p o l l l i s t ] )
return HttpResponse ( o u t p u t )

∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗
S i s t u d e n t ? , Kako j e t v o j f o t e r ? , Kako j e t v o j a mama? , Kako s i ? , What ’ s up ?
∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗

The page’s design is hard-coded in the view. If you want to change the way the page looks, you’ll have to edit
this python code: use django’s template system to separate the design from python:
from d j a n g o . template i m p o r t Context , l o a d e r
from e s t u d e n t . p o l l s . models i m p o r t P o l l
from d j a n g o . h t t p i m p o r t HttpResponse

def vote ( request , p o l l i d ) :


return HttpResponse ( ”You ’ r e v o t i n g on p o l l %s . ” % p o l l i d )

def r e s u l t s ( request , p o l l i d ) :
return HttpResponse ( ”You ’ r e l o o k i n g a t t h e r e s u l t s of p o l l %s . ” % p o l l i d )

def d e t a i l ( request , p o l l i d ) :
return HttpResponse ( ”You ’ r e l o o k i n g a t p o l l %s . ” % p o l l i d )

def index ( request ) :


l a t e s t p o l l l i s t = P o l l . o b j e c t s . a l l ( ) . o r d e r b y ( ’−p u b d a t e ’ ) [ : 5 ]
t = l o a d e r . g e t t e m p l a t e ( ’ p o l l s / i n d e x . html ’ )
c = Context ( { ’ l a t e s t p o l l l i s t ’ : l a t e s t p o l l l i s t , } )
return HttpResponse ( t . r e n d e r ( c ) )

Edit TEMPLATES DIRS in your settings.py and set the templates directory and in there create directory
polls in that directory and within that index.html (loader.get template(’polls/index.html’) maps to ”[tem-
plate directory]/polls/index.html). Template should contain:
{% i f l a t e s t p o l l l i s t %}
<u l >
{% f o r p o l l i n l a t e s t p o l l l i s t %}
< l i > {{ p o l l . q u e s t i o n }} </ l i >
{% e n d f o r %}
</u l >
{% e l s e %}
<p>No p o l l s a r e a v a i l a b l e . </p>
{% e n d i f %}

10
load the page in your Web browser, and you should see a bulleted-list containing the ”What’s up” poll. Shortcut:
from d j a n g o . s h o r t c u t s i m p o r t r e n d e r t o r e s p o n s e
from m y s i t e . p o l l s . models i m p o r t P o l l

def index ( request ) :


l a t e s t p o l l l i s t = P o l l . o b j e c t s . a l l ( ) . o r d e r b y ( ’−p u b d a t e ’ ) [ : 5 ]
return r e n d e r t o r e s p o n s e ( ’ p o l l s / i n d e x . html ’ , { ’ l a t e s t p o l l l i s t ’ : l a t e s t p o l l l i s t })

render to response takes a template name as its first argument and a dictionary as its optional second argument.
It returns an HttpResponse object of the given template rendered with the given context.

Let’s also change the urls.py so that URL design will be specific to the app (and not the django installation).
Copy the file estudent/urls.py to estudent/polls/urls.py and edit it:
from d j a n g o . c o n f . u r l s . d e f a u l t s i m p o r t ∗

from d j a n g o . c o n t r i b i m p o r t admin
admin . a u t o d i s c o v e r ( )

urlpatterns = patterns ( ’ ’ ,
( r ’ ˆ p o l l s / ’ , include ( ’ estudent . p o l l s . views . index ’ ) ) ,
( r ’ ˆ p o l l s / ( ?P<p o l l i d >\d+)/ ’ , i n c l u d e ( ’ e s t u d e n t . p o l l s . v i e w s . d e t a i l ’ ) ) ,
( r ’ ˆ p o l l s / ( ?P<p o l l i d >\d+)/ r e s u l t s / ’ , i n c l u d e ( ’ e s t u d e n t . p o l l s . v i e w s . r e s u l t s ’ ) ) ,
( r ’ ˆ p o l l s / ( ?P<p o l l i d >\d+)/ v o t e / ’ , i n c l u d e ( ’ e s t u d e n t . p o l l s . v i e w s . v o t e ’ ) ) ,
( r ’ ˆ admin / ’ , i n c l u d e ( admin . s i t e . u r l s ) ) ,
)

include() chops off whatever part of the URL matched up to that point and sends the remaining string to the
the included URLconf for further processing.

The idea behind include() and URLconf decoupling is to make it easy to plug-and-play URLs.

2 Basics of dynamic web pages


We’ll work under the eleanor project/dorectory.

Goal: create a web page that displays the current date and time. We’ll write a view function() - a python
function that tkaes a web request and returns a web response. Response can be:
• the HTML contents of a web page
• a redirect
• a 404 error
• an XML document
• an image
• ...
view contains whatever logic is necessary to return that response. Create eleanor/views.py:

Explanation:
• the current datetime is the view function - each view function takes an HttpRequest object as it’s first
parameter.
• 1: calculates the current date and time

11
• 2: constructs an HTML response using python’s format-string capability. The %s within thr string is a
placeholder.

• 3: returns an HttpResponse objuect that contains the generated response

The view functions need to be in python path.

2.1 Mapping URLs to views


This view function returns an HTML page that includes the current date and time: but how to tell django to
use this code - with URLconfs (urls.py): a mapping between URL patterns and the view functions that should
be called for those URL patterns. Edit urls.py:
from d j a n g o . c o n f . u r l s . d e f a u l t s i m p o r t ∗
from e l e a n o r . v i e w s i m p o r t c u r r e n t d a t e t i m e

urlpatterns = patterns ( ’ ’ ,
( r ’ ˆ time /$ ’ , c u r r e n t d a t e t i m e ) ,
)

Explanation:

• line is an urlpattern which is a python tuple in which the first element is a simple RE and second element
is the view function to use (any request to the URL /time/ should be handled by the current datetime
view function)

• we passed current datetime as an object without calling the function (functions are first-class objects)

The urlpatterns variable (defined in ROOT URLCONF) defines the mapping between URLs and the code
that handles those URLs.

2.2 How django processes a request


• the ”python manage.py runserver” imports a file settings.py from the same directory (configurations:
ROOT URLCONF - which python module should be used as the URLcond for this web site)

• when a request comes in - example: /time/ - django loads the URLconf and check each of the URLpatterns
in order (until it finds one it matches) and then calls the view function associated with that pattern, passing
an HttpRequest object as the first parameter to the function

• the view function is responsible for returning an HttpResponse object

Each view always takes an HttpRequest object as its first parameter.

2.3 URLconfs and loose coupling


If two pieces of code are loosely coupled, then changes made to one of the pieces will have little or no effect on
the other: the decision of what the URL should be for a given function, and the implementation of the function
itself, reside in two separate places.

If we wanted to change the URL for the application— say, move it from /time/ to /currenttime/—we could
make a quick change to the URLconf, without having to worry about the underlying implementation of the
function. Similarly, if we wanted to change the view function—altering its logic somehow—we could do that
without affecting the URL to which the function is bound.

12
2.4 Dynamic URLs
The /time/ was static, let’s make a dynamic url now: /time/plus/1 would display date/time one hour into the
future, /time/plus/2 two hours,...
from d j a n g o . c o n f . u r l s . d e f a u l t s i m p o r t ∗
from e l e a n o r . v i e w s i m p o r t c u r r e n t d a t e t i m e , h o u r s a h e a d

urlpatterns = patterns ( ’ ’ ,
( r ’ ˆ time /$ ’ , c u r r e n t d a t e t i m e ) ,
( r ’ ˆ t i m e / p l u s /\d { 1 , 2 } / $ ’ , h o u r s a h e a d ) ,
)

the ”\d1,2” allows either one-or-two digit numbers (number limited to 99).

Now we need to pass that data to view function: place parentheses around the data in the URLpattern that we
want to save:
( r ’ ˆ time / p l u s /(\ d {1 ,2}) /$ ’ , hours ahead ) ,

Now we need to write he hours ahead view (takes an extra argument - number of hours of offset):
def hours ahead ( request , o f f s e t ) :
o f f s e t = int ( o f f s e t )
dt = d a t e t i m e . d a t e t i m e . now ( ) + d a t e t i m e . t i m e d e l t a ( h o u r s= o f f s e t )
html = ”<html><body>I n %s hour ( s ) , i t w i l l be %s . </ body></html>” % ( o f f s e t , dt )
return HttpResponse ( html )

2.5 Error pages


When error occurs you have a lot of info:
• TypeError (Request Method, Request URL, Exception Type, Exception Value, Exception Location)

• Traceback (Switch to copy-and-paste view)

• Request information

Are you the type of programmer who likes to debug with the help of carefully placed print statements? You can
use the Django error page to do so—just without the print statements. At any point in your view, temporarily
insert an assert False to trigger the error page. Then, you can view the local variables and state of the program.

All this info is only displayed when then the django project is in debug mode.

3 Django Template System


We normally don’t hard-code HTML into our python code, because:

• any change to the design of the page requires a change to the python code

• you can’t split the responsibilities among two different people

Template system is a string of text that is intended to separate the presentation of a document from its data. A
template defines placeholders and various bits of basic logic that regulate how the document should be displayed.

Example:

13
<html>
<head><t i t l e >O r d e r i n g n o t i c e </ t i t l e ></head>

<body>

<p>Dear {{ p e r s o n n a m e }} , </p>

<p>Thanks f o r p l a c i n g an o r d e r from {{ company } } . I t ’ s s c h e d u l e d t o


s h i p on {{ s h i p d a t e | d a t e : ” F j , Y” }}. </p>

<p>Here a r e t h e i t e m s you ’ ve o r d e r e d : </p>

<u l >
{% f o r i t e m i n i t e m l i s t %}
< l i >{{ i t e m }}</ l i >
{% e n d f o r %}
</u l >

{% i f o r d e r e d w a r r a n t y %}
<p>Your w a r r a n t y i n f o r m a t i o n w i l l be i n c l u d e d i n t h e p a c k a g i n g . </p>
{% e n d i f %}

<p>S i n c e r e l y ,< br />{{ company }}</p>

</body>
</html>

this is a basic HTML with some variables and template tags:


• any text surrounded by a pair of braces ( {{ person name }} ) is a variable: insert the value of a variable
with the given name
• any text surrounded by %{ is a template tag: just tells the template system to do something
• for tag let you loop over each item in a sequence
• if tag acts like a logical if statement (if the value of ordered warranty variable evaluates to True: if it does
the template system will display everything between the % ... % and % endif % ; if not, the template
system won’t display it. It also supports % ... %.
• with filter you can alter the display of a variable:
{{ s h i p d a t e | d a t e : ”F j , Y” }}

here we’re passing the ship date variable to the date filter, giving (pipe) the date filter the argument ”F
j, Y”: the date filter formats dates in a given format.

3.1 Using the template system


Two steps:
• create a Template object by providing the raw template code as a string
• call the render() method of the Template object with a given set of variables which returns a fully
rendered template as a string, with all the variables and block tags evaluated according to the context.

3.2 Creating template objects


Template class lives in the django.template module and the constructor takes one argument: the raw template
code.

Example (first start interactive shell by: ”python manage.py shell”):

14
>>> from d j a n g o . template i m p o r t Template
>>> t = Template ( ”My name i s {{ name } } . ” )
>>> p r i n t t
<d j a n g o . template . Template o b j e c t a t 0 x83b2e6c>
>>>
>>>
>>> from d j a n g o . template i m p o r t Context , Template
>>> t = Template ( ”My name i s {{ name } } . ” )
>>> c = Context ( { ”name” : ” E l e a n o r ” } )
>>> t . r e n d e r ( c )
u ’My name i s E l e a n o r .

we call the render() method on our template object, passing it the context. This returns the rendered tem-
plate—that is, it replaces template variables with the actual values of the variables, and it executes any block
tags.

Those are the fundamentals of using the Django template system: just write a template, create a Template
object, create a Context, and call the render() method.

3.3 Context variable lookup


The template system also handles more complex data structures, such as lists, dictionaries, and custom objects.
The key to traversing complex data structures in Django templates is the dot character (.). Use a dot to access
dictionary keys, attributes, indices, or methods of an object.

Example:
>>> from d j a n g o . template i m p o r t Context , Template
>>> p e r s o n = { ’ name ’ : ’ E l e a n o r ’ , ’ a g e ’ : ’ 22 ’ }
>>> t = Template ( ’ {{ p e r s o n . name }} i s {{ p e r s o n . a g e }} y e a r s o l d . ’ )
>>> c = Context ( { ’ p e r s o n ’ : p e r s o n } )
>>> t . r e n d e r ( c )
u ’ E l e a n o r i s 22 y e a r s o l d .

Another example:
>>> from d j a n g o . template i m p o r t Context , Template
>>> i m p o r t d a t e t i m e
>>> d = d a t e t i m e . d a t e ( 1 9 9 3 , 5 , 2 )
>>> d . y e a r
1993
>>> d . month
5
>>> d . day
2
>>> t = Template ( ’ The month i s {{ d a t e . month }} and t h e y e a r i s {{ d a t e . y e a r } } . ’ )
>>> c = Context ( { ’ d a t e ’ : d } )
>>> t . r e n d e r ( c )
u ’ The month i s 5 and t h e y e a r i s 1 9 9 3 . ’

This example uses custom class:


>>> from d j a n g o . template i m p o r t Context , Template
>>> c l a s s P e r s o n ( o b j e c t ) :
... def init ( s e l f , first name , last name ) :
... s e l f . first name , s e l f . last name = first name , last name
...
>>> t = Template ( ’ H e l l o , {{ p e r s o n . f i r s t n a m e }} {{ p e r s o n . l a s t n a m e } } . ’ )
>>> c = Context ( { ’ p e r s o n ’ : P e r s o n ( ’ Dejan ’ , ’ Lukan ’ ) } )
>>> t . r e n d e r ( c )
u ’ H e l l o , Dejan Lukan . ’

We can also call methods on objects:

15
>>> from d j a n g o . template i m p o r t Context , Template
>>> t = Template ( ’ {{ v a r }} −− {{ v a r . upper }} −− {{ v a r . i s d i g i t }} ’ )
>>> t . r e n d e r ( Context ( { ’ v a r ’ : ’ h e l l o ’ } ) )
u ’ h e l l o −− HELLO −− F a l s e ’
>>> t . r e n d e r ( Context ( { ’ v a r ’ : ’ 123 ’ } ) )
u ’ 123 −− 123 −− True ’

It’s not possible to pass arguments to the methods: you can only call methods that have no required arguments.

You can also list indices (Negative list indices are not allowed. For example, the template variable items.-
1 would cause a TemplateSyntaxError):
>>> from d j a n g o . template i m p o r t Context , Template
>>> t = Template ( ’ Item 2 i s {{ i t e m s . 2 } } . ’ )
>>> c = Context ( { ’ i t e m s ’ : [ ’ a p p l e s ’ , ’ bananas ’ , ’ c a r r o t s ’ ] } )
>>> t . r e n d e r ( c )
u ’ Item 2 i s c a r r o t s . ’

Dot lookups can be nested multiple levels deep:


>>> from d j a n g o . template i m p o r t Context , Template
>>> p e r s o n = { ’ name ’ : ’ Dejan ’ , ’ a g e ’ : ’ 22 ’ }
>>> t = Template ( ’ {{ p e r s o n . name . upper }} i s {{ p e r s o n . a g e }} y e a r s o l d . ’ )
>>> c = Context ( { ’ p e r s o n ’ : p e r s o n } )
>>> t . r e n d e r ( c )
u ’DEJAN i s 22 y e a r s o l d . ’

Summarized dot lookups:

• dictionary lookup (foo[”bar”])

• attribute lookup (foo.bar)

• method call (foo.bar())

• list-index lookup (foo[bar])

How to prevent the template from executing a certain function (if you have a BankAccount object that has a
delete() method. A template shouldn’t be allowed to include something like account.delete ): set the function
attribute alters data on the method:
d e f delete ( s e l f ) :
# Delete the account
d e l e t e . a l t e r s d a t a = True

the template system won’t execute any method marked in this way. In other words, if a template includes
account.delete , that tag will not execute the delete() method. It will fail silently.

If a variable doesn’t exist, the template system renders it as an empty string:


>>> from d j a n g o . template i m p o r t Context , Template
>>> t = Template ( ’ Your name i s {{ name } } . ’ )
>>> t . r e n d e r ( Context ( ) )
u ’ Your name i s . ’

16
3.4 Playing with context objects
Most of the time, you’ll instantiate Context objects by passing in a fully populated dictionary to Context().
But you can add and delete items from a Context object once it’s been instantiated, too, using standard Python
dictionary syntax:
>>> from d j a n g o . template i m p o r t Context
>>> c = Context ( { ” f o o ” : ” b a r ” } )
>>> c [ ’ f o o ’ ]
’ bar ’
>>> d e l c [ ’ f o o ’ ]
>>> c [ ’ f o o ’ ]
T r a ceback ( most r e c e n t c a l l l a s t ) :
F i l e ”<c o n s o l e >” , l i n e 1 , i n <module>
F i l e ” / u s r / l i b / python2 . 6 / s i t e −p a c k a g e s / d j a n g o / t e m p l a t e / c o n t e x t . py ” , l i n e 4 4 , i n getitem
r a i s e KeyError ( key )
KeyError : ’ f o o ’
>>> c [ ’ newfoo ’ ] = ’ newbar ’
>>> c [ ’ newfoo ’ ]
’ newbar ’

3.5 Basic template tags


3.5.1 if/else
The {% if %} tag evaluates a variable, and if that variable is “true” (it exists, is not empty, and is not a false
Boolean value), the system will display everything between {% if %} and {% endif %}.

In Python, the empty list ([]), tuple (()), dictionary (), string (”), zero (0), and the special object None
are False in a Boolean context. Everything else is True.

The {% if %} tag accepts and, or, or not for testing multiple variables, or to negate a given variable:
{% i f a t h l e t e l i s t and c o a c h l i s t %}
Both a t h l e t e s and c o a c h e s a r e a v a i l a b l e .
{% e n d i f %}

{% i f not a t h l e t e l i s t %}
There a r e no a t h l e t e s .
{% e n d i f %}

{% i f a t h l e t e l i s t or c o a c h l i s t %}
There a r e some a t h l e t e s or some c o a c h e s .
{% e n d i f %}

{% i f not a t h l e t e l i s t or c o a c h l i s t %}
There a r e no a t h l e t e s or t h e r e a r e some c o a c h e s . (OK, s o
w r i t i n g E n g l i s h t r a n s l a t i o n s o f Boolean l o g i c sounds
s t u p i d ; i t ’ s not our f a u l t . )
{% e n d i f %}

if tags don’t allow and and or clauses within the same tag, because the order of logic would be ambiguous. For
example, this is invalid:
{% i f a t h l e t e l i s t and c o a c h l i s t or c h e e r l e a d e r l i s t %}

The use of parentheses for controlling order of operations is not supported.

There is no elif tag: use nested if tags to accomplish the same thing.

You should close each if with an endif tag, otherwise django will throw a TemplateSyntaxError.

17
3.5.2 for
The for tag allows you to loop over each item in a sequence. Syntax is:
for X in Y

each time through the loop, the template system will render everything between for and endfor.
Example:
<u l >
{% f o r a t h l e t e i n a t h l e t e l i s t %}
< l i >{{ a t h l e t e . name }}</ l i >
{% e n d f o r %}
</u l >

Add reversed to the tag to loop over the list in reverse:


{% f o r a t h l e t e i n athlete list r e v e r s e d %}
...
{% e n d f o r %}

You can’t break out of the loop before the loop is finished: like break or continue.

For tag sets the forloop template that can give you information about the progress in loop:
• forloop.counter: the number of times the loop has been entered (first time == 1)
• forloop.counter0: the same as forloop.counter except zero indexed
• forloop.revcounter: the number of remaining items in the loop
• forloop.revcouner0
• forloop.first: True if the first time through the loop
{% f o r o b j e c t i n o b j e c t s %}
{% i f f o r l o o p . f i r s t %}< l i c l a s s=” f i r s t ”>{% e l s e %}< l i >{% e n d i f %}
{{ o b j e c t }}
</ l i >
{% e n d f o r %}

• forloop.last: True if this is the last time through the loop


• forloop.parentloop: a reference to the forloop object for parent loop

3.5.3 ifequal/ifnotequal
To compare two values and display something (everything between ifequal and endifequal) if they’re equal:
{% i f e q u a l u s e r c u r r e n t u s e r %}
<h1>Welcome! </h1>
{% e n d i f e q u a l %}

Only template variables, strings, integers, and decimal numbers are allowed as arguments to ifequal:
{% ifequal v a r i a b l e 1 %}
{% ifequal v a r i a b l e 1 . 2 3 %}
{% ifequal v a r i a b l e ’ f o o ’ %}
{% ifequal v a r i a b l e ” f o o ” %}

Any other types of variables, such as Python dictionaries, lists, or Booleans, can’t be hard-coded in ifequal:
{% i f e q u a l v a r i a b l e True %}
{% i f e q u a l v a r i a b l e [ 1 , 2 , 3 ] %}
{% i f e q u a l v a r i a b l e { ’ key ’ : ’ v a l u e ’ } %}

18
3.5.4 Comments
A comment:
{# T h i s i s a comment #}

3.6 Filters
Template filters are a simple way of altering the value of variables before they’re displayed:
{{ name | l o w e r }}

this displays the value of the {{ name }} variable after being filtered through the lower filter, which converts
text to lowercase. Use a pipe (—) to apply a filter.

Filtering can be chained and some filters take arguments (always in double quotes):
{{ m y t e x t | e s c a p e | l i n e b r e a k s }}

{{ b i o | t r u n c a t e w o r d s : ” 30 ” }}

Most important filters are:


• addslashes: adds a backslash before any backslash, single quote or double quote (if text included in a
javascript)
• date: formats a date or datetime object according to a format string given in the parameter
• escape: escapes ampersands, quotes, and angle brackets in the given string (ensuring data is valid XML
or XHTML)
• length: returns the length of the value
Django template language has limitations:
• a template cannot set a variable or change the value of a variable
• a template cannot call raw python code

3.7 Using templates in views


First change the view code to use django’s template loading functionality rather than hard-coding the template
paths:
from d j a n g o . template . l o a d e r i m p o r t g e t t e m p l a t e
from d j a n g o . template i m p o r t Context
from d j a n g o . h t t p i m p o r t HttpResponse
import datetime

def current datetime ( request ) :


now = d a t e t i m e . d a t e t i m e . now ( )
t = g e t t e m p l a t e ( ’ c u r r e n t d a t e t i m e . html ’ )
html = t . r e n d e r ( Context ( { ’ c u r r e n t d a t e ’ : now } ) )
return HttpResponse ( html )

we’re using the function django.template.loader.get template() rather than loading the template from the filesys-
tem manually. The get template() function takes a template name as its argument, figures out where the tem-
plate lives on the filesystem, opens that file, and returns a compiled Template object.

If get template() cannot find the template with the given name, it raises a TemplateDoesNotExist exception.

Create a new subdirectory templates/ and create newtemplate current datetime.html:

19
<html><body>I t i s now {{ c u r r e n t d a t e }}. </ body></html>

3.8 render to response


This lets you do the following actions in one line of code:
• load a template
• fill a Context
• return an HttpResponse object with the results of rendered template
A rewritten view is:
from d j a n g o . s h o r t c u t s i m p o r t r e n d e r t o r e s p o n s e
from d j a n g o . h t t p i m p o r t HttpResponse
import datetime

def current datetime ( request ) :


now = d a t e t i m e . d a t e t i m e . now ( )
return r e n d e r t o r e s p o n s e ( ’ c u r r e n t d a t e t i m e . html ’ , { ’ c u r r e n t d a t e ’ : now } )

3.9 The locals() trick


Locals() returns a dictonary mapping all local variable names to their values. The view can be rewritten like
this:
def current datetime ( request ) :
c u r r e n t d a t e = d a t e t i m e . d a t e t i m e . now ( )
return r e n d e r t o r e s p o n s e ( ’ c u r r e n t d a t e t i m e . html ’ , l o c a l s ( ) )

instead of manually specifying the context dictionary as before, we pass the value of locals(), which will include
all variables defined at that point in the function’s execution. This can save you a lot of typing.

One thing to watch out for when using locals() is that it includes every local variable, which may comprise
more variables than you actually want your template to have access to.

A final thing to consider is that locals() incurs a small bit of overhead, because when you call it, Python has to
create the dictionary dynamically. If you specify the context dictionary manually, you avoid this overhead.

3.10 Subdirectories in get template()


It can get unwieldy to store all of your templates in a single directory. You might like to store templates in
subdirectories of your template directory: just include the subdirectory name and a slash before the template
name:
t = g e t t e m p l a t e ( ’ da t ea p p / c u r r e n t d a t e t i m e . html ’ )

3.11 The include template tag


The include template tag allows you to include the contents of another template. The argument to the tag
should be the name of the template to include, and the template name can be either a variable or a hard-coded
(quoted) string, in either single or double quotes.

Example:

20
# include t h e template i n c l u d e s / nav . html
{% i n c l u d e ’ i n c l u d e s / nav . html ’ %}

# include t h e c o n t e n t s o f t h e template whose name i s c o n t a i n e d i n t h e v a r a i b l e template \ name


{% i n c l u d e t e m p l a t e n a m e %}

Included templates are evaluated with the context of the template that’s including them.

3.12 Template inheritance


Template inheritance lets you build a base skeleton template that contains all the common parts of your site
and defines blocks that child templates can override.

Let’s change the current datatime view:


<!DOCTYPE HTML PUBLIC ”−//W3C//DTD HTML 4 . 0 1 / /EN”>
<html l a n g=” en ”>
<head>
< t i t l e >The c u r r e n t time </ t i t l e >
</head>
<body>
<h1>My h e l p f u l timestamp s i t e </h1>
<p>I t i s now {{ c u r r e n t d a t e }}. </p>

<hr>
<p>Thanks f o r v i s i t i n g my s i t e . </p>
</body>
</html>

Let’s create another template for another view:


<!DOCTYPE HTML PUBLIC ”−//W3C//DTD HTML 4 . 0 1 / /EN”>
<html l a n g=” en ”>
<head>
< t i t l e >Fut ure time </ t i t l e >
</head>
<body>
<h1>My h e l p f u l timestamp s i t e </h1>
<p>I n {{ h o u r o f f s e t }} hour ( s ) , i t w i l l be {{ n e x t t i m e }}. </p>

<hr>
<p>Thanks f o r v i s i t i n g my s i t e . </p>
</body>
</html>

we’ve just duplicated a lot of HTML. Solution: factor out the common bits in both template and save them in
a separate template snippets, which are then included in each template.

Store the top bit of the template in header.html:


<!DOCTYPE HTML PUBLIC ”−//W3C//DTD HTML 4 . 0 1 / /EN”>
<html l a n g=” en ”>
<head>

the bottom part in footer.html:


<hr>
<p>Thanks f o r v i s i t i n g my s i t e . </p>
</body>
</html>

but then it would get messy, because we couldn’t include anything else (different stuff on every page).

21
Solution is: django inheritance: instead of defining the snippets that are common, you define the snip-
pets that are different.

Define a base template (a skeleton of your page that child template will later fill in):
<!DOCTYPE HTML PUBLIC ”−//W3C//DTD HTML 4 . 0 1 / /EN”>
<html l a n g=” en ”>
<head>
< t i t l e >{% b l o c k t i t l e %}{% e n d b l o c k %}</ t i t l e >
</head>
<body>
<h1>My h e l p f u l timestamp s i t e </h1>
{% b l o c k c o n t e n t %}{% e n d b l o c k %}
{% b l o c k f o o t e r %}
<hr>
<p>Thanks f o r v i s i t i n g my s i t e . </p>
{% e n d b l o c k %}
</body>
</html>

we’ll use this templates for all the pages on the site: and then the child templates will override/add/leave alone
the contents of the blocks.

The block tag tells the template engine that a child template may override those portions of the template.

Let’s modify the current datetime.html now:


{% e x t e n d s ” b a s e . html ” %}

{% b l o c k t i t l e %}The c u r r e n t t i m e{% e n d b l o c k %}

{% b l o c k c o n t e n t %}
<p>I t i s now {{ c u r r e n t d a t e }}. </p>
{% e n d b l o c k %}

now the template only contains code that’s unique to that template (no redundancy).

Inheritance doesn’t affect the way the context works, and you can use as many levels of inheritance as needed.
One common way of using inheritance is the following three-level approach:
• create a base.html template that holds the main look and feel of your site (rarely changes)
• create a base SECTION.html template for each section of your site (base photos.html and base forum.html,...).
These templates extend base.html and include section-specific styles/design.
• create individual templates for each type of page, such as forum page or photo gallery. These templates
extend the appropriate section template.
Useful info:
• If you find yourself duplicating code in a number of templates, it probably means you should move that
code to a block in a parent template.
• If you need to get the content of the block from the parent template, the {{ block.super }} variable will
do the trick. This is useful if you want to add to the contents of a parent block instead of completely
overriding it.
• The template name you pass to extends is loaded using the same method that get template() uses. That
is, the template name is appended to your TEMPLATE DIRS setting.

22
4 Interacting with database
You can of course hard-code the the text to view (use python library to execute a SQL query):
from d j a n g o . s h o r t c u t s i m p o r t r e n d e r t o r e s p o n s e
i m p o r t MySQLdb

def book list ( request ) :


db = MySQLdb . c o n n e c t ( u s e r= ’me ’ , db= ’ mydb ’ , passwd= ’ s e c r e t ’ , h o s t= ’ l o c a l h o s t ’ )
c u r s o r = db . c u r s o r ( )
c u r s o r . e x e c u t e ( ’SELECT name FROM boo ks ORDER BY name ’ )
names = [ row [ 0 ] f o r row i n c u r s o r . f e t c h a l l ( ) ]
db . c l o s e ( )
return r e n d e r t o r e s p o n s e ( ’ b o o k l i s t . html ’ , { ’ names ’ : names } )

A number of problems exits: hard-coding the database connection parameters ; we have to create a connection,
create a cursor, execute a statement and close the connection ; it ties us to mysql.

4.1 Yout first model


A Django model is a description of the data in your database, represented as Python code (TABLES). Django
uses a model to execute SQL code behind the scenes and return convenient Python data structures representing
the rows in your database tables.

Finally, we should note that Django includes a utility that can generate models by introspecting an exist-
ing database. This is useful for quickly getting up and running with legacy data.

First step: declaring the database layout. Edit the models.py file that was created by the startapp command:
from d j a n g o . db i m p o r t models

c l a s s P u b l i s h e r ( models . Model ) :
name = models . C h a r F i e l d ( m a x l e n g t h =30)
a d d r e s s = models . C h a r F i e l d ( m a x l e n g t h =50)
c i t y = models . C h a r F i e l d ( m a x l e n g t h =60)
s t a t e p r o v i n c e = models . C h a r F i e l d ( m a x l e n g t h =30)
c o u n t r y = models . C h a r F i e l d ( m a x l e n g t h =50)
w e b s i t e = models . URLField ( )

def unicode ( self ) :


return s e l f . name

c l a s s Author ( models . Model ) :


s a l u t a t i o n = models . C h a r F i e l d ( m a x l e n g t h =10)
f i r s t n a m e = models . C h a r F i e l d ( m a x l e n g t h =30)
l a s t n a m e = models . C h a r F i e l d ( m a x l e n g t h =40)
e m a i l = models . E m a i l F i e l d ( )
h e a d s h o t = models . I m a g e F i e l d ( u p l o a d t o= ’ /home/ e l e a n o r / P r o j e c t s / d j a n g o 2 / e l e a n o r / i m a g e s ’ )

def unicode ( self ) :


return u ’%s %s ’ % ( s e l f . f i r s t n a m e , s e l f . last name )

c l a s s Book ( models . Model ) :


t i t l e = models . C h a r F i e l d ( m a x l e n g t h =100)
a u t h o r s = models . ManyToManyField ( Author )
p u b l i s h e r = models . ForeignKey ( P u b l i s h e r )
p u b l i c a t i o n d a t e = models . D a t e F i e l d ( )

def unicode ( self ) :


return s e l f . t i t l e

Explanation:

23
• each model is represented by a python class that is a subclass of django.db.models.Model: the parent
class Model contains all the machinery necessary to make these objects capable of interacting with a
database - and we only define the fields.
• each model corresponds to a single database table and each attribute to a column in that table (the
attribute name == column’s name and the type of the field (CharField) == database column type
(varchar)).
• we haven’t explicitly defined a primary key in any of these models. Unless you instruct it otherwise,
Django automatically gives every model an integer primary key field called id. Each Django model is
required to have a single-column primary key.

4.2 Installing the model


Number of steps:
• add the books app to the list of installed apps in settings.py:
INSTALLED APPS = (
’ d j a n g o . c o n t r i b . auth ’ ,
’ django . c o n t r i b . contenttypes ’ ,
’ django . c o n t r i b . s e s s i o n s ’ ,
’ django . c o n t r i b . s i t e s ’ ,
’ e l e a n o r . bo oks ’ ,
)

• validate the models:


python manage . py v a l i d a t e

• print the sql code:


python manage . py s q l a l l boo ks

• create the database tables:


python manage . py syncdb

Sync looks at all of the models in each app in your INSTALLED APPS setting, checks the database to see
whether the appropriate tables exist yet, and creates the tables if they don’t yet exist. Note that syncdb does
not sync changes in models or deletions of models; if you make a change to a model or delete a model, and you
want to update the database, syncdb will not handle that.

5 Django administration site


For certain web sites, an admin interface is an essential part of infrastructure: web based interface, limited to
trusted site administrators, that enables the adding, editing and deletion of site content.

5.1 Activating the admin interface


• add django.contrib.admin to your INSTALLED APPS
• add admin metadata to your models: edit the <myapp>/admin.py
Not all models should be editable by admin users, so you need to mark models that should have an admin
interface:

24
from d j a n g o . c o n t r i b i m p o r t admin
from <m y p r o j e c t >.<myapp>. models i m p o r t MyModel
admin . s i t e . r e g i s t e r ( MyModel )

from d j a n g o . c o n t r i b i m p o r t admin
from e l e a n o r . book s . models i m p o r t P u b l i s h e r
admin . s i t e . r e g i s t e r ( P u b l i s h e r )

• add your models:


from d j a n g o . db i m p o r t models

c l a s s P u b l i s h e r ( models . Model ) :
name = models . C h a r F i e l d ( m a x l e n g t h =30)
a d d r e s s = models . C h a r F i e l d ( m a x l e n g t h =50)
c i t y = models . C h a r F i e l d ( m a x l e n g t h =60)
s t a t e p r o v i n c e = models . C h a r F i e l d ( m a x l e n g t h =30)
c o u n t r y = models . C h a r F i e l d ( m a x l e n g t h =50)
w e b s i t e = models . URLField ( )

def unicode ( self ) :


return s e l f . name

• run ”python manage.py syncdb”: installs extra database tables the admin interface uses
• add the URL pattern to your urls.py:
from d j a n g o . c o n f . u r l s . d e f a u l t s i m p o r t ∗
from d j a n g o . c o n t r i b i m p o r t admin
admin . a u t o d i s c o v e r ( )

( r ’ ˆ admin / ’ , i n c l u d e ( ’ d j a n g o . c o n t r i b . admin . u r l s ’ ) ) ,

You’ll need to restart the development server to see your changes. Normally, the server auto-reloads code every
time you modify a file, but the action of creating a new file doesn’t trigger the auto-reloading logic.

Each object given an Admin declaration shows up on the main index page.

5.2 Users, Groups and Permissions


The admin interface has a user permissions system that you can use to give other users access only to the
portions of the interface that they need.

User objects have the standard username, password, e-mail, and real name fields you might expect, along
with a set of fields that define what the user is allowed to do in the admin interface. First, there’s a set of three
flags:

• is active: if the user is active at all

• is staff: if user is allowed to login to the admin interface

• superuser: gives the user full access to admin interface

5.3 Customizing the admin interface


Change the admin declaration in admin.py:

25
from d j a n g o . c o n t r i b i m p o r t admin
from e l e a n o r . books . models i m p o r t Book

c l a s s BookAdmin ( admin . ModelAdmin ) :


l i s t d i s p l a y = ( ’ t i t l e ’ , ’ publisher ’ , ’ publication date ’ )
l i s t f i l t e r = ( ’ publisher ’ , ’ publication date ’ )
o r d e r i n g = ( ’−p u b l i c a t i o n d a t e ’ , )
s e a r c h f i e l d s = ( ’ t i t l e ’ ,)

admin . s i t e . r e g i s t e r ( Book , BookAdmin )

Each of those lines instructed the admin interface to construct a different piece of interface:

• list display: controls which columns to appear in the change list table (default: displays only a single
column that contains the object’s string representation)
• list filter: creates the filtering bar on the right side of the list (filtering by date - can be any field)

• ordering: the order in which the objects are presented in the admin interface (prefixing a field by minus
sign reverses the given order)

• search fields: creates a field that allows text searches

5.4 Customizing the admin interface’s look and feel


The TEMPLATE DIRS specifies a list of directories to check when loading django templates. To customize
django’s admin templates, copy the relevant stock admin template from the django distribution into that
directory.
cp / u s r / l i b / python2 . 6 / s i t e −p a c k a g e s / d j a n g o / c o n t r i b / admin / t e m p l a t e s / admin / b a s e s i t e . html t e m p l a t e s /

Then just edit the admin base.html to replace the generic django text with your own.

5.5 Customizing the admin index page


By default, it displays all available applications, according to your INSTALLED APPS setting, sorted by the
name of the application. You might, however, want to change this order to make it easier to find the applications
you’re looking for.

You should edit the admin/index.html template. Edit the file, and you’ll see it uses a template tag called
get admin app list as app list. This tag retrieves every installed Django application. Instead of using the
tag, you can hard-code links to object-specific admin pages in whatever way you think is best.

6 Form processing
6.1 Search
Often the difference between the success or failure of a site is the quality of its search. We’ll start by adding
the search view to our URLconf (eleanor.urls):
( r ’ ˆ search /$ ’ , ’ e l e a n o r . boo ks . v i e w s . s e a r c h ’ ) ,

Then we write the search view (eleanor.books.view):

26
from d j a n g o . db . models i m p o r t Q
from d j a n g o . s h o r t c u t s i m p o r t r e n d e r t o r e s p o n s e
from models i m p o r t Book

def search ( request ) :


q u e r y = r e q u e s t .GET. g e t ( ’ q ’ , ’ ’ )
i f query :
qset = (
Q( t i t l e i c o n t a i n s =q u e r y ) |
Q( a u t h o r s f i r s t n a m e i c o n t a i n s=q u e r y ) |
Q( a u t h o r s l a s t n a m e i c o n t a i n s=q u e r y )
)
r e s u l t s = Book . o b j e c t s . f i l t e r ( q s e t ) . d i s t i n c t ( )
else :
results = []
return r e n d e r t o r e s p o n s e ( ” s e a r c h . html ” , { ” r e s u l t s ” : r e s u l t s , ” query ” : query })

Explanation:
• request.GET is how you access GET data from django (POST is accessed through request.POST). GET
and POST are the two methods that browsers use to send data to a server (instruct the browser to submit
the form data to the URL /book/search/ using the GET method):
<form a c t i o n=” / boo ks / s e a r c h / ” method=” g e t ”>

• the get() method on request.GET looks for a GET parameter named q and return an empty string if that
parameter wasn’t submitted.
• Q objects are used to build complex queries (here we’re searching for any books where either the title or
name matches the search).
• icontains == a case-insensitive seach that uses the SQL like operator in the underlying database
• distinct() eliminates any duplicate values
We also have to create the template:
<!DOCTYPE HTML PUBLIC ”−//W3C//DTD HTML 4 . 0 1 / /EN”>
<html l a n g=” en ”>
<head>
< t i t l e >S e a r c h{% i f q u e r y %} R e s u l t s{% e n d i f %}</ t i t l e >
</head>
<body>
<h1>S e a r c h </h1>
<form a c t i o n=” . ” method=”GET”>
< l a b e l f o r=”q”>S e a r c h : </ l a b e l >
<i n p u t t y p e=” t e x t ” name=”q” v a l u e=” {{ q u e r y | e s c a p e }} ”>
<i n p u t t y p e=” submit ” v a l u e=” S e a r c h ”>
</form>

{% i f q u e r y %}
<h2>R e s u l t s f o r ” {{ q u e r y | e s c a p e }} ” : </h2>

{% i f r e s u l t s %}
<u l >
{% f o r book i n r e s u l t s %}
< l i >{{ book | e s c a p e }}</ l 1 >
{% e n d f o r %}
</u l >
{% e l s e %}
<p>No books found </p>
{% e n d i f %}
{% e n d i f %}
</body>
</html>

Explanation:

27
• the form’s action is ’.’ which means ”the current url”

• we reinserted the query back into the <input> which lets readers easily refine their searches without
having to retype what they searched for.

• everywhere query and book is used, we pass it through the escape filter to make sure that any potentially
malicious search text is filtered out before being inserted into the page.

6.2 The perfect form


• It should ask the user for some information, obviously. Accessibility and usability matter here, so smart
use of the HTML <label> element and useful contextual help are important.

• The submitted data should be subjected to extensive validation. The golden rule of Web application
security is “never trust incoming data,” so validation is essential.

• If the user has made any mistakes, the form should be redisplayed with detailed, informative error mes-
sages. The original data should be prefilled, to save the user from having to reenter everything.

• The form should continue to redisplay until all of the fields have been correctly filled.

6.3 Creating a feedback form


Let’s build a simple feedback form and use it to illustrate Django’s forms framework in action.

Let’s start by adding the url in urls.py:


( r ’ ˆ contact /$ ’ , ’ e l e a n o r . bo oks . v i e w s . c o n t a c t ’ ) ,

Create the new form and save it in forms.py within application directory:
from d j a n g o i m p o r t f o r m s

TOPIC CHOICES = (
( ’ g e n e r a l ’ , ’ General enquiry ’ ) ,
( ’ bug ’ , ’ Bug r e p o r t ’ ) ,
( ’ suggestion ’ , ’ Suggestion ’ ) ,
)

c l a s s ContactForm ( f o r m s . Form ) :
t o p i c = f o r m s . C h o i c e F i e l d ( c h o i c e s=TOPIC CHOICES)
message = f o r m s . C h a r F i e l d ( )
s e n d e r = f o r m s . E m a i l F i e l d ( r e q u i r e d=F a l s e )

a django form is a subclass of django.newforms.Form and contains a number of field classes (topic, message,
sender, ...). The form object knows how to do a number of useful things: validate a collection of data, generate
its own HTML widgets, and draw the entire form for us.

views.py:
from f o r m s i m p o r t ContactForm

def contact ( request ) :


form = ContactForm ( )
return r e n d e r t o r e s p o n s e ( ’ c o n t a c t . html ’ , { ’ form ’ : form } )

contact.html:

28
<!DOCTYPE HTML PUBLIC ”−//W3C//DTD HTML 4 . 0 1 / /EN”>
<html l a n g=” en ”>
<head>
< t i t l e >Contact us </ t i t l e >
</head>
<body>
<h1>Contact us </h1>
<form a c t i o n=” . ” method=”POST”>
<t a b l e >
{{ form . a s t a b l e }}
</ t a b l e >
<p><i n p u t t y p e=” submit ” v a l u e=” Submit ”></p>
</form>
</body>
</html>

Explanation:
• form.as table: form is our ContactForm instance, passed to render to response, as table is a method on
that object that renders the form as a sequence of table rows - this is generated:
<t r >
<th><l a b e l f o r=” i d t o p i c ”>Topic : </ l a b e l ></th>
<td>
< s e l e c t name=” t o p i c ” i d=” i d t o p i c ”>
<o p t i o n v a l u e=” g e n e r a l ”>G e n e r a l e n q u i r y </o p t i o n >
<o p t i o n v a l u e=” bug ”>Bug r e p o r t </o p t i o n >
<o p t i o n v a l u e=” s u g g e s t i o n ”>S u g g e s t i o n </o p t i o n >
</ s e l e c t >
</td>
</t r >
<t r >
<th><l a b e l f o r=” i d m e s s a g e ”>Message : </ l a b e l ></th>
<td><i n p u t t y p e=” t e x t ” name=” message ” i d=” i d m e s s a g e ” /></td>
</t r >
<t r >
<th><l a b e l f o r=” i d s e n d e r ”>S e n d e r : </ l a b e l ></th>
<td><i n p u t t y p e=” t e x t ” name=” s e n d e r ” i d=” i d s e n d e r ” /></td>
</t r >

the table and form tags are not included: define those yourself
We can add arguments to the ”message = forms.CharField(widget=forms.Textarea())”:
• widget=forms.Textarea(): each field type has a default widget, but we can override the default or provide
a custom widget of your own
• initial=”test”: initial data of the form

6.4 Processing the submission


When the form passes the validation rules, we need to do something useful with the data: construct and send
a email containing the user’s feedback.

We need to tell if the data is indeed valid and then access the data:
form = ContactForm ( r e q u e s t . POST)
i f form . i s v a l i d ( ) :
t o p i c = form . c l e a n e d d a t a [ ’ t o p i c ’ ]
message = form . c l e a n e d d a t a [ ’ message ’ ]
s e n d e r = form . c l e a n e d d a t a . g e t ( ’ s e n d e r ’ , ’ no repl y@exa mple . com ’ )
# ...

Explanation:
• we use form.clean data to access the data.

29
• since the sender is not required, we provide a default when it’s missing
Finally, we need to record the user’s feedback: (email it to a site admin):
from d j a n g o . c o r e . m a i l i m p o r t s e n d m a i l

# ...

send mail (
’ Feedback from your s i t e , t o p i c : %s ’ % t o p i c ,
message , s e n d e r ,
[ ’ a d m i n i s t r a t o r @ e x a m p l e . com ’ ]
)

the send mail function has four arguments:


• subject
• body
• from address
• list of recipient addresses
• is a convenient wrapper around Django’s EmailMessage class, which provides advanced features such as
attachments, multipart emails, and full control over email headers.
Having sent the feedback email, we’ll redirect our user to a static confirmation page. The finished view function
looks like this:
from django . http import HttpResponseRedirect
from django . s h o r t c u t s import r e n d e r t o r e s p o n s e
from django . c o r e . mail import send mail
from f o r m s i m p o r t ContactForm

def contact ( request ) :


i f r e q u e s t . method == ’POST ’ :
form = ContactForm ( r e q u e s t . POST)
i f form . i s v a l i d ( ) :
t o p i c = form . c l e a n d a t a [ ’ t o p i c ’ ]
message = form . c l e a n d a t a [ ’ message ’ ]
s e n d e r = form . c l e a n d a t a . g e t ( ’ s e n d e r ’ , ’ no repl y@ex ample . com ’ )
send mail (
’ Feedback from your s i t e , t o p i c : %s ’ % t o p i c ,
message , s e n d e r ,
[ ’ a d m i n i s t r a t o r @ e x a m p l e . com ’ ]
)
return H t t p R e s p o n s e R e d i r e c t ( ’ / c o n t a c t / t h a n k s / ’ )
else :
form = ContactForm ( )
return r e n d e r t o r e s p o n s e ( ’ c o n t a c t . html ’ , { ’ form ’ : form } )

6.5 A custom look and feel


The quickest way to customize the form’s presentation is with CSS. The list of errors in particular could do with
some visual enhancement, and the ul has a class attribute of errorlist for that exact purpose. The following
CSS really makes our errors stand out:
< s t y l e t y p e=” t e x t / c s s ”>
ul . e r r o r l i s t {
margin : 0 ;
padding : 0 ;
}
. errorlist li {
background−c o l o r : r e d ;
c o l o r : white ;

30
display : block ;
f o n t −s i z e : 10 px ;
margin : 0 0 3 px ;
padding : 4 px 5 px ;
}
</ s t y l e >

Each field widget (<input type=”text”>, <textarea>, ...) can be rendered by accessing {{ form.fieldname }}.
Any errors associated with a field are available as {{ form.fieldname.errors }}.
We can use these form variables to construct a custom template for our contact form:
<form a c t i o n=” . ” method=”POST”>
<d i v c l a s s=” f i e l d W r a p p e r ”>
{{ form . t o p i c . e r r o r s }}
< l a b e l f o r=” i d t o p i c ”>Kind o f f e e d b a c k : </ l a b e l >
{{ form . t o p i c }}
</div>
<d i v c l a s s=” f i e l d W r a p p e r ”>
{{ form . message . e r r o r s }}
< l a b e l f o r=” i d m e s s a g e ”>Your message : </ l a b e l >
{{ form . message }}
</div>
<d i v c l a s s=” f i e l d W r a p p e r ”>
{{ form . s e n d e r . e r r o r s }}
< l a b e l f o r=” i d s e n d e r ”>Your e m a i l ( o p t i o n a l ) : </ l a b e l >
{{ form . s e n d e r }}
</div>
<p><i n p u t t y p e=” submit ” v a l u e=” Submit ”></p>
</form>

6.6 Creating forms from models


Our Publisher model class says that a publisher has a name, address, city, state province, country, and website:
use form for model() function to take fields from model.
from models i m p o r t P u b l i s h e r
from d j a n g o . newforms i m p o r t f o r m f o r m o d e l

PublisherForm = f o r m f o r m o d e l ( P u b l i s h e r )

You can use PublisherForm like this:


from f o r m s i m p o r t P u b l i s h e r F o r m

def add publisher ( request ) :


i f r e q u e s t . method == ’POST ’ :
form = P u b l i s h e r F o r m ( r e q u e s t . POST)
i f form . i s v a l i d ( ) :
form . s a v e ( )
return H t t p R e s p o n s e R e d i r e c t ( ’ / a d d p u b l i s h e r / t h a n k s / ’ )
else :
form = P u b l i s h e r F o r m ( )
return r e n d e r t o r e s p o n s e ( ’ boo ks / a d d p u b l i s h e r . html ’ , { ’ form ’ : form } )

There’s one more shortcut being demonstrated here. Since forms derived from models are often used to save
new instances of the model to the database, the form class created by form for model includes a convenient
save() method. This deals with the common case; you’re welcome to ignore it if you want to do something a
bit more involved with the submitted data.

form for instance() is a related method that can create a preinitialized form from an instance of a model
class. This is useful for creating “edit” forms.

6.7 All available form fields


Core field arguments:

31
• required: if the value is required

• label: a label for this field (used when displayed in a form)

• initial: the initial value to use when rendering

• widget: a Widget class to use when rendering this field

• help text: descriptive text for this field

• error messages: overrides the default messages that the field will raise

• validators: let you provide a list of validation functions for this field

Those are:

• BooleanField: CheckboxInput

• CharField: TextInput

• ChoiceField: Select

• TypedChoiceField: Select

• DateField: DateInput

• DateTimeField: DateTimeInput

• DecimalField: TextInput

• EmailField: TextInput

• FileField: FileInput

• FilePathField: Select

• FloatField: TextInput

• ImageField: FileInput

• IntegerField: TextInput

• IPAddressField: TextInput

• MultipleChoiceField: SelectMultiple

• NullBooleanField: NullBooleanSelect

• RegexField: TextInput

• SlugField: TextInput

• TimeField: TextInput

• URLField: TextInput

• ComboField: TextInput

• MultiValueField: TextInput

32
• SplitDateTimeField: SplitDateTimeWidget

• ModelChoiceField: Allows the selection of a single model object, suitable for representing a foreign key.
A single argument is required:

– ModelChoiceField.queryset: A QuerySet of model objects from which the choices for the field will
be derived, and which will be used to validate the user’s selection.
– ModelChoiceField.empty label: By default the select widget used by ModelChoiceField will have
a an empty choice at the top of the list. You can change the text of this label (which is ”———”
by default) with the empty label attribute, or you can disable the empty label entirely by setting
empty label to None:

• ModelMultipleChoiceField: Allows the selection of one or more model objects, suitable for representing
a many-to-many relation. As with ModelChoiceField, you can use label from instance to customize the
object representations, and queryset is a required parameter.

If the built-in Field classes don’t meet your needs, you can easily create custom Field classes. To do this, just
create a subclass of django.forms.Field. Its only requirements are that it implement a clean() method and that
its init () method accept the core arguments mentioned above (required, label, initial, widget, help text).

7 Advanced views and URLconfs


7.1 Streamlining function imports
Each entry in URLconf includes its associated view function, which means it’s necessary to import the view
function at the top of the module:
from d j a n g o . c o n f . u r l s . d e f a u l t s i m p o r t ∗
from e l e a n o r . v i e w s i m p o r t c u r r e n t d a t e t i m e , h o u r s a h e a d , h o u r s b e h i n d , n o w i n c h i c a g o , n o w i n l o n d o n

urlpatterns = patterns ( ’ ’ ,
( r ’ ˆnow/ $ ’ , c u r r e n t d a t e t i m e ) ,
)

but when django app grows in complexity, its URLconf grows too: import is necessary for every view function,
but you can avoid that by importing the view module itself:
from d j a n g o . c o n f . u r l s . d e f a u l t s i m p o r t ∗
from e l e a n o r i m p o r t v i e w s

urlpatterns = patterns ( ’ ’ ,
( r ’ ˆnow/ $ ’ , v i e w s . c u r r e n t d a t e t i m e ) ,
)

You can also pass a string containing the module name and function name rather than the function object itself:
from d j a n g o . c o n f . u r l s . d e f a u l t s i m p o r t ∗

urlpatterns = patterns ( ’ ’ ,
( r ’ ˆnow/ $ ’ , ’ e l e a n o r . v i e w s . c u r r e n t d a t e t i m e ’ ) ,
)

using this, it’s no longer necessary to import the view functions (django automatically imports the appropriate
view function the first time it’s needed).

If using the string technique, you can factor out the common view prefix:

33
from d j a n g o . c o n f . u r l s . d e f a u l t s i m p o r t ∗

u r l p a t t e r n s = patterns ( ’ eleanor . views ’ ,


( r ’ ˆnow/ $ ’ , ’ c u r r e n t d a t e t i m e ’ ) ,
)

you don’t put a trailing dot (”.”) in the prefix, nor do you put a leading dot in the view strings. Django puts
those in automatically.

7.2 Using multiple view prefixes


If you use the string technique, you’ll probably end up mixing views to the point where the views in your
URLconf won’t have a common prefix: add multiple patterns() objects together:
from d j a n g o . c o n f . u r l s . d e f a u l t s i m p o r t ∗

u r l p a t t e r n s = patterns ( ’ mysite . views ’ ,


( r ’ ˆ/? $ ’ , ’ a r c h i v e i n d e x ’ ) ,
( r ’ ˆ ( \ d { 4 } ) / ( [ a−z ] { 3 } ) / $ ’ , ’ a r c h i v e m o n t h ’ ) ,
)

u r l p a t t e r n s += p a t t e r n s ( ’ weblog . v i e w s ’ ,
( r ’ ˆ t a g / ( \w+)/ $ ’ , ’ t a g ’ ) ,
)

7.3 Using named groups


So far we’ve used non-named regular expression groups - we put parentheses around parts of the URL we wanted
to capture and django passed that captured text to the view function as a positional argument. But it is also
possible to use named regular expression groups to capture URL bits and pass them as keyword arguments to
a view.

The syntax for named regular expression group is:


# name == name o f t h e group ; p a t t e r n == some p a t t e r n t o match
( ?P<name>p a t t e r n ) ,

Example with non-named groups:


from d j a n g o . c o n f . u r l s . d e f a u l t s i m p o r t ∗
from m y s i t e i m p o r t v i e w s

urlpatterns = patterns ( ’ ’ ,
( r ’ ˆ a r t i c l e s /(\d{4}) /$ ’ , views . y e a r a r c h i v e ) ,
( r ’ ˆ a r t i c l e s /(\d{4}) /(\d{2}) /$ ’ , views . month archive ) ,
)

Example with named groups:


from d j a n g o . c o n f . u r l s . d e f a u l t s i m p o r t ∗
from m y s i t e i m p o r t v i e w s

urlpatterns = patterns ( ’ ’ ,
( r ’ ˆ a r t i c l e s / ( ?P<y e a r >\d { 4 } ) / $ ’ , v i e w s . y e a r a r c h i v e ) ,
( r ’ ˆ a r t i c l e s / ( ?P<y e a r >\d { 4 } ) / ( ?P<month>\d { 2 } ) / $ ’ , v i e w s . m o n t h a r c h i v e ) ,
)

the captured values are passed to view functions as keyword arguments rather than positional
arguments.
Example: function call with non-named groups:
month archive ( request , ’ 2006 ’ , ’ 03 ’ )

34
Example: function call with named groups:
m o n t h a r c h i v e ( r e q u e s t , y e a r= ’ 2006 ’ , month= ’ 03 ’ )

7.4 Passing extra options to view functions


If we have almost the same view functions:
# u r l s . py

from d j a n g o . c o n f . u r l s . d e f a u l t s i m p o r t ∗
from m y s i t e i m p o r t v i e w s

urlpatterns = patterns ( ’ ’ ,
( r ’ ˆ foo /$ ’ , views . foo view ) ,
( r ’ ˆ ba r / $ ’ , v i e w s . b a r v i e w ) ,
)

# v i e w s . py

from d j a n g o . s h o r t c u t s i m p o r t r e n d e r t o r e s p o n s e
from m y s i t e . models i m p o r t MyModel

def foo view ( request ) :


m l i s t = MyModel . o b j e c t s . f i l t e r ( i s n e w=True )
return r e n d e r t o r e s p o n s e ( ’ t e m p l a t e 1 . html ’ , { ’ m l i s t ’ : m l i s t })

def bar view ( request ) :


m l i s t = MyModel . o b j e c t s . f i l t e r ( i s n e w=True )
return r e n d e r t o r e s p o n s e ( ’ t e m p l a t e 2 . html ’ , { ’ m l i s t ’ : m l i s t })

To solve this use optional URLconf parameter. Each pattern in URLconf may include a third item: a dictionary
of keyword arguments to pass to the view function:
# u r l s . py

from d j a n g o . c o n f . u r l s . d e f a u l t s i m p o r t ∗
from m y s i t e i m p o r t v i e w s

urlpatterns = patterns ( ’ ’ ,
( r ’ ˆ f o o /$ ’ , views . foobar view , { ’ template name ’ : ’ t e m p l a t e 1 . html ’ } ) ,
( r ’ ˆ ba r / $ ’ , v i e w s . f o o b a r v i e w , { ’ t e m p l a t e n a m e ’ : ’ t e m p l a t e 2 . html ’ } ) ,
)

# v i e w s . py

from d j a n g o . s h o r t c u t s i m p o r t r e n d e r t o r e s p o n s e
from m y s i t e . models i m p o r t MyModel

d e f f o o b a r v i e w ( request , template name ) :


m l i s t = MyModel . o b j e c t s . f i l t e r ( i s n e w=True )
return r e n d e r t o r e s p o n s e ( template name , { ’ m l i s t ’ : m l i s t })

the URLconf specifies template name in the URLconf. The view function treats it as just another parameter.
This extra URLconf options technique is a nice way of sending additional information to your view functions
with minimal fuss.

Every Python class has a name attribute that returns the class name. This feature is useful at times
like this, when we don’t know the type of class until runtime. For example, the BlogEntry class’s name is
the string ’BlogEntry’.

When there’s a conflict, extra URLconf parameters get precedence over captured parameters. In other words,
if your URLconf captures a named-group variable and an extra URLconf parameter includes a variable with
the same name, the extra URLconf parameter value will be used:

35
from d j a n g o . c o n f . u r l s . d e f a u l t s i m p o r t ∗

urlpatterns = patterns ( ’ ’ ,
( r ’ ˆ mydata / ( ?P<i d >\d+)/ $ ’ , v i e w s . my view , { ’ i d ’ : 3 } ) ,
)

both the regular expression and the extra dictionary include an id. The hard-coded id gets precedence. That
means any request (e.g., /mydata/2/ or /mydata/432432/) will be treated as if id is set to 3, regardless of the
value captured in the URL.

7.5 Using default view arguments


You can specify default parameters for a view’s arguments (which value to use for a parameter by default if
none is specified):
u r l s . py

from d j a n g o . c o n f . u r l s . d e f a u l t s i m p o r t ∗

urlpatterns = patterns ( ’ ’ ,
( r ’ ˆ b l o g / $ ’ , v i e w s . page ) ,
( r ’ ˆ b l o g / page ( ?P<num>\d+)/ $ ’ , v i e w s . page ) ,
)

# v i e w s . py

d e f page ( r e q u e s t , num=” 1 ” ) :
# Output t h e a p p r o p r i a t e page o f b l o g e n t r i e s , a c c o r d i n g t o num .
# ...

both URL patterns point to the same view — views.page — but the first pattern doesn’t capture anything from
the URL. If the first pattern matches, the page() function will use its default argument for num, ”1”. If the
second pattern matches, page() will use whatever num value was captured by the regular expression.

Don’t put URL logic in the view. Each captured argument is sent to the view as a plain Python
string, regardless of what sort of match the regular expression makes.

7.6 Including other URLconfs


URLconf can include other URLconf modules:
from d j a n g o . c o n f . u r l s . d e f a u l t s i m p o r t ∗

urlpatterns = patterns ( ’ ’ ,
( r ’ ˆ weblog / ’ , i n c l u d e ( ’ m y s i t e . b l o g . u r l s ’ ) ) ,
( r ’ ˆ photos / ’ , i n c l u d e ( ’ mysite . photos . u r l s ’ ) ) ,
( r ’ ˆ about / $ ’ , ’ m y s i t e . v i e w s . about ’ ) ,
)

The regular expressions in this example that point to an include() do not have a $ (end-of-string match char-
acter) but do include a trailing slash. Whenever Django encounters include(), it chops off whatever part of the
URL matched up to that point and sends the remaining string to the included URLconf for further processing.

So the mysite.blog.urls would look like:


from d j a n g o . c o n f . u r l s . d e f a u l t s i m p o r t ∗

urlpatterns = patterns ( ’ ’ ,
( r ’ ˆ ( \ d\d\d\d ) / $ ’ , ’ m y s i t e . b l o g . v i e w s . y e a r d e t a i l ’ ) ,
( r ’ ˆ ( \ d\d\d\d ) / ( \ d\d ) / $ ’ , ’ m y s i t e . b l o g . v i e w s . m o n t h d e t a i l ’ ) ,
)

36
Handled requests:

• /weblog/2007/ : django strips weblog/ and the remaining part 2007/ is sent to mysite.blog.urls where it
matches the first line

• /about/ : matches mysite.views.about (you can mix include patterns with non-include patterns)

8 Generic views
Take certain common idioms and patterns found in view development and abstract them so that you can quickly
write common views of data without having to write too much code.

Generic views do the following:

• perform common simple tasks: redirect to a different page and render a given template

• display and list and detail pages for a single object

• present date-based objects in year/month/day archive pages

8.1 Using generic views


All of these views are used by creating configuration dictionaries in your URLconf files and passing those dic-
tionaries as the third member of the URLconf tuple for a given pattern.

Example:
from d j a n g o . c o n f . u r l s . d e f a u l t s i m p o r t ∗
from d j a n g o . v i e w s . g e n e r i c . s i m p l e i m p o r t d i r e c t t o t e m p l a t e

urlpatterns = patterns ( ’ ’ ,
( ’ ˆ about / $ ’ , d i r e c t t o t e m p l a t e , { ’ t e m p l a t e ’ : ’ about . html ’ } ) ,
)

Explanation:

• direct to template grabs information from the extra-parameters dictionary and uses that information when
rendering the view

• direct to template returns an HttpResponse

• (w+) in URLconf accpets only letters and numbers (any malicious characters - dots and slashes - will be
rejected by the URL resolver before they reach the view itself)

Generic view is a regular view function like any other - and that’s why we can reuse it inside our own views: map
URLs of the form /about/<whatever>.html to staticaly rendered about/<whatever>.html. Edit URLconf:
from m y s i t e . books . v i e w s i m p o r t a b o u t p a g e s

urlpatterns = patterns ( ’ ’ ,
( ’ ˆ about / (w+)/ $ ’ , a b o u t p a g e s ) ,
)

Then write about pages view:

37
from d j a n g o . h t t p i m p o r t Http404
from d j a n g o . template i m p o r t T e mp l at e Do esN o tE xi st
from d j a n g o . v i e w s . g e n e r i c . s i m p l e i m p o r t d i r e c t t o t e m p l a t e

d e f a b o u t p a g e s ( r e q u e s t , page ) :
try :
return d i r e c t t o t e m p l a t e ( r e q u e s t , template=” about/%s . html ” % page )
e x c e p t Templat e Do esN o t Exi st :
r a i s e Http404 ( )

How do we deal with missing templates: we don’t want a nonexistent template to cause a server error, so we
catch TemplateDoesNotExist exception and return 404 error instead.

8.2 Generic views of objects


Let’s look at the ”object list” generic view (using Publisher object):
from d j a n g o . db i m p o r t models

c l a s s P u b l i s h e r ( models . Model ) :
name = models . C h a r F i e l d ( m a x l e n g t h =30)
a d d r e s s = models . C h a r F i e l d ( m a x l e n g t h =50)
c i t y = models . C h a r F i e l d ( m a x l e n g t h =60)
s t a t e p r o v i n c e = models . C h a r F i e l d ( m a x l e n g t h =30)
c o u n t r y = models . C h a r F i e l d ( m a x l e n g t h =50)
w e b s i t e = models . URLField ( )

def unicode ( self ) :


return s e l f . name

c l a s s Meta :
o r d e r i n g = [ ”−name” ]

To build a list of all books, use URLconf like this:


from d j a n g o . c o n f . u r l s . d e f a u l t s i m p o r t ∗
from d j a n g o . v i e w s . g e n e r i c i m p o r t l i s t d e t a i l
from m y s i t e . books . models i m p o r t P u b l i s h e r

publisher info = {
” queryset ” : Publisher . objects . a l l () ,
}

urlpatterns = patterns ( ’ ’ ,
( r ’ ˆ p u b l i s h e r s /$ ’ , l i s t d e t a i l . o b j e c t l i s t , publisher info )
)

We need to write the template too (we could tell the object list view which template to use by including a
template name key in extra arguments dictionary, but in absence of an explicit template django will infer one
from the object’s name - books/publisher list.html: books comes from the name of the app that defines the
model, while the publisher bit is just lowercased version of the model’s name):
{% e x t e n d s ” b a s e . html ” %}

{% b l o c k c o n t e n t %}
<h2>P u b l i s h e r s </h2>
<u l >
{% f o r p u b l i s h e r i n o b j e c t l i s t %}
< l i >{{ p u b l i s h e r . name }}</ l i >
{% e n d f o r %}
</u l >
{% e n d b l o c k %}

All the cool features of generic views come from changing the “info” dictionary passed to the generic view.

38
8.3 Extending generic views
There’s no question that using generic views can speed up development substantially. In most projects, however,
there comes a moment when the generic views no longer suffice: there are ways to simply extend generic views
to handle a larger array of use cases.

The publisher list template stores all the books in a variable named object list. We can change the name
of that variable easily with the template object name:
publisher info = {
” queryset ” : Publisher . objects . a l l () ,
” template object name ” : ” publisher ” ,
}

urlpatterns = patterns ( ’ ’ ,
( r ’ ˆ p u b l i s h e r s /$ ’ , l i s t d e t a i l . o b j e c t l i s t , publisher info )
)

8.4 Adding extra context


If you want to present some extra information beyond that provided by the generic view. For example, think of
showing a list of all the other publishers on each publisher detail page. The object detail generic view provides
the publisher to the context, but it seems there’s no way to get a list of all publishers in that template: all
generic views take an extra optional parameter extra context, which is a dictionary of extra objects that will
be added to the template’s context.
publisher info = {
” queryset ” : Publisher . objects . a l l () ,
” template object name ” : ” publisher ” ,
” e x t r a c o n t e x t ” : { ” b o o k l i s t ” : Book . o b j e c t s . a l l ( ) }
}

this would create a book list variable in the template context.

Any callable function that’s passed to extra context will be evaluated when the view is rendered (instead
of only once):
def get books () :
return Book . o b j e c t s . a l l ( )

publisher info = {
” queryset ” : Publisher . objects . a l l () ,
” template object name ” : ” publisher ” ,
” e x t r a c o n t e x t ” : {” b o o k l i s t ” : g e t b o o k s }
}

8.5 Viewing subsets of objects


The queryset key is how the view knows which set of objects to display.

Example (order a list of books by publication date, with the most recent first):
book info = {
” q u e r y s e t ” : Book . o b j e c t s . a l l ( ) . o r d e r b y ( ”−p u b l i c a t i o n d a t e ” ) ,
}

urlpatterns = patterns ( ’ ’ ,
( r ’ ˆ p u b l i s h e r s /$ ’ , l i s t d e t a i l . o b j e c t l i s t , p u b l i s h e r i n f o ) ,
( r ’ ˆ books / $ ’ , l i s t d e t a i l . o b j e c t l i s t , b o o k i n f o ) ,
)

39
9 Extending the template engine
9.1 Template language review
• A template is a text document, or a normal Python string, that is marked up using the Django template
language. A template can contain block tags and variables.
• A block tag is a symbol within a template that does something: produce content, serve as a control
structure
• A variable is a symbol within a template that outputs a value.
• A context is a name - value mapping (similar to a Python dictionary) that is passed to a template.
• A template renders a context by replacing the variable “holes” with values from the context and executing
all block tags.

9.2 RequestContext and Context processors


When rendeting a template you need a context: instance of django.template.Context and django.template.RequestContext,
which adds a bunch of variables to your template context by default (things like the HttpRequest object or
information about the currently logged-in user).

Use RequestContext when you don’t want to have to specify the same set of variables in a series of templates:
from d j a n g o . template i m p o r t l o a d e r , Context

def view 1 ( request ) :


# ...
t = l o a d e r . g e t t e m p l a t e ( ’ t e m p l a t e 1 . html ’ )
c = Context ( {
’ app ’ : ’My app ’ ,
’ user ’ : request . user ,
’ i p a d d r e s s ’ : r e q u e s t .META[ ’REMOTE ADDR ’ ] ,
’ message ’ : ’ I am view 1 . ’
})
return t . r e n d e r ( c )

def view 2 ( request ) :


# ...
t = l o a d e r . g e t t e m p l a t e ( ’ t e m p l a t e 2 . html ’ )
c = Context ( {
’ app ’ : ’My app ’ ,
’ user ’ : request . user ,
’ i p a d d r e s s ’ : r e q u e s t .META[ ’REMOTE ADDR ’ ] ,
’ message ’ : ’ I am t h e s e c o n d view . ’
})
return t . r e n d e r ( c )

def view 3 ( request ) :


# ...
t = l o a d e r . g e t t e m p l a t e ( ’ t e m p l a t e 3 . html ’ )
c = Context ( {
’ app ’ : ’My app ’ ,
’ user ’ : request . user ,
’ i p a d d r e s s ’ : r e q u e s t .META[ ’REMOTE ADDR ’ ] ,
’ message ’ : ’ I am t h e t h i r d view . ’
})
return t . r e n d e r ( c )

def view 4 ( request ) :


# ...
t = l o a d e r . g e t t e m p l a t e ( ’ t e m p l a t e 4 . html ’ )
c = Context ( {
’ app ’ : ’My app ’ ,
’ user ’ : request . user ,

40
’ i p a d d r e s s ’ : r e q u e s t .META[ ’REMOTE ADDR ’ ] ,
’ message ’ : ’ I am t h e f o u r t h view . ’
})
return t . r e n d e r ( c )

Each view passes the same three variables - app, user and ip address - to its template. Context processors let
you specify a number of variables that get set in each context automatically - without you having to specify the
variables in each render to response() call:
from d j a n g o . template i m p o r t l o a d e r , R e q u e s t C o n t e x t

def custom proc ( request ) :


”A c o n t e x t p r o c e s s o r t h a t p r o v i d e s ’ app ’ , ’ u s e r ’ and ’ i p a d d r e s s ’ . ”
return {
’ app ’ : ’My app ’ ,
’ user ’ : request . user ,
’ i p a d d r e s s ’ : r e q u e s t .META[ ’REMOTE ADDR ’ ]
}

def view 1 ( request ) :


# ...
t = l o a d e r . g e t t e m p l a t e ( ’ t e m p l a t e 1 . html ’ )
c = R e q u e s t C o n t e x t ( r e q u e s t , { ’ message ’ : ’ I am view 1 . ’ } ,
p r o c e s s o r s =[ c u s t o m p r o c ] )
return t . r e n d e r ( c )

def view 2 ( request ) :


# ...
t = l o a d e r . g e t t e m p l a t e ( ’ t e m p l a t e 2 . html ’ )
c = R e q u e s t C o n t e x t ( r e q u e s t , { ’ message ’ : ’ I am t h e s e c o n d view . ’ } ,
p r o c e s s o r s =[ c u s t o m p r o c ] )
return t . r e n d e r ( c )

def view 3 ( request ) :


# ...
t = l o a d e r . g e t t e m p l a t e ( ’ t e m p l a t e 3 . html ’ )
c = R e q u e s t C o n t e x t ( r e q u e s t , { ’ message ’ : ’ I am t h e t h i r d view . ’ } ,
p r o c e s s o r s =[ c u s t o m p r o c ] )
return t . r e n d e r ( c )

def view 4 ( request ) :


# ...
t = l o a d e r . g e t t e m p l a t e ( ’ t e m p l a t e 4 . html ’ )
c = R e q u e s t C o n t e x t ( r e q u e s t , { ’ message ’ : ’ I am t h e f o u r t h view . ’ } ,
p r o c e s s o r s =[ c u s t o m p r o c ] )
return t . r e n d e r ( c )

Explanation:
• define function custom proc: is a context processor which takes an HttpRequest object and returns a
dictionary of variables to use in the template context.
• other view functions use RequestContext: the first argument has to be an HttpRequest and Request-
Context takes an optional processors argument, which is a list or tuple of context processor functions to
use.
• each view no longer has to include app, user or ip address in its context construction, because those are
provided by custom proc.
• each view still has the flexibility to introduce any custom template variables it might need. In this example,
the message template variable is set differently in each view.
Render to response() shortcut saves you from having to call loader.get template(), then create a Context, then
call the render() method on the template:
from d j a n g o . s h o r t c u t s i m p o r t r e n d e r t o r e s p o n s e
from d j a n g o . template i m p o r t R e q u e s t C o n t e x t

41
def custom proc ( request ) :
”A c o n t e x t p r o c e s s o r t h a t p r o v i d e s ’ app ’ , ’ u s e r ’ and ’ i p a d d r e s s ’ . ”
return {
’ app ’ : ’My app ’ ,
’ user ’ : request . user ,
’ i p a d d r e s s ’ : r e q u e s t .META[ ’REMOTE ADDR ’ ]
}

def view 1 ( request ) :


# ...
return r e n d e r t o r e s p o n s e ( ’ t e m p l a t e 1 . html ’ ,
{ ’ message ’ : ’ I am view 1 . ’ } ,
c o n t e x t i n s t a n c e=R e q u e s t C o n t e x t ( r e q u e s t , p r o c e s s o r s =[ c u s t o m p r o c ] ) )

def view 2 ( request ) :


# ...
return r e n d e r t o r e s p o n s e ( ’ t e m p l a t e 2 . html ’ ,
{ ’ message ’ : ’ I am t h e s e c o n d view . ’ } ,
c o n t e x t i n s t a n c e=R e q u e s t C o n t e x t ( r e q u e s t , p r o c e s s o r s =[ c u s t o m p r o c ] ) )

def view 3 ( request ) :


# ...
return r e n d e r t o r e s p o n s e ( ’ t e m p l a t e 3 . html ’ ,
{ ’ message ’ : ’ I am t h e t h i r d view . ’ } ,
c o n t e x t i n s t a n c e=R e q u e s t C o n t e x t ( r e q u e s t , p r o c e s s o r s =[ c u s t o m p r o c ] ) )

def view 4 ( request ) :


# ...
return r e n d e r t o r e s p o n s e ( ’ t e m p l a t e 4 . html ’ ,
{ ’ message ’ : ’ I am t h e f o u r t h view . ’ } ,
c o n t e x t i n s t a n c e=R e q u e s t C o n t e x t ( r e q u e s t , p r o c e s s o r s =[ c u s t o m p r o c ] ) )

Using context processors doesn’t save you much typing if you have to type processors all the time. For that rea-
son, Django provides support for global context processors. The TEMPLATE CONTEXT PROCESSORS
setting designates which context processors should always be applied to RequestContext. This removes the need
to specify processors each time you use RequestContext.

By default, TEMPLATE CONTEXT PROCESSORS is set to the following:


TEMPLATE CONTEXT PROCESSORS = (
’ django . core . c o n t e x t p r o c e s s o r s . auth ’ ,
’ django . core . c o n t e x t p r o c e s s o r s . debug ’,
’ django . core . c o n t e x t p r o c e s s o r s . i18n ’ ,
’ django . core . c o n t e x t p r o c e s s o r s . media ’,
)

9.2.1 django.core.context processors.auth


Every RequestContext will contain these variables:

• user: represents the current logged-in user

• messages: a list of messages for the current logged-in user

• perms: represents the permissions the current logged-in user has

9.2.2 django.core.context processors.debug


• debug: you can use this variable in templates to test whether you’re in debug mode

• sql queries: a list of dictionaries representing every sql query that has happened so far during the request
and how long it took

42
9.2.3 django.core.context processors.i18n
• LANGUAGES: the value of LANGUAGES setting
• LANGUAGE CODE: the value of LANGUAGE CODE setting

9.2.4 django.core.context processors.request


If this processor is enabled, every RequestContext will contain a variable request, which is the current HttpRe-
quest object. Note that this processor is not enabled by default; you have to activate it.

9.3 Creating a template library


Whether you’re writing custom tags or filters, the first thing to do is to create a template library - a small bit
of infrastructure Django can hook into.

Creating a template library:


• decide which django application should housethe template library (you can create another app solely for
the template library - via manage.py startapp). Add the app to your INSTALLED APPS.
• create a templatetags directory in the appropriate django application (on the same level as models.py
and views.py)
• crete two empty files in the templatetags directory: an init .py and a file that will contain your custom
tag/filter definitions (what you’ll use to load the tags later)
If you write a template library that isn’t tied to any particular models/views, it’s valid and quite normal to have
a Django application package that contains only a templatetags package. There’s no limit on how many modules
you put in the templatetags package. Just keep in mind that a {% load %} statement will load tags/filters for
the given Python module name, not the name of the application.

To be a valid tag library, the module must contain a module-level variable named register that is a tem-
plate.Library instance. This template.Library instance is the data structure in which all the tags and filters are
registered. So, near the top of your module, insert the following:
from d j a n g o i m p o r t template

r e g i s t e r = template . L i b r a r y ( )

Once you’ve created this register variable, you’ll use it to create template filters and tags.

9.4 Writing custom template filters

10 Deploying django
10.1 Using django with apache and mod python
mod python is an apache plugin that embeds python within apache and loads python code into memory when
the server starts: code stays in memory throughout the life of an apache process, which leads to significant
performance gains over other server arrangements.

First configure httpd.conf:


LoadModule python module modules / mod python . s o

43
Edit the config file and add:
<L o c a t i o n ” / d j a n g o / ”>
S e t H a n d l e r mod python
PythonHandler d j a n g o . c o r e . h a n d l e r s . modpython
SetEnv DJANGO SETTINGS MODULE e l i t e s o f t . s e t t i n g s
PythonOption d j a n g o . r o o t / d j a n g o
PythonDebug On
PythonPath ” [ ’ / home/ e l e a n o r / P r o j e c t s / d j a n g o ’ , ’ / home/ e l e a n o r / P r o j e c t s / d j a n g o / e l i t e s o f t ’ ] + s y s . path

</L o c a t i o n >

then all URL patterns will need to start with ”/mysite/”: deploy django at the root of your domain or edit
URLconf to also contain the /mysite/ level.
Apache should have access to files settings.py and database (you also need to grant access to all parent direc-
tories):
chmod 777 e l i t e s o f t d a t a b a s e
chmod 777 s e t t i n g s . py

Changing the read/write permissions to directories (you need that so apache can have access to files it needs):
eleanor@elitesoft ˜/ P r o j e c t s / d j a n g o $ chown e l e a n o r : apache /home/ e l e a n o r /
eleanor@elitesoft ˜/ P r o j e c t s / d j a n g o $ chown e l e a n o r : apache /home/ e l e a n o r / P r o j e c t s /
eleanor@elitesoft ˜/ P r o j e c t s / d j a n g o $ chown e l e a n o r : apache /home/ e l e a n o r / P r o j e c t s / d j a n g o
eleanor@elitesoft ˜/ P r o j e c t s / d j a n g o $ chown e l e a n o r : apache /home/ e l e a n o r / P r o j e c t s / d j a n g o / e l i t e s o f t
eleanor@elitesoft ˜/ P r o j e c t s / d j a n g o $ chmod g+rwx /home/ e l e a n o r
eleanor@elitesoft ˜/ P r o j e c t s / d j a n g o $ chmod g+rwx /home/ e l e a n o r / P r o j e c t s /
eleanor@elitesoft ˜/ P r o j e c t s / d j a n g o $ chmod g+rwx /home/ e l e a n o r / P r o j e c t s / d j a n g o
eleanor@elitesoft ˜/ P r o j e c t s / d j a n g o $ chmod g+rwx /home/ e l e a n o r / P r o j e c t s / d j a n g o / e l i t e s o f t

Then you have to serve static pages (images, style sheets, video): django itself doesn’t serve that, but leaves
the job to whichever web server you choose.

Put this in your apache config:


# A l i a s a l l o w s documents t o be s t o r e d i n t h e l o c a l f i l e s y s t e m ( not under t h e DocumentRoot )
A l i a s / media / / u s r / l i b 6 4 / python2 . 6 / s i t e −p a c k a g e s / d j a n g o / c o n t r i b / admin / media /
<D i r e c t o r y ” / u s r / l i b 6 4 / python2 . 6 / s i t e −p a c k a g e s / d j a n g o / c o n t r i b / admin / media ”>
Order deny , a l l o w
Allow from a l l
</ D i r e c t o r y >

The admin files live in django/contrib/admin/media/. Two approaches:

• create a symbolic link to the admin files from within your document root (all your django related files -
code and templates - will stay in one place)

• copy the admin media files so that they live within your apache document root

10.2 Using django with apache and mod wsgi


Create directory deploy and create a file django.wsgi in it:
import os
import sys

s y s . path . append ( ’< p a r e n t d i r w h e r e p r o j e c t i s l o c a t e d > ’ )


o s . e n v i r o n [ ’DJANGO SETTINGS MODULE ’ ] = ’<p r o j e c t n a m e >. s e t t i n g s ’

import django . c o r e . h a n d l e r s . wsgi


a p p l i c a t i o n = d j a n g o . c o r e . h a n d l e r s . w s g i . WSGIHandler ( )

And put this into httpd.conf:

44
W S G I S c r i p t A l i a s / /< d i r >/d j a n g o . w s g i
<D i r e c t o r y /< p a r e n t d i r /<p r o j e c t n a m e >
Order deny , a l l o w
Allow from a l l
</ D i r e c t o r y >

11 Django Models
Each model maps to a single database table. The only required part of a model is the list of database fields it
defines which can have specific types (should be an appropriate Field class).

Each field takes a certain set of field-specific arguments (CharField requires a max length argument). There is
also a set of common arguments avilable to all field types:

• null: if true, django will store empty values as NULL in the database

• blank: if true, the field is allowed to be blank - validation related

• choices: an iterable list/tuple of 2-tuples to use as choices for this field - django will use the select box
instead of the standard text field and will limit choices to the choices given (first element == value that
will be stored in the database ; second element == will be displayed by the admin interface

• default: default value for the field (can be a value of a callable object - will be called every time a new
object is created)

• help text: extra text help to be displayed under the field on the object’s admin form

• primary key: if true, this field is the primary key for the model (oterwise django will automatically add
an IntegerField to hold the primary key)

• unique: if true, this field must be unique throughout the table

11.1 Verbose field names


Each field type, except for ForeignKey, ManyToManyField and OneToOneField, takes an optional first positional
argument - a verbose name. If the verbose name isn’t given, Django will automatically create it using the field’s
attribute name, converting underscores to spaces.
f i r s t n a m e = models . C h a r F i e l d ( ” P e r s o n ’ s f i r s t name” , m a x l e n g t h =30)
f i r s t n a m e = models . C h a r F i e l d ( m a x l e n g t h =30)
p o l l = models . ForeignKey ( P o l l , v e r b o s e n a m e=” t h e r e l a t e d p o l l ” )
s i t e s = models . ManyToManyField ( S i t e , v e r b o s e n a m e=” l i s t o f s i t e s ” )
p l a c e = models . OneToOneField ( P l a c e , v e r b o s e n a m e=” r e l a t e d p l a c e ” )

11.2 Relationships
Relations are: many-to-one, many-to-many and one-to-one.

45
11.2.1 many-to-one
Use ForeignKey: use it just like any other Field type (by including it as a class attribute of your model).

It requires a positional argument: the class to which the model is related.

Example: a Car model has a Manufacturer - that is, a Manufacturer makes multiple cars but each Car only has
one Manufacturer - use the following definitions:
c l a s s M a n u f a c t u r e r ( models . Model ) :
# ...

c l a s s Car ( models . Model ) :


m a n u f a c t u r e r = models . ForeignKey ( M a n u f a c t u r e r )
# ...

It’s suggested, but not required, that the name of a ForeignKey field (manufacturer in the example above) be
the name of the model, lowercase. You can, of course, call the field whatever you want.

11.2.2 many-to-many
Use ManyToManyField: use it by including it as a class attribute of your model.

It requires a positional argument: the class to which the model is related.

Example: a Pizza has multiple Topping objects - that is, a Topping can be on multiple pizzas and each
Pizza has multiple toppings:
c l a s s Topping ( models . Model ) :
# ...

c l a s s P i z z a ( models . Model ) :
# ...
t o p p i n g s = models . ManyToManyField ( Topping )

It’s suggested, but not required, that the name of a ManyToManyField (toppings in the example above) be a
plural describing the set of related model objects.

It doesn’t matter which model gets the ManyToManyField, but you only need it in one of the models - not in
both.

11.2.3 one-to-one
Use OneToOneField. OneToOneField requires a positional argument: the class to which the model is related.

12 Database design
12.1 Primary key
Primary key is used to uniquely identify each row of a relational table: often just an ID of the table, but can be
any number of attributes. The question arises: How can we uniquely identify a table row? The primary
key can only occur once in the primery key column of a table.

Example: we have a table customer:

46
customer id FirstName LastName PhoneNumber
1 John Smith 123456789
2 John Connor 987654321

we could try to select a customer in this table by searching for customer’s first name: not a good idea, because
there are two johns in the table (impossible to select the john you want). You could search for combination of
first and last name, but it’s not as efficient. Define the customer id instead.

12.2 Foreign key


Is a column in a table used to reference a primary key in another table (used when you have relationships that
join together multiple tables).

Example: we have a table order:


order id customer id OrderDate
1 2 7/2/2009
2 2 8/2/2009

here the customer id is a foreign key (can be used to refer to given customer) in order table, which can be
used to reference a customer stored in the customer table.

You define a foreign key in database to model relationship in the real world: relationships between pairs of
tables, which can be: one-to-one, one-to-many, many-to-many.

12.3 one-to-one relationship


For every row in the first table, there is at most one row in the second table (rarely occur: if you have to split
one table into two parts because of limitation of rows).

Tables that are related in a one-to-one relationship should always have the same primary key, which will
serve as the join column.

12.4 one-to-many relationship


For every row in the first table, there can be zero or more rows in the second table, but for every row in the
second table there is exactly one row in the first table (each order in a pizza delivery can have multiple items).

12.5 many-to-many relationship


For every row in the first table, there can be many rows in the second table (must be broken into one-to-many
relational tables).

13 Django tips
13.1 Make TEMPLATE DIRS in settings.py relative
Edit the settings.py like this:
ROOT PATH = o s . path . dirname ( file )

TEMPLATE DIRS = (
( o s . path . j o i n (ROOT PATH, ’ templates ’ ) ) ,

47
13.2 save foreign keys as objects
If you want the values to have the foreign keys as actual objects rather than just ids:
d i c t ( [ ( f . name , g e t a t t r ( o bj , f . name ) ) f o r f i n o b j . meta . f i e l d s ] )

13.3 Models - define hierarchy classes


Example:
# which s u b j e c t s s t u d e n t i s c u r r e n t l y e n r o l l e d w i t h ( a l l students )
c l a s s B a s e S t u d e n t ( models . Model ) :
s t u d e n t = models . ManyToManyField ( S t u d e n t )
s u b j e c t = models . ManyToManyField ( S u b j e c t )

c l a s s Meta :
a b s t r a c t = True

c l a s s StudentSubject ( BaseStudent ) :
pass

c l a s s StudentGrades ( BaseStudent ) :
pass

13.4 Forms - declare your own date - calender widget


Example views.py:
# −∗− c o d i n g : u t f −8 −∗−
from d j a n g o i m p o r t f o r m s
from models i m p o r t ∗
from d j a n g o . c o n t r i b . admin . w i d g e t s i m p o r t AdminDateWidget
from d a t e t i m e i m p o r t ∗

c l a s s PeriodExamsForm ( f o r m s . Form ) :
e x a m i d = f o r m s . M o d e l M u l t i p l e C h o i c e F i e l d ( q u e r y s e t=S u b j e c t . o b j e c t s . a l l ( ) )
exam date = f o r m s . D a t e F i e l d ( r e q u i r e d=True , w i d g e t=AdminDateWidget ( ) )
e x a m p r o f e s s o r =f o r m s . M o d e l M u l t i p l e C h o i c e F i e l d ( q u e r y s e t=P r o f e s s o r . o b j e c t s . a l l ( ) )

Put this in your template:


{% e x t e n d s ” c o n t e n t . html ” %}

{% b l o c k c o n t e n t j a v a s c r i p t %}
< s c r i p t t y p e=” t e x t / j a v a s c r i p t ” s r c=” / my admin / j s i 1 8 n / ”></ s c r i p t >
< s c r i p t t y p e=” t e x t / j a v a s c r i p t ” s r c=” / media / admin / media / j s / c o r e . j s ”></ s c r i p t >
< s c r i p t t y p e=” t e x t / j a v a s c r i p t ” s r c=” / admin / j s i 1 8 n / ”></ s c r i p t >
< l i n k r e l=” s t y l e s h e e t ” t y p e=” t e x t / c s s ” h r e f=” / admin / media / c s s / f o r m s . c s s ”/>
< l i n k r e l=” s t y l e s h e e t ” t y p e=” t e x t / c s s ” h r e f=” / admin / media / c s s / b a s e . c s s ”/>
< l i n k r e l=” s t y l e s h e e t ” t y p e=” t e x t / c s s ” h r e f=” / admin / media / c s s / g l o b a l . c s s ”/>
< l i n k r e l=” s t y l e s h e e t ” t y p e=” t e x t / c s s ” h r e f=” / admin / media / c s s / w i d g e t s . c s s ”/>
{{ form . media }}
{% e n d b l o c k %}

{% b l o c k c o n t e n t b o d y %}
<t a b l e >
{{ form . a s t a b l e }}
</ t a b l e >
{% e n d b l o c k %}

And make sure you can serve static files in urls.py:


u r l p a t t e r n s += p a t t e r n s ( ’ ’ ,
( r ’ ˆ c s s / ( ?P<path >.∗) $ ’ , ’ d j a n g o . v i e w s . s t a t i c . s e r v e ’ , { ’ d o c u m e n t r o o t ’ : s e t t i n g s .MEDIA ROOT} ) ,
( r ’ ˆ media / ( ?P<path >.∗) $ ’ , ’ d j a n g o . v i e w s . s t a t i c . s e r v e ’ , { ’ d o c u m e n t r o o t ’ : s e t t i n g s . MEDIA ROOT2} ) ,
( r ’ ˆ my admin / j s i 1 8 n ’ , ’ d j a n g o . v i e w s . i 1 8 n . j a v a s c r i p t c a t a l o g ’ ) ,
)

48
# s e t t i n g s . py
MEDIA ROOT = o s . path . j o i n ( o s . path . dirname ( file ) , ” templates /” )
MEDIA ROOT2 = ” / u s r / l i b 6 4 / python2 . 6 / s i t e −p a c k a g e s / d j a n g o / c o n t r i b / ”

49