The Definitive Guide To Django

The%20Definitive%20Guide%20to%20Django

The%20Definitive%20Guide%20to%20Django

The%20Definitive%20Guide%20to%20Django

The%20Definitive%20Guide%20To%20Django%20(2nd%20Edition)%20-%20Adrian%20Holovaty%20-%20Apress

The%20Definitive%20Guide%20to%20Django

User Manual: Pdf

Open the PDF directly: View PDF PDF.
Page Count: 513 [warning: Documents this large are best viewed by clicking the View PDF Link!]

The Definitive Guide
to Django
Web Development Done Right,
Second Edition
Adrian Holovaty and Jacob Kaplan-Moss
The Definitive Guide to Django: Web Development Done Right, Second Edition
Copyright © 2009 by Adrian Holovaty and Jacob Kaplan-Moss
All rights reserved. No part of this work may be reproduced or transmitted in any form or by any means,
electronic or mechanical, including photocopying, recording, or by any information storage or retrieval
system, without the prior written permission of the copyright owner and the publisher.
ISBN 13: 978-1-4302-1936-1
ISBN (electronic): 978-1-4302-1937-8
Printed and bound in the United States of America 9 8 7 6 5 4 3 2 1
Trademarked names may appear in this book. Rather than use a trademark symbol with every occurrence
of a trademarked name, we use the names only in an editorial fashion and to the benefit of the trademark
owner, with no intention of infringement of the trademark.
Java™ and all Java-based marks are trademarks or registered trademarks of Sun Microsystems, Inc., in the
US and other countries. Apress, Inc., is not affiliated with Sun Microsystems, Inc., and this book was writ-
ten without endorsement from Sun Microsystems, Inc.
Lead Editor: Duncan Parkes
Technical Reviewer: Sean Legassick
Editorial Board: Clay Andres, Steve Anglin, Mark Beckner, Ewan Buckingham, Tony Campbell,
Gary Cornell, Jonathan Gennick, Michelle Lowman, Matthew Moodie, Jeffrey Pepper, Frank Pohlmann,
Ben Renow-Clarke, Dominic Shakeshaft, Matt Wade, Tom Welsh
Project Managers: Grace Wong and James Markham
Copy Editors: Nancy Sixsmith and Candace English
Associate Production Director: Kari Brooks-Copony
Production Editor: Katie Stence
Compositor: Patrick Cunningham
Proofreader: April Eddy
Indexer: BIM Indexing & Proofreading Services
Artist: April Milne
Cover Designer: Kurt Krames
Manufacturing Director: Tom Debolski
Distributed to the book trade worldwide by Springer-Verlag New York, Inc., 233 Spring Street, 6th Floor,
New York, NY 10013. Phone 1-800-SPRINGER, fax 201-348-4505, e-mail kn`ano)ju<olnejcan)o^i*_ki, or
visit dppl6++sss*olnejcankjheja*_ki.
For information on translations, please contact Apress directly at 2855 Telegraph Avenue, Suite 600,
Berkeley, CA 94705. Phone 510-549-5930, fax 510-549-5939, e-mail ejbk<]lnaoo*_ki, or visit dppl6++sss*
]lnaoo*_ki.
Apress and friends of ED books may be purchased in bulk for academic, corporate, or promotional use.
eBook versions and licenses are also available for most titles. For more information, reference our Special
Bulk Sales–eBook Licensing web page at dppl6++sss*]lnaoo*_ki+ejbk+^qhgo]hao.
The information in this book is distributed on an “as is” basis, without warranty. Although every precau-
tion has been taken in the preparation of this work, neither the author(s) nor Apress shall have any liability
to any person or entity with respect to any loss or damage caused or alleged to be caused directly or indi-
rectly by the information contained in this work.
The source code for this book is available to readers at dppl6++sss*]lnaoo*_ki.
This book is dedicated to the Django community.
iv
Contents at a Glance
About the Author ................................................................xxvii
About the Technical Reviewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxix
Acknowledgments ...............................................................xxxi
Preface .......................................................................xxxiii
Introduction ....................................................................xxxv
PART 1 NNN Getting Started
CHAPTER 1 Introduction to Django ...........................................3
CHAPTER 2 Getting Started .................................................11
CHAPTER 3 Views and URLconfs ............................................21
CHAPTER 4 Templates .....................................................39
CHAPTER 5 Models ........................................................71
CHAPTER 6 The Django Admin Site .........................................95
CHAPTER 7 Forms ........................................................119
PART 2 NNN Advanced Usage
CHAPTER 8 Advanced Views and URLconfs ................................145
CHAPTER 9 Advanced Templates ..........................................167
CHAPTER 10 Advanced Models .............................................191
CHAPTER 11 Generic Views ................................................203
CHAPTER 12 Deploying Django .............................................213
v
PART 3 NNN Other Django Features
CHAPTER 13 Generating Non-HTML Content .................................237
CHAPTER 14 Sessions, Users, and Registration ..............................255
CHAPTER 15 Caching ......................................................277
CHAPTER 16 django.contrib ................................................291
CHAPTER 17 Middleware ...................................................309
CHAPTER 18 Integrating with Legacy Databases and Applications ............317
CHAPTER 19 Internationalization ............................................323
CHAPTER 20 Security ......................................................341
PART 4 NNN Appendixes
APPENDIX A Model Definition Reference ....................................353
APPENDIX B Database API Reference .......................................369
APPENDIX C Generic View Reference .......................................395
APPENDIX D Settings ......................................................413
APPENDIX E Built-in Template Tags and Filters .............................429
APPENDIX F The django-admin Utility ......................................455
APPENDIX G Request and Response Objects ................................469
INDEX .......................................................................479
vii
Contents
About the Author ................................................................xxvii
About the Technical Reviewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . xxix
Acknowledgments ...............................................................xxxi
Preface .......................................................................xxxiii
Introduction ....................................................................xxxv
PART 1 NNN Getting Started
CHAPTER 1 Introduction to Django .......................................3
What Is a Web Framework? ........................................3
The MVC Design Pattern ...........................................5
Django's History ..................................................7
How to Read This Book ............................................8
Required Programming Knowledge ............................8
Required Python Knowledge ..................................8
Required Django Version .....................................9
Getting Help .....................................................9
What’s Next? ....................................................9
CHAPTER 2 Getting Started ..............................................11
Installing Python .................................................11
Python Versions ............................................11
Installation .................................................12
Installing Django ................................................12
Installing an Official Release .................................12
Installing the Trunk Version ..................................13
Testing the Django Installation ....................................14
NCONTENTS
viii
Setting Up a Database ...........................................15
Using Django with PostgreSQL ...............................16
Using Django with SQLite 3 ..................................16
Using Django with MySQL ...................................17
Using Django with Oracle ....................................17
Using Django Without a Database .............................17
Starting a Project ................................................17
Running the Development Server .............................18
What's Next? ...................................................19
CHAPTER 3 Views and URLconfs ........................................21
Your First Django-Powered Page: Hello World .......................21
Your First View .............................................21
Your First URLconf ..........................................22
A Quick Note About 404 Errors ...............................26
A Quick Note About the Site Root .............................27
How Django Processes a Request .................................28
Your Second View: Dynamic Content ...............................28
URLconfs and Loose Coupling .....................................31
Your Third View: Dynamic URLs ...................................31
Django’s Pretty Error Pages .......................................35
What's Next? ...................................................37
CHAPTER 4 Templates ...................................................39
Template-System Basics .........................................40
Using the Template System .......................................41
Creating Template Objects ...................................42
Rendering a Template .......................................43
Multiple Contexts, Same Template ............................45
Context Variable Lookup .....................................46
Playing with Context Objects .................................49
Basic Template Tags and Filters ...................................50
Tags ......................................................50
Filters .....................................................56
Philosophies and Limitations ......................................57
Using Templates in Views ........................................58
NCONTENTS ix
Template Loading ...............................................60
render_to_response() .......................................63
The locals() Trick ...........................................63
Subdirectories in get_template() ..............................64
The include Template Tag ...................................65
Template Inheritance ............................................66
What's Next? ...................................................70
CHAPTER 5 Models .......................................................71
The “Dumb” Way to Do Database Queries in Views ..................71
The MTV (or MVC) Development Pattern ............................72
Configuring the Database .........................................74
Your First App ...................................................76
Defining Models in Python ........................................77
Your First Model .................................................78
Installing the Model ..............................................80
Basic Data Access ...............................................83
Adding Model String Representations ..............................84
Inserting and Updating Data ......................................86
Selecting Objects ................................................88
Filtering Data ..............................................88
Retrieving Single Objects ....................................89
Ordering Data ..............................................90
Chaining Lookups. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Slicing Data ................................................92
Updating Multiple Objects in One Statement. . . . . . . . . . . . . . . . . . . . 92
Deleting Objects .................................................93
What's Next? ...................................................94
CHAPTER 6 The Django Admin Site .....................................95
The django.contrib Packages .....................................95
Activating the Admin Interface ....................................96
Using the Admin Site .............................................97
Adding Your Models to the Admin Site .............................102
How the Admin Site Works ......................................103
Making Fields Optional ..........................................103
Making Date and Numeric Fields Optional ....................104
Customizing Field Labels ........................................105
NCONTENTS
x
Custom ModelAdmin Classes ....................................106
Customizing Change Lists ..................................106
Customizing Edit Forms ....................................112
Users, Groups, and Permissions ..................................116
When and Why to Use the Admin Interface—And When Not To .......117
What’s Next? ..................................................118
CHAPTER 7 Forms .......................................................119
Getting Data from the Request Object .............................119
Information About the URL ..................................119
Other Information About the Request .........................120
Information About Submitted Data ...........................121
A Simple Form-Handling Example ................................122
Improving Our Simple Form-Handling Example .....................125
Simple Validation ...............................................127
Making a Contact Form .........................................129
Your First Form Class ...........................................133
Tying Form Objects into Views ..............................136
Changing How Fields Are Rendered ..........................137
Setting a Maximum Length .................................137
Setting Initial Values .......................................138
Adding Custom Validation Rules .............................138
Specifying Labels ..........................................139
Customizing Form Design ...................................139
What’s Next? ..................................................141
PART 2 NNN Advanced Usage
CHAPTER 8 Advanced Views and URLconfs ...........................145
URLconf Tricks .................................................145
Streamlining Function Imports ...............................145
Using Multiple View Prefixes ................................147
Special-Casing URLs in Debug Mode .........................148
Using Named Groups .......................................148
Understanding the Matching/Grouping Algorithm ..............150
Passing Extra Options to View Functions ......................150
Using Default View Arguments ..............................155
NCONTENTS xi
Special-Casing Views ......................................156
Capturing Text in URLs .....................................157
Determining What the URLconf Searches Against ..............158
Higher-Level Abstractions of View Functions ..................158
Wrapping View Functions ...................................161
Including Other URLconfs ........................................162
How Captured Parameters Work with include() ................163
How Extra URLconf Options Work with include() ...............164
What’s Next? ..................................................165
CHAPTER 9 Advanced Templates .......................................167
Template Language Review ......................................167
RequestContext and Context Processors ...........................168
django.core.context_processors.auth ........................171
django.core.context_processors.debug .......................171
django.core.context_processors.i18n ........................172
django.core.context_processors.request ......................172
Guidelines for Writing Your Own Context Processors ...........172
Automatic HTML Escaping .......................................173
How to Turn It Off ..........................................174
Notes ....................................................175
Automatic Escaping of String Literals in Filter Arguments .......176
Inside Template Loading ........................................176
Extending the Template System ..................................177
Creating a Template Library .................................177
Writing Custom Template Filters .............................178
Writing Custom Template Tags ..............................180
Writing the Compilation Function ............................180
Writing the Template Node ..................................182
Registering the Tag ........................................182
Setting a Variable in the Context .............................183
Parsing Until Another Template Tag ..........................184
Parsing Until Another Template Tag and Saving Contents .......185
Shortcut for Simple Tags ...................................185
Inclusion Tags .............................................186
Writing Custom Template Loaders ................................188
Configuring the Template System in Standalone Mode ..............189
What’s Next? ..................................................190
NCONTENTS
xii
CHAPTER 10 Advanced Models ..........................................191
Related Objects ................................................191
Accessing Foreign Key Values ...............................192
Accessing Many-to-Many Values ............................193
Making Changes to a Database Schema ...........................193
Adding Fields .............................................193
Removing Fields ...........................................196
Removing Many-to-Many Fields .............................196
Removing Models. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 196
Managers .....................................................197
Adding Extra Manager Methods .............................197
Modifying Initial Manager QuerySets .........................198
Model Methods ................................................199
Executing Raw SQL Queries. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 200
What’s Next? ..................................................201
CHAPTER 11 Generic Views ..............................................203
Using Generic Views ............................................204
Generic Views of Objects ........................................205
Extending Generic Views ........................................207
Making “Friendly” Template Contexts ........................207
Adding Extra Context .......................................208
Viewing Subsets of Objects .................................209
Complex Filtering with Wrapper Functions ....................210
Performing Extra Work .....................................211
What’s Next? ..................................................212
CHAPTER 12 Deploying Django ..........................................213
Preparing Your Codebase for Production ...........................213
Turning Off Debug Mode ....................................213
Turning Off Template Debug Mode ...........................214
Implementing a 404 Template ...............................214
Implementing a 500 Template ...............................214
Setting Up Error Alerts ......................................215
Setting Up Broken Link Alerts ...............................215
Using Different Settings for Production ............................216
DJANGO_SETTINGS_MODULE. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
NCONTENTS xiii
Using Django with Apache and mod_python .......................218
Basic Configuration ........................................218
Running Multiple Django Installations on
the Same Apache Instance ...............................219
Running a Development Server with mod_python ..............220
Serving Django and Media Files from
the Same Apache Instance ...............................220
Error Handling .............................................221
Handling a Segmentation Fault ..............................221
An Alternative: mod_wsgi ...................................222
Using Django with FastCGI .......................................222
FastCGI Overview ..........................................222
Running Your FastCGI Server ................................223
Using Django with Apache and FastCGI .......................224
FastCGI and lighttpd .......................................225
Running Django on a Shared-Hosting Provider with Apache .....227
Scaling ........................................................228
Running on a Single Server .................................228
Separating Out the Database Server .........................229
Running a Separate Media Server. . . . . . . . . . . . . . . . . . . . . . . . . . . . 229
Implementing Load Balancing and Redundancy ...............230
Going Big .................................................232
Performance Tuning ............................................232
There’s No Such Thing As Too Much RAM ....................233
Turn Off Keep-Alive ........................................233
Use Memcached ...........................................233
Use Memcached Often .....................................234
Join the Conversation ......................................234
What’s Next? ..................................................234
PART 3 NNN Other Django Features
CHAPTER 13 Generating Non-HTML Content ............................237
The Basics: Views and MIME Types ...............................237
Producing CSV .................................................238
Generating PDFs ...............................................239
Installing ReportLab ........................................240
Writing Your View ..........................................240
Complex PDFs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
NCONTENTS
xiv
Other Possibilities ..............................................242
The Syndication-Feed Framework ................................242
Initialization ...............................................243
A Simple Feed .............................................244
A More Complex Feed ......................................245
Specifying the Type of Feed .................................247
Enclosures ................................................247
Language .................................................248
URLs .....................................................248
Publishing Atom and RSS Feeds in Tandem ...................248
The Sitemap Framework ........................................249
Installation ................................................249
Initialization ...............................................250
Sitemap Classes ...........................................250
Shortcuts .................................................251
Creating a Sitemap Index ...................................252
Pinging Google ............................................253
What's Next? ..................................................254
CHAPTER 14 Sessions, Users, and Registration ........................255
Cookies .......................................................255
Getting and Setting Cookies .................................256
The Mixed Blessing of Cookies ..............................257
Django’s Session Framework ....................................258
Enabling Sessions .........................................258
Using Sessions in Views ....................................259
Setting Test Cookies .......................................261
Using Sessions Outside of Views .............................261
When Sessions Are Saved ..................................262
Browser-Length Sessions vs. Persistent Sessions ..............262
Other Session Settings .....................................263
Users and Authentication ........................................264
Enabling Authentication Support .............................264
Using Users ...............................................265
Logging In and Out .........................................267
Limiting Access to Logged-in Users ..........................269
Limiting Access to Users Who Pass a Test ....................269
Managing Users, Permissions, and Groups ....................271
Using Authentication Data in Templates ......................273
NCONTENTS xv
Permissions, Groups, and Messages ..............................274
Permissions ...............................................274
Groups ...................................................275
Messages ................................................275
What’s Next? ..................................................276
CHAPTER 15 Caching .....................................................277
Setting Up the Cache ...........................................278
Memcached ..............................................278
Database Caching .........................................279
Filesystem Caching ........................................279
Local-Memory Caching .....................................280
Dummy Caching (for Development) ..........................280
Using a Custom Cache Back-End ............................280
CACHE_BACKEND Arguments ...............................281
The Per-Site Cache .............................................281
The Per-View Cache ............................................282
Specifying Per-View Cache in the URLconf ....................283
Template Fragment Caching .....................................284
The Low-Level Cache API. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
Upstream Caches ...............................................286
Using Vary Headers .............................................287
Controlling Cache: Using Other Headers ...........................288
Other Optimizations .............................................290
Order of MIDDLEWARE_CLASSES .................................290
What’s Next? ..................................................290
CHAPTER 16 django.contrib ..............................................291
The Django Standard Library .....................................291
Sites ..........................................................293
Scenario 1: Reusing Data on Multiple Sites ...................293
Scenario 2: Storing Your Site Name/Domain in One Place .......293
How to Use the Sites Framework ............................293
The Sites Framework’s Capabilities ..........................294
CurrentSiteManager. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297
How Django Uses the Sites Framework .......................298
Flatpages ......................................................299
Using Flatpages ...........................................299
Adding, Changing, and Deleting Flatpages ....................301
Using Flatpage Templates ..................................301
NCONTENTS
xvi
Redirects ......................................................302
Using the Redirects Framework .............................302
Adding, Changing, and Deleting Redirects ....................303
CSRF Protection ................................................304
A Simple CSRF Example ....................................304
A More Complex CSRF Example .............................304
Preventing CSRF ...........................................304
Humanizing Data ...............................................306
apnumber ................................................306
intcomma ................................................306
intword ...................................................306
ordinal ...................................................307
Markup Filters .................................................307
What’s Next? ..................................................307
CHAPTER 17 Middleware .................................................309
What’s Middleware? ............................................309
Middleware Installation ..........................................310
Middleware Methods ............................................311
Initializer: __init__(self) ....................................311
Request Preprocessor: process_request(self, request) ..........311
View Preprocessor: process_view(self, request, view,
args, kwargs) ...........................................311
Response Postprocessor: process_response(self,
request, response) ......................................312
Exception Postprocessor: process_exception(self,
request, exception) ......................................312
Built-in Middleware .............................................313
Authentication Support Middleware ..........................313
“Common” Middleware ....................................313
Compression Middleware ...................................314
Conditional GET Middleware ................................314
Reverse Proxy Support (X-Forwarded-For Middleware) .........314
Session Support Middleware ................................315
Sitewide Cache Middleware .................................315
Transaction Middleware ....................................315
What’s Next? ..................................................315
NCONTENTS xvii
CHAPTER 18 Integrating with Legacy Databases and Applications ...317
Integrating with a Legacy Database ...............................317
Using inspectdb ...........................................317
Cleaning Up Generated Models ..............................318
Integrating with an Authentication System .........................319
Specifying Authentication Back-Ends .........................319
Writing an Authentication Back-End ..........................319
Integrating with Legacy Web Applications .........................321
What’s Next? ..................................................322
CHAPTER 19 Internationalization ........................................323
How to Specify Translation Strings ................................324
In Python Code ............................................324
In Template Code ..........................................327
Working with Lazy Translation Objects .......................329
How to Create Language Files ....................................330
Message Files .............................................330
Compiling Message Files ...................................332
How Django Discovers Language Preference .......................333
Using Translations in Your Own Projects ...........................335
The set_language Redirect View .................................336
Translations and JavaScript ......................................337
The javascript_catalog View ................................337
Using the JavaScript Translation Catalog .....................337
Creating JavaScript Translation Catalogs .....................339
Notes for Users Familiar with gettext ..............................339
gettext on Windows .............................................339
What’s Next? ..................................................340
CHAPTER 20 Security .....................................................341
The Theme of Web Security ......................................341
SQL Injection ..................................................342
The Solution ..............................................343
Cross-Site Scripting (XSS) .......................................343
The Solution ..............................................344
Cross-Site Request Forgery ......................................345
Session Forging/Hijacking .......................................345
The Solution ..............................................346
NCONTENTS
xviii
E-mail Header Injection .........................................347
The Solution ..............................................347
Directory Traversal .............................................347
The Solution ..............................................348
Exposed Error Messages ........................................349
The Solution ..............................................349
A Final Word on Security ........................................349
What’s Next? ..................................................349
PART 4 NNN Appendixes
APPENDIX A Model Definition Reference ...............................353
Fields .........................................................353
AutoField .................................................354
BooleanField ..............................................354
CharField .................................................354
CommaSeparatedIntegerField ...............................354
DateField .................................................355
DateTimeField .............................................355
DecimalField ..............................................355
EmailField ................................................355
FileField ..................................................355
FilePathField ..............................................357
FloatField .................................................357
ImageField ................................................357
IntegerField ...............................................358
IPAddressField ............................................358
NullBooleanField ...........................................358
PositiveIntegerField ........................................358
PositiveSmallIntegerField ...................................358
SlugField .................................................358
SmallIntegerField ..........................................358
TextField .................................................358
TimeField .................................................358
URLField ..................................................359
XMLField .................................................359
NCONTENTS xix
Universal Field Options ..........................................359
null ......................................................359
blank. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360
choices ...................................................360
db_column ...............................................361
db_index .................................................361
db_tablespace ............................................361
default ...................................................361
editable ..................................................361
help_text .................................................361
primary_key ..............................................362
unique ...................................................362
unique_for_date ...........................................362
unique_for_month .........................................362
unique_for_year ...........................................362
verbose_name ............................................362
Relationships ..................................................363
ForeignKey ...............................................363
ManyToManyField .........................................364
OneToOneField ............................................365
Model Metadata Options ........................................365
abstract ..................................................365
db_table ..................................................366
db_tablespace ............................................366
get_latest_by .............................................366
managed .................................................366
ordering ..................................................367
proxy. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368
unique_together ...........................................368
verbose_name ............................................368
verbose_name_plural ......................................368
APPENDIX B Database API Reference ...................................369
Creating Objects. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
What Happens When You Save? .............................370
Autoincrementing Primary Keys .............................370
Saving Changes to Objects ......................................371
Retrieving Objects ..............................................372
Caching and QuerySets .........................................373
NCONTENTS
xx
Filtering Objects ................................................373
Chaining Filters ............................................374
Limiting QuerySets .........................................375
Query Methods That Return New QuerySets ...................376
QuerySet Methods That Do Not Return QuerySets ..............379
Field Lookups ..................................................382
exact .....................................................382
iexact ....................................................382
contains ..................................................382
icontains .................................................383
gt, gte, lt, and lte ..........................................383
in .......................................................383
startswith .................................................384
istartswith ................................................384
endswith and iendswith ....................................384
range ....................................................384
year, month, and day ......................................384
isnull .....................................................385
search ...................................................385
The pk Lookup Shortcut ....................................385
Complex Lookups with Q Objects .................................385
Related Objects ................................................387
Lookups That Span Relationships ............................387
Foreign-Key Relationships ..................................387
“Reverse” Foreign-Key Relationships ........................388
Many-to-Many Relationships ................................390
Queries over Related Objects ................................391
Deleting Objects ................................................391
Shortcuts ......................................................392
get_object_or_404() .......................................392
get_list_or_404() ..........................................392
Falling Back to Raw SQL ........................................393
APPENDIX C Generic View Reference ...................................395
Common Arguments to Generic Views ............................395
“Simple” Generic Views .........................................396
Rendering a Template ......................................396
Redirecting to Another URL .................................397
NCONTENTS xxi
List/Detail Generic Views ........................................397
Lists of Objects ............................................397
Detail Views ..............................................400
Date-Based Generic Views .......................................401
Archive Index .............................................402
Year Archives .............................................403
Month Archives ............................................404
Week Archives ............................................406
Day Archives ..............................................408
Archive for Today ..........................................409
Date-Based Detail Pages ...................................409
APPENDIX D Settings .....................................................413
The Basics of Settings Files ......................................413
Default Settings ...........................................413
Seeing Which Settings You’ve Changed ......................414
Using Settings in Python Code ...............................414
Altering Settings at Runtime ................................414
Security ..................................................414
Creating Your Own Settings .................................415
Designating the Settings: DJANGO_SETTINGS_MODULE .............415
The django-admin.py Utility .................................415
On the Server (mod_python) ................................416
Using Settings Without Setting DJANGO_SETTINGS_MODULE ........416
Custom Default Settings ....................................417
Either configure() or DJANGO_SETTINGS_MODULE Is Required . . 417
Available Settings ..............................................417
ABSOLUTE_URL_OVERRIDES ................................417
ADMIN_MEDIA_PREFIX .....................................418
ADMINS ..................................................418
ALLOWED_INCLUDE_ROOTS ................................418
APPEND_SLASH ...........................................418
CACHE_BACKEND .........................................418
CACHE_MIDDLEWARE_KEY_PREFIX ..........................418
DATABASE_ENGINE ........................................418
DATABASE_HOST ..........................................419
DATABASE_NAME .........................................419
DATABASE_OPTIONS. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 419
DATABASE_PASSWORD ....................................419
DATABASE_PORT ..........................................419
NCONTENTS
xxii
DATABASE_USER ..........................................419
DATE_FORMAT ............................................419
DATETIME_FORMAT .......................................420
DEBUG ...................................................420
DEFAULT_CHARSET ........................................420
DEFAULT_CONTENT_TYPE ..................................420
DEFAULT_FROM_EMAIL ....................................420
DISALLOWED_USER_AGENTS ...............................420
EMAIL_HOST ..............................................421
EMAIL_HOST_PASSWORD ..................................421
EMAIL_HOST_USER ........................................421
EMAIL_PORT ..............................................421
EMAIL_SUBJECT_PREFIX ...................................421
FIXTURE_DIRS ............................................421
IGNORABLE_404_ENDS ....................................421
IGNORABLE_404_STARTS ..................................422
INSTALLED_APPS .........................................422
LANGUAGE_CODE .........................................422
LANGUAGES ..............................................422
MANAGERS ...............................................423
MEDIA_ROOT .............................................423
MEDIA_URL ...............................................423
MIDDLEWARE_CLASSES ....................................423
MONTH_DAY_FORMAT .....................................423
PREPEND_WWW ..........................................424
ROOT_URLCONF ...........................................424
SECRET_KEY ..............................................424
SEND_BROKEN_LINK_EMAILS ..............................424
SERIALIZATION_MODULES ..................................424
SERVER_EMAIL ............................................424
SESSION_COOKIE_AGE .....................................424
SESSION_COOKIE_DOMAIN .................................425
SESSION_COOKIE_NAME ...................................425
SESSION_COOKIE_SECURE .................................425
SESSION_EXPIRE_AT_BROWSER_CLOSE .....................425
SESSION_SAVE_EVERY_REQUEST ...........................425
SITE_ID ..................................................425
TEMPLATE_CONTEXT_PROCESSORS .........................425
TEMPLATE_DEBUG ........................................426
TEMPLATE_DIRS ..........................................426
TEMPLATE_LOADERS ......................................426
NCONTENTS xxiii
TEMPLATE_STRING_IF_INVALID .............................426
TEST_DATABASE_NAME ...................................426
TEST_RUNNER ............................................426
TIME_FORMAT ............................................427
TIME_ZONE ...............................................427
URL_VALIDATOR_USER_AGENT .............................427
USE_ETAGS ...............................................427
USE_I18N ................................................428
YEAR_MONTH_FORMAT ....................................428
APPENDIX E Built-in Template Tags and Filters ........................429
Built-in Tag Reference ..........................................429
autoescape ...............................................429
block .....................................................429
comment .................................................429
cycle .....................................................430
debug ....................................................431
extends ..................................................431
filter .....................................................431
firstof ....................................................431
for .......................................................432
if .......................................................433
ifchanged .................................................434
ifequal ...................................................435
ifnotequal .................................................435
include ...................................................435
load ......................................................436
now ......................................................436
regroup ..................................................438
spaceless .................................................440
ssi .......................................................440
templatetag ...............................................440
url .......................................................441
widthratio ................................................441
with ......................................................442
Built-in Filter Reference .........................................442
add ......................................................442
addslashes ...............................................442
capfirst ...................................................442
center ....................................................442
NCONTENTS
xxiv
cut .......................................................442
date .....................................................442
default ...................................................443
default_if_none ...........................................443
dictsort ...................................................443
dictsortreversed ...........................................444
divisibleby ................................................444
escape ...................................................444
escapejs ..................................................444
filesizeformat .............................................444
first ......................................................445
fix_ampersands ...........................................445
floatformat ................................................445
force_escape .............................................446
get_digit. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 446
iriencode .................................................446
join ......................................................446
last ......................................................447
length ....................................................447
length_is .................................................447
linebreaks ................................................447
linenumbers ..............................................447
ljust ......................................................447
lower ....................................................448
make_list .................................................448
phone2numeric ...........................................448
pluralize ..................................................448
pprint ....................................................448
random ...................................................449
removetags ...............................................449
rjust .....................................................449
safe ......................................................449
safeseq ..................................................449
slice .....................................................449
slugify ....................................................450
stringformat ..............................................450
striptags ..................................................450
time .....................................................450
timesince .................................................451
timeuntil ..................................................451
title ......................................................451
NCONTENTS xxv
truncatewords .............................................451
truncatewords_html .......................................451
unordered_list ............................................452
upper ....................................................452
urlencode .................................................452
urlize .....................................................452
urlizetrunc ................................................453
wordcount ................................................453
wordwrap ................................................453
yesno ....................................................453
APPENDIX F The django-admin Utility ..................................455
Usage .........................................................455
Getting Runtime Help ......................................456
App Names ...............................................456
Determining the Version ....................................456
Displaying Debug Output ...................................456
Available Subcommands ........................................456
cleanup ..................................................456
compilemessages .........................................456
createcachetable ..........................................457
createsuperuser ...........................................457
dbshell ...................................................457
diffsettings. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458
dumpdata ................................................458
flush .....................................................458
inspectdb .................................................459
loaddata <fixture fixture ...> ................................459
makemessages ...........................................461
reset <appname appname ...> ..............................461
runfcgi [options] ...........................................462
runserver .................................................462
shell .....................................................463
sql <appname appname ...> ................................463
sqlall <appname appname ...> ..............................463
sqlclear <appname appname ...> ...........................463
sqlcustom <appname appname ...> .........................464
sqlflush ..................................................464
sqlindexes <appname appname ...> .........................464
sqlreset <appname appname ...> ...........................464
NCONTENTS
xxvi
sqlsequencereset <appname appname ...> ...................464
startapp <appname> ......................................464
startproject <projectname> .................................464
syncdb ...................................................464
test ......................................................465
testserver <fixture fixture ...> ...............................465
validate ..................................................465
Default Options .................................................466
--pythonpath ..............................................466
--settings .................................................466
--traceback ...............................................466
--verbosity ................................................466
Extra Niceties ..................................................467
Syntax Coloring ...........................................467
Bash Completion ..........................................467
APPENDIX G Request and Response Objects ...........................469
HttpRequest ...................................................469
QueryDict Objects .........................................471
A Complete Example .......................................473
HttpResponse ..................................................474
Construction HttpResponses ................................474
Setting Headers ...........................................474
HttpResponse Subclasses ..................................474
Returning Errors ...........................................475
Customizing the 404 (Not Found) View .......................476
Customizing the 500 (Server Error) View ......................477
INDEX ......................................................................479
xxvii
About the Authors
NADRIAN HOLOVATY is a cocreator and co–Benevolent Dictator for Life of Django. He runs a Web
start-up called EveryBlock. He lives with his wife in Chicago and spends his free time attempt-
ing to play guitar in the style of Django Reinhardt.
NJACOB KAPLAN-MOSS is a lead developer and co–Benevolent Dictator for Life of Django. Jacob
is a partner at Revolution Systems, a consultancy that helps companies make the most of open
source software. Jacob previously worked for the Lawrence Journal-World, the locally owned
newspaper in Lawrence, Kansas where Django was developed. At Journal-World Jacob was the
lead developer of Ellington, a commercial Web-publishing platform for media companies.
xxix
About the Technical Reviewer
NSEAN LEGASSICK has been creating software for over 15 years. His work
designing the architecture of South African open source framework
Chisimba has contributed significantly to software-engineering capac-
ity-building in Africa and other areas of the developing world. He is a
cofounder of MobGeo, a start-up developing innovative location-aware
mobile marketing solutions. Away from the world of software, he writes
on politics and culture.
xxxi
Acknowledgments
Thanks to the many people who contributed to our online first drafts, and thanks to the folks
at Apress for their great editing.
xxxiii
Preface
Welcome to the second edition of The Definitive Guide to Django, informally known as The
Django Book! This book aims to teach you how to use the Django Web framework to develop
Web sites efficiently.
When Jacob Kaplan-Moss and I wrote the first edition of this book, Django was still in a
pre-1.0 stage. Once Django version 1.0 was released, with its several backward-incompatible
changes, the first edition inevitably became outdated and people began demanding an update.
I’m happy to report this edition covers Django 1.1 and should serve you well for some time.
My thanks go to the many contributors who posted comments, corrections, and rants to
dppl6++`f]jck^kkg*_ki+, the accompanying Web site for this book, where I posted chapter
drafts as I wrote them. You guys are great.
Adrian Holovaty
Cocreator and co–Benevolent Dictator for Life, Django
xxxv
Introduction
In the early days, Web developers wrote every page by hand. Updating a Web site meant edit-
ing HTML; a “redesign” involved redoing every single page, one at a time.
As Web sites grew and became more ambitious, it quickly became obvious that that
situation was tedious, time-consuming, and ultimately untenable. A group of enterprising
hackers at NCSA (the National Center for Supercomputing Applications, where Mosaic, the
first graphical Web browser, was developed) solved this problem by letting the Web server
spawn external programs that could generate HTML dynamically. They called this protocol
the Common Gateway Interface, or CGI, and it changed the Web forever.
It’s hard now to imagine what a revelation CGI must have been: instead of treating HTML
pages as simple files on disk, CGI allows you to think of your pages as resources generated
dynamically on demand. The development of CGI ushered in the first generation of dynamic
Web sites.
However, CGI has its problems: CGI scripts need to contain a lot of repetitive “boilerplate”
code, they make code reuse difficult, and they can be difficult for first-time developers to write
and understand.
PHP fixed many of these problems, and it took the world by storm—it’s now by far the
most popular tool used to create dynamic Web sites, and dozens of similar languages and
environments (ASP, JSP, etc.) have followed PHP’s design closely. PHP’s major innovation is its
ease of use: PHP code is simply embedded into plain HTML. The learning curve for someone
who already knows HTML is extremely shallow.
But PHP has its own problems; its very ease of use encourages sloppy, repetitive, ill-
conceived code. Worse, PHP does little to protect programmers from security vulnerabilities,
and thus many PHP developers found themselves learning about security only once it was
too late.
These and similar frustrations led directly to the development of the current crop of
“third- generation” Web-development frameworks. These frameworks—Django and Ruby
on Rails appear to be the most popular these days—recognize that the Web’s importance has
escalated of late.
With this new explosion of Web development comes yet another increase in ambition;
Web developers are expected to do more and more every day.
Django was invented to meet these new ambitions. Django lets you build deep, dynamic,
interesting sites in an extremely short time. Django is designed to let you focus on the fun,
interesting parts of your job while easing the pain of the repetitive bits. In doing so, it provides
high-level abstractions of common Web-development patterns, shortcuts for frequent pro-
gramming tasks, and clear conventions on how to solve problems. At the same time, Django
tries to stay out of your way, letting you work outside the scope of the framework as needed.
NINTRODUCTION
xxxvi
We wrote this book because we firmly believe that Django makes Web development bet-
ter. It’s designed to quickly get you moving on your own Django projects, and then ultimately
teach you everything you need to know to successfully design, develop, and deploy a site that
you’ll be proud of.
We’re extremely interested in your feedback. The online version of this book—available
at dppl6++`f]jck^kkg*_ki+—will let you comment on any part of the book and discuss it with
other readers. We’ll do our best to read all the comments posted there, and to respond to as
many as possible. If you prefer e-mail, please drop us a line at baa`^]_g<`f]jck^kkg*_ki. Either
way, we’d love to hear from you!
We’re glad you’re here, and we hope you find Django as exciting, fun, and useful as we do.
PART 1
Getting Started
3
CHAPTER 1
Introduction to Django
This book is about Django, a Web-development framework that saves you time and makes
Web development a joy. Using Django, you can build and maintain high-quality Web applica-
tions with minimal fuss.
At its best, Web development is an exciting, creative act; at its worst, it can be a repeti-
tive, frustrating nuisance. Django lets you focus on the fun stuff—the crux of your Web
application—while easing the pain of the repetitive bits. In doing so, it provides high-level
abstractions of common Web development patterns, shortcuts for frequent programming
tasks, and clear conventions for how to solve problems. At the same time, Django tries to stay
out of your way, letting you work outside the scope of the framework as needed.
The goal of this book is to make you a Django expert. The focus is twofold. First, we
explain, in depth, what Django does and how to build Web applications with it. Second, we
discuss higher-level concepts where appropriate, answering the question “How can I apply
these tools effectively in my own projects?” By reading this book, you’ll learn the skills needed
to develop powerful Web sites quickly, with code that is clean and easy to maintain.
What Is a Web Framework?
Django is a prominent member of a new generation of Web frameworks—but what does that
term mean, precisely?
To answer that question, let’s consider the design of a Web application written in Python
without a framework. Throughout this book, we’ll take this approach of showing you basic
ways to get work done without shortcuts, in the hope that you’ll recognize why shortcuts are
so helpful. (It’s also valuable to know how to get things done without shortcuts because short-
cuts aren’t always available. And most importantly, knowing why things work the way they do
makes you a better Web developer.)
One of the simplest, most direct ways to build a Python Web app from scratch is to use
the Common Gateway Interface (CGI) standard, which was a popular technique circa 1998.
Here’s a high-level explanation of how it works: create a Python script that outputs HTML,
then save the script to a Web server with a *_ce extension and visit the page in your Web
browser. That’s it.
CHAPTER 1 N INTRODUCTION TO DJANGO
4
Here’s a sample Python CGI script that displays the ten most recently published books
from a database. Don’t worry about syntax details; just get a feel for the basic things it’s doing.
+qon+^ej+ajrlupdkj
eilknpIuOMH`^
lnejp?kjpajp)Pula6patp+dpihXj
lnejp8dpih:8da]`:8pepha:>kkgo8+pepha:8+da]`:
lnejp8^k`u:
lnejp8d-:>kkgo8+d-:
lnejp8qh:
_kjja_pekj9IuOMH`^*_kjja_p$qoan9#ia#(l]oos`9#hapiaej#(`^9#iu[`^#%
_qnokn9_kjja_pekj*_qnokn$%
_qnokn*ata_qpa$OAHA?Pj]iaBNKI^kkgoKN@AN>Ulq^[`]pa@AO?HEIEP-,%
bknnksej_qnokn*bap_d]hh$%6
lnejp8he:!o8+he:!nksW,Y
lnejp8+qh:
lnejp8+^k`u:8+dpih:
_kjja_pekj*_hkoa$%
First, to fulfill the requirements of CGI, this code prints a “Content-Type” line, followed
by a blank line. It prints some introductory HTML, connects to a database, and runs a query to
retrieve the names of the latest ten books. Looping over those books, it generates an HTML list
of the titles. Finally, it prints the closing HTML and closes the database connection.
With a one-off page like this one, the write-it-from-scratch approach isn’t necessarily bad.
For one thing, this code is simple to comprehend—even a novice developer can read these 16
lines of Python and understand everything it does, from start to finish. There’s nothing else
to learn, no other code to read. It’s also simple to deploy: just save this code in a file that ends
with *_ce, upload that file to a Web server, and visit that page with a browser.
Despite its simplicity, this approach has a number of problems and annoyances. Ask your-
self these questions:
Ê UÊ 7>ÌÊ>««iÃÊÜiÊÕÌ«iÊ«>ÀÌÃÊvÊÞÕÀÊ>««V>ÌÊii`ÊÌÊViVÌÊÌÊÌiÊ`>Ì>-
base? Surely that database-connecting code shouldn’t need to be duplicated in each
individual CGI script. The pragmatic thing to do would be to refactor it into a shared
function.
Ê UÊ -Õ`Ê>Ê`iÛi«iÀÊreally have to worry about printing the “Content-Type” line and
remembering to close the database connection? This sort of boilerplate reduces pro-
grammer productivity and introduces opportunities for mistakes. These setup- and
teardown-related tasks would best be handled by some common infrastructure.
CHAPTER 1 N INTRODUCTION TO DJANGO 5
Ê UÊ 7>ÌÊ>««iÃÊÜiÊÌÃÊV`iÊÃÊÀiÕÃi`ÊÊÕÌ«iÊiÛÀiÌÃ]Êi>VÊÜÌÊ>ÊÃi«>-
rate database and password? At this point, some environment-specific configuration
becomes essential.
Ê UÊ 7>ÌÊ>««iÃÊÜiÊ>Ê7iLÊ`iÃ}iÀÊÜÊ>ÃÊÊiÝ«iÀiViÊV`}Ê*ÞÌÊÜÃiÃÊÌÊ
redesign the page? One wrong character could crash the entire application. Ideally,
the logic of the page—the retrieval of book titles from the database—would be sepa-
rate from the HTML display of the page so that a designer could edit the latter without
affecting the former.
These problems are precisely what a Web framework intends to solve. A Web framework
provides a programming infrastructure for your applications so that you can focus on writ-
ing clean, maintainable code without having to reinvent the wheel. In a nutshell, that’s what
Django does.
The MVC Design Pattern
Let’s dive in with a quick example that demonstrates the difference between the previous
approach and a Web framework’s approach. Here’s how you might write the previous
CGI code using Django. The first thing to note is that we split it over three Python files
(ik`aho*lu, reaso*lu, qnho*lu) and an HTML template (h]paop[^kkgo*dpih):
ik`aho*lu$pda`]p]^]oap]^hao%
bnki`f]jck*`^eilknpik`aho
_h]oo>kkg$ik`aho*Ik`ah%6
j]ia9ik`aho*?d]nBeah`$i]t[hajcpd91,%
lq^[`]pa9ik`aho*@]paBeah`$%
reaso*lu$pda^qoejaoohkce_%
bnki`f]jck*odknp_qpoeilknpnaj`an[pk[naolkjoa
bnkiik`ahoeilknp>kkg
`abh]paop[^kkgo$namqaop%6
^kkg[heop9>kkg*k^fa_po*kn`an[^u$#)lq^[`]pa#%W6-,Y
napqnjnaj`an[pk[naolkjoa$#h]paop[^kkgo*dpih#(w#^kkg[heop#6^kkg[heopy%
qnho*lu$pdaQNH_kjbecqn]pekj%
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
eilknpreaso
qnhl]ppanjo9l]ppanjo$##(
$n#Zh]paop+ #(reaso*h]paop[^kkgo%(
%
CHAPTER 1 N INTRODUCTION TO DJANGO
6
h]paop[^kkgo*dpih$pdapailh]pa%
8dpih:8da]`:8pepha:>kkgo8+pepha:8+da]`:
8^k`u:
8d-:>kkgo8+d-:
8qh:
w!bkn^kkgej^kkg[heop!y
8he:ww^kkg*j]iayy8+he:
w!aj`bkn!y
8+qh:
8+^k`u:8+dpih:
Again, don’t worry about the particulars of syntax; just get a feel for the overall design. The
main thing to note here is the separation of concerns:
Ê UÊ /iÊik`aho*lu file contains a description of the database table, represented by a
Python class. This class is called a model. Using it, you can create, retrieve, update, and
delete records in your database using simple Python code rather than writing repetitive
SQL statements.
Ê UÊ /iÊreaso*lu file contains the business logic for the page. The h]paop[^kkgo$% function
is called a view.
Ê UÊ /iÊqnho*lu file specifies which view is called for a given URL pattern. In this case, the
URL +h]paop+ will be handled by the h]paop[^kkgo$% function. In other words, if your
domain is example.com, any visit to the URL dppl6++at]ilha*_ki+h]paop+ will call the
h]paop[^kkgo$% function.
Ê UÊ /iÊh]paop[^kkgo*dpih file is an HTML template that describes the design of the page.
It uses a template language with basic logic statements—for example, w!bkn^kkgej
^kkg[heop!y.
Taken together, these pieces loosely follow a pattern called Model-View-Controller (MVC).
Simply put, MVC is way of developing software so that the code for defining and accessing
data (the model) is separate from request-routing logic (the controller), which in turn is sepa-
rate from the user interface (the view). (We’ll discuss MVC in more depth in Chapter 5.)
A key advantage of such an approach is that components are loosely coupled. Each distinct
piece of a Django-powered Web application has a single key purpose and can be changed
independently without affecting the other pieces. For example, a developer can change the
URL for a given part of the application without affecting the underlying implementation. A
designer can change a page’s HTML without having to touch the Python code that renders it.
A database administrator can rename a database table and specify the change in a single place
rather than having to search and replace through a dozen files.
In this book, each component of MVC gets its own chapter. Chapter 3 covers views,
Chapter 4 covers templates, and Chapter 5 covers models.
CHAPTER 1 N INTRODUCTION TO DJANGO 7
Django's History
Before we dive into more code, we should take a moment to explain Django’s history. We
noted earlier that we’ll be showing you how to do things without shortcuts so that you more
fully understand the shortcuts. Similarly, it’s useful to understand why Django was created,
because knowledge of the history will put into context why Django works the way it does.
If you’ve been building Web applications for a while, you’re probably familiar with the
problems in the CGI example we presented earlier. The classic Web developer’s path goes
something like this:
1. Write a Web application from scratch.
2. Write another Web application from scratch.
3. Realize the application from step 1 shares much in common with the application from
step 2.
4. Refactor the code so that application 1 shares code with application 2.
5. Repeat steps 2–4 several times.
6. Realize you’ve invented a framework.
This is precisely how Django itself was created!
Django grew organically from real-world applications written by a Web-development
team in Lawrence, Kansas, USA. It was born in the fall of 2003, when the Web programmers
at the Lawrence Journal-World newspaper, Adrian Holovaty and Simon Willison, began using
Python to build applications.
The World Online team, responsible for the production and maintenance of several local
news sites, thrived in a development environment dictated by journalism deadlines. For the
sites—including LJWorld.com, Lawrence.com, and KUsports.com—journalists (and manage-
ment) demanded that features be added and entire applications be built on an intensely fast
schedule, often with only days’ or hours’ notice. Thus, Simon and Adrian developed a time-
saving Web-development framework out of necessity—it was the only way they could build
maintainable applications under the extreme deadlines.
In summer 2005, after having developed this framework to a point where it was efficiently
powering most of World Online’s sites, the team, which now included Jacob Kaplan-Moss,
decided to release the framework as open source software. They released it in July 2005 and
named it Django, after the jazz guitarist Django Reinhardt.
Now, several years later, Django is a well-established open source project with tens of
thousands of users and contributors spread across the planet. Two of the original World
Online developers (the “Benevolent Dictators for Life,” Adrian and Jacob) still provide central
guidance for the framework’s growth, but it’s much more of a collaborative team effort.
This history is relevant because it helps explain two key things. The first is Django’s “sweet
spot.” Because Django was born in a news environment, it offers several features (such as its
admin site, covered in Chapter 6) that are particularly well suited for “content” sites—sites
like Amazon.com, Craigslist, and The Washington Post that offer dynamic, database-driven
information. Don’t let that turn you off, though—although Django is particularly good for
developing those sorts of sites, that doesn’t preclude it from being an effective tool for build-
ing any sort of dynamic Web site. (There’s a difference between being particularly effective at
something and being ineffective at other things.)
CHAPTER 1 N INTRODUCTION TO DJANGO
8
The second matter to note is how Django’s origins have shaped the culture of its open
source community. Because Django was extracted from real-world code rather than being an
academic exercise or a commercial product, it is acutely focused on solving Web-development
problems that Django’s developers themselves have faced—and continue to face. As a result,
Django itself is actively improved on an almost daily basis. The framework’s maintainers have
a vested interest in making sure Django saves developers time, produces applications that are
easy to maintain, and performs well under load. If nothing else, the developers are motivated
by their own selfish desires to save themselves time and enjoy their jobs. (To put it bluntly,
they eat their own dog food.)
How to Read This Book
In writing this book, we tried to strike a balance between readability and reference, with a bias
toward readability. Our goal with this book, as stated earlier, is to make you a Django expert,
and we believe the best way to teach is through prose and plenty of examples, rather than
providing an exhaustive but bland catalog of Django features. (As the saying goes, you can’t
expect to teach somebody how to speak a language merely by teaching them the alphabet.)
With that in mind, we recommend that you read Chapters 1 through 12 in order. They
form the foundation of how to use Django; once you’ve read them, you’ll be able to build
and deploy Django-powered Web sites. Specifically, Chapters 1 through 7 are the “core cur-
riculum,” Chapters 8 through 11 cover more-advanced Django usage, and Chapter 12 covers
deployment. The remaining chapters, 13 through 20, focus on specific Django features and
can be read in any order.
The appendixes are for reference. They, along with the free documentation at dppl6++sss*
`f]jcklnkfa_p*_ki+, are probably what you’ll flip back to occasionally to recall syntax or find
quick synopses of what certain parts of Django do.
Required Programming Knowledge
Readers of this book should understand the basics of procedural and object-oriented pro-
gramming: control structures (e.g., eb, sdeha, bkn), data structures (lists, hashes/dictionaries),
variables, classes, and objects.
Experience in Web development is, as you may expect, very helpful, but it’s not required
to understand this book. Throughout the book, we try to promote best practices in Web devel-
opment for readers who lack this experience.
Required Python Knowledge
At its core, Django is simply a collection of libraries written in the Python programming
language. To develop a site using Django, you write Python code that uses these libraries.
Learning Django, then, is a matter of learning how to program in Python and understanding
how the Django libraries work.
CHAPTER 1 N INTRODUCTION TO DJANGO 9
If you have experience programming in Python, you should have no trouble diving in. By
and large, the Django code doesn’t perform a lot of “magic” (i.e., programming trickery whose
implementation is difficult to explain or understand). For you, learning Django will be a mat-
ter of learning Django’s conventions and APIs.
If you don’t have experience programming in Python, you’re in for a treat. It’s easy to
learn and a joy to use! Although this book doesn’t include a full Python tutorial, it highlights
Python features and functionality where appropriate, particularly when code doesn’t immedi-
ately make sense. Still, we recommend you read the official Python tutorial, available online at
dppl6++`k_o*lupdkj*knc+pqp+. We also recommend Mark Pilgrim’s free book Dive Into Python
(Apress, 2004), available at dppl6++sss*`eraejpklupdkj*knc+ and published in print by Apress.
Required Django Version
This book covers Django 1.1.
Django’s developers maintain backward compatibility within “major version” numbers.
This commitment means that, if you write an application for Django 1.1, it will still work for
1.2, 1.3, 1.9, and any other version number that starts with “1.” Once Django hits 2.0, though,
your applications might need to be rewritten—but version 2.0 is a long way away. As a point of
reference, it took more than three years to release version 1.0. (This is very similar to the com-
patibility policy that applies to the Python language itself: code that was written for Python 2.0
works with Python 2.6, but not necessarily with Python 3.0.) Given that this book covers Django
1.1, it should serve you well for some time.
Getting Help
One of the greatest benefits of Django is its kind and helpful user community. For help with
any aspect of Django—from installation to application design to database design to deploy-
ment—feel free to ask questions online.
Ê UÊ /iÊ>}ÊÕÃiÀÃÊ>}ÊÃÌÊÃÊÜiÀiÊÌÕÃ>`ÃÊvÊ>}ÊÕÃiÀÃÊ>}ÊÕÌÊÌÊ>ÃÊ>`Ê
answer questions. Sign up for free at dppl6++sss*`f]jcklnkfa_p*_ki+n+`f]jck)qoano.
Ê UÊ /iÊ>}Ê,ÊV>iÊÃÊÜiÀiÊ>}ÊÕÃiÀÃÊ>}ÊÕÌÊÌÊV>ÌÊ>`Êi«Êi>VÊÌiÀÊÊ
real time. Join the fun by logging on to `f]jck on the Freenode IRC network.
What’s Next?
In the next chapter, we’ll get started with Django, covering installation and initial setup.
CHAPTER 2
Getting Started
Installing Django is a multistep process because of the multiple moving parts in modern Web
development environments. In this chapter, we’ll walk you through how to install the frame-
work and its few dependencies.
Because Django is “just” Python code, it runs anywhere Python does—including on some
cell phones! But this chapter just covers the common scenarios for Django installations. We’ll
assume that you’re installing it either on a desktop/laptop machine or on a server.
Later on (in Chapter 12), we’ll cover how to deploy Django to a production site.
Installing Python
Django is written purely in Python, so the first step in installing the framework is to make sure
that you have Python installed.
Python Versions
The core Django framework works with any Python version from 2.3 to 2.6, inclusive. Django’s
optional Geographic Information Systems (GIS) support requires Python 2.4 to 2.6.
If you’re not sure which version of Python to install and you have complete freedom over
the decision, pick the latest one in the 2.x series: version 2.6. Although Django works equally
well with any version from 2.3 to 2.6, the later versions of Python have performance improve-
ments and additional language features you might like to use in your applications. Plus,
certain third-party Django add-ons that you might want to use might require a version newer
than Python 2.3, so using a later version of Python keeps your options open.
DJANGO AND PYTHON 3.0
At the time of writing, Python 3.0 was released, but Django didn’t yet support it. Python 3.0 introduced a
substantial number of backward-incompatible changes to the language, so we expect that most major Python
libraries and frameworks, including Django, will take a few years to catch up.
If you’re new to Python and are wondering whether to learn Python 2.x or Python 3.x, our advice is to
stick with Python 2.x.
11
CHAPTER 2 N GETTING STARTED
12
Installation
If you’re on Linux or Mac OS X, you probably have Python already installed. Type lupdkj at a
command prompt (or in Applications/Utilities/Terminal in OS X). If you see something like
this, Python is installed:
Lupdkj.*0*-$.(I]n/-.,,1(,,6,16-,%
WC??/*/.,,/,/,0$=llha?kilqpan(Ej_*^qeh`-222%Ykj`]nsej
Puladahl(_klunecdp(_na`epoknhe_ajoabkniknaejbkni]pekj*
:::
Otherwise, you’ll need to download and install Python. It’s fast and easy, and detailed
instructions are available at dppl6++sss*lupdkj*knc+`ksjhk]`+.
Installing Django
At any given time, two distinct versions of Django are available to you: the latest official release
and the bleeding-edge trunk version. The version you decide to install depends on your priori-
ties. Do you want a stable and tested version of Django, or do you want a version containing
the latest features, perhaps so you can contribute to Django itself, at the expense of stability?
We recommend sticking with an official release, but it’s important to know that the trunk
development version exists because you’ll find it mentioned in the documentation and by
members of the community.
Installing an Official Release
Official releases have a version number, such as 1.0.3 or 1.1, and the latest one is always avail-
able at dppl6++sss*`f]jcklnkfa_p*_ki+`ksjhk]`+.
If you’re on a Linux distribution that includes a package of Django, it’s a good idea to use
the distributor’s version. That way, you’ll get security updates along with the rest of your sys-
tem packages.
If you don’t have access to a prepackaged version, you can download and install the
framework manually. To do so, first download the tarball, which will be named something
similar to @f]jck)-*,*.)bej]h*p]n*cv. (It doesn’t matter which local directory you download
this file into; the installation process will put Django’s files in the right place.) Then unzip it
and run oapql*luejop]hh, as you do with most Python libraries.
Here’s how that process looks on Unix systems:
1. p]ntvrb@f]jck)-*,*.)bej]h*p]n*cv
2. _`@f]jck)&
3. oq`klupdkjoapql*luejop]hh
On Windows, we recommend using 7-Zip (dppl6++sss*`f]jcklnkfa_p*_ki+n+3vel+) to
unzip *p]n*cv files. Once you’ve unzipped the file, start up a DOS shell (the command prompt)
with administrator privileges and run the following command from within the directory whose
name starts with @f]jck):
lupdkjoapql*luejop]hh
CHAPTER 2 N GETTING STARTED 13
In case you’re curious, Django’s files will be installed into your Python installation’s
oepa)l]_g]cao directory—a directory where Python looks for third-party libraries. Usually
it’s in a place similar to +qon+he^+lupdkj.*0+oepa)l]_g]cao.
Installing the Trunk Version
The latest and greatest Django development version is referred to as the trunk version, and it’s
available from Django’s Subversion repository. You should consider installing this version if
you want to work on the bleeding edge or if you want to contribute code to Django itself.
Subversion is a free, open source revision-control system, and the Django team uses it
to manage changes to the Django codebase. You can use a Subversion client to grab the very
latest Django source code and you can update your local version of the Django code, known
as your local checkout, at any given time to get the latest changes and improvements made by
Django developers.
When using trunk, keep in mind there’s no guarantee things won’t be broken at any given
moment. With that said, though, some members of the Django team run production sites on
trunk, so they have an incentive to keep it stable.
To grab the latest Django trunk, follow these steps:
1. Make sure that you have a Subversion client installed. You can get the software free
from dppl6++oq^ranoekj*pecneo*knc+ and you can find excellent documentation at
dppl6++orj^kkg*na`)^a]j*_ki+.
If you’re on a Mac with OS X 10.5 or later, you’re in luck; Subversion should already be
installed. You can verify this by typing orj))ranoekj in the Terminal.
2. Check out the trunk using the command orj_kdppl6++_k`a*`f]jcklnkfa_p*_ki+orj+
`f]jck+pnqjg`fpnqjg.
3. Locate your Python installation’s oepa)l]_g]cao directory, which is usually in a place
similar to +qon+he^+lupdkj.*0+oepa)l]_g]cao. If you have no idea, type this command
from a command prompt:
lupdkj)_#eilknpouo(llnejp7llnejp*llnejp$ouo*l]pd%#
The resulting output should include your oepa)l]_g]cao directory.
Within the oepa)l]_g]cao directory, create a file called `f]jck*lpd and edit it to contain
the full path to your `fpnqjg directory to it. For example, the file could contain just this
line:
+dkia+ia+_k`a+`fpnqjg
4. Place `fpnqjg+`f]jck+^ej on the system path. This directory includes management
utilities such as `f]jck)]`iej*lu.
NTip If*lpd files are new to you, you can learn more about them at dppl6++sss*`f]jcklnkfa_p*
_ki+n+lupdkj+oepa)ik`qha+.
CHAPTER 2 N GETTING STARTED
14
After downloading from Subversion and following the preceding steps, there’s no need to
run lupdkjoapql*luejop]hh—you just did the work by hand!
Because the Django trunk changes often with bug fixes and feature additions, you’ll prob-
ably want to update it every once in a while. To update the code, just run the command orj
ql`]pa from within the `fpnqjg directory. When you run that command, Subversion will con-
tact dppl6++_k`a*`f]jcklnkfa_p*_ki, determine whether any of Django’s code has changed,
and update your local version of the code with any changes that have been made since you last
updated. It’s quite slick.
Finally, if you use trunk, you should know how to figure out which version of trunk you’re
running. Knowing your version number is important if you ever need to reach out to the com-
munity for help or if you submit improvements to the framework. In these cases, you should
tell people which trunk version (also known as a revision number or changeset) that you’re
using. To find out your revision number, type orjejbk from within the `fpnqjg directory, and
look for the number after Revision. This number is incremented each time Django is changed,
whether through a bug fix, feature addition, documentation improvement, or anything else.
Among some members of the Django community, it’s a badge of honor to be able to say, “I’ve
been using Django since [insert very low revision number here].”
Testing the Django Installation
For some post-installation positive feedback, take a moment to test whether the installation
worked. In a command shell, change into another directory (not the directory that contains
the `f]jck directory) and start the Python interactive interpreter by typing lupdkj. If the instal-
lation was successful, you should be able to import the module `f]jck:
:::eilknp`f]jck
:::`f]jck*RANOEKJ
$-(-(,(#bej]h#(-%
INTERACTIVE INTERPRETER EXAMPLES
The Python interactive interpreter is a command-line program that lets you write a Python program interac-
tively. To start it, run the command lupdkj at the command line.
Throughout this book, we feature example Python interactive interpreter sessions. You can recognize
these examples by the triple greater-than signs (:::) that designate the interpreter’s prompt. If you’re copy-
ing examples from this book, don’t copy those greater-than signs.
CHAPTER 2 N GETTING STARTED 15
Multiline statements in the interactive interpreter are padded with three dots (***). For example:
:::lnejpPdeoeo]
***opnejcpd]pol]jo
***pdnaahejao*
Pdeoeo]
opnejcpd]pol]jo
pdnaahejao*
:::`abiu[bqj_pekj$r]hqa%6
***lnejpr]hqa
:::iu[bqj_pekj$#dahhk#%
dahhk
Those three dots at the start of the additional lines are inserted by the Python shell—they’re not part of
our input. We include them to be faithful to the actual output of the interpreter. If you copy our examples to
follow along, don’t copy those dots.
Setting Up a Database
At this point, you could very well begin writing a Web application with Django because
Django’s only hard-and-fast prerequisite is a working Python installation. However, odds
are you’ll be developing a database-driven Web site, in which case you’ll need to configure
a database server.
If you just want to start playing with Django, skip ahead to the “Starting a Project” sec-
tion—but keep in mind that all the examples in this book assume that you have a working
database set up.
Django supports four database engines:
Ê UÊ *ÃÌ}Ài-+Êdppl6++sss*lkopcnaomh*knc+)
Ê UÊ -+ÌiÊÎÊdppl6++sss*omhepa*knc+)
Ê UÊ Þ-+Êdppl6++sss*iuomh*_ki+)
Ê UÊ "À>ViÊdppl6++sss*kn]_ha*_ki+)
For the most part, all the engines work equally well with the core Django framework.
(A notable exception is Django’s optional GIS support, which is much more powerful with
*ÃÌ}Ài-+ÊÌ>ÊÜÌÊÌiÀÊ`>Ì>L>Ãið®ÊvÊÞÕ½ÀiÊÌÊÌi`ÊÌÊ>ÞÊi}>VÞÊÃÞÃÌiÊ>`Ê>ÛiÊÌiÊ
vÀii`ÊÌÊVÃiÊ>Ê`>Ì>L>ÃiÊL>Vi`]ÊÜiÊÀiVi`Ê*ÃÌ}Ài-+, which achieves a fine
balance between cost, features, speed, and stability.
CHAPTER 2 N GETTING STARTED
16
Setting up the database is a two-step process:
1. First, you’ll need to install and configure the database server. This process is beyond
the scope of this book, but each of the four database back-ends has rich documenta-
tion on its Web site. (If you’re on a shared hosting provider, the server is probably set
up already.)
2. Second, you’ll need to install the Python library for your particular database back-end.
This is a third-party bit of code that allows Python to interface with the database. We
outline the specific, per-database requirements in the following sections.
If you’re just playing around with Django and don’t want to install a database server, con-
Ã`iÀÊÕÃ}Ê-+Ìi°Ê-+Ìi is unique in the list of supported databases in that it doesn’t require
either of the preceding steps if you’re using Python 2.5 or higher. It merely reads and writes
its data to a single file on your filesystem, and Python versions 2.5 and higher include built-in
support for it.
On Windows, obtaining database driver binaries can be frustrating. If you’re eager to
Õ«Ê]ÊÜiÊÀiVi`ÊÕÃ}Ê*ÞÌÊÓ°xÊ>`ÊÌÃÊLÕÌÊÃÕ««ÀÌÊvÀÊ-+Ìe.
Using Django with PostgreSQL
IfÊÞÕÊÕÃiÊ*ÃÌ}Ài-+]ÊÞÕ½Êii`ÊÌÊÃÌ>ÊiÌiÀÊÌiÊlou_klc or lou_klc. package from
dppl6++sss*`f]jcklnkfa_p*_ki+n+lupdkj)lcomh+. We recommend lou_klc. because it is
newer, more actively developed, and can be easier to install. Either way, remember whether
you’re using version 1 or 2; you’ll need this information later.
vÊÞÕ½ÀiÊÕÃ}Ê*ÃÌ}Ài-+ÊÊ7`ÜÃ]ÊÞÕÊV>Êv`Ê«ÀiV«i`ÊL>ÀiÃÊvÊlou_klc at
dppl6++sss*`f]jcklnkfa_p*_ki+n+lupdkj)lcomh+sej`kso+.
If you’re on Linux, check whether your distribution’s package-management system offers
a package called lupdkj)lou_klc., lou_klc.)lupdkj, lupdkj)lkopcnaomh, or something similar.
Using Django with SQLite 3
If you’re using Python version 2.5 or higher, you’re in luck: no database-specific installation is
ÀiµÕÀi`ÊLiV>ÕÃiÊ*ÞÌÊÃ«ÃÊÜÌÊ-+ÌiÊÃÕ««ÀÌ°Ê-«Ê>i>`ÊÌÊÌiÊiÝÌÊÃiVÌ°
vÊÞÕ½ÀiÊÜÀ}ÊÜÌÊ*ÞÌÊÓ°{ÊÀÊ`iÀ]ÊÞÕ½Êii`Ê-+ÌiÊÎpnot version 2—from
dppl6++sss*`f]jcklnkfa_p*_ki+n+omhepa+ and the luomhepa package from dppl6++sss*
`f]jcklnkfa_p*_ki+n+lupdkj)omhepa+. Make sure that you have luomhepa version 2.0.3 or
higher.
"Ê7`ÜÃ]ÊÞÕÊV>ÊÃ«ÊÃÌ>}ÊÌiÊvÀiÀÊÌiÊÃi«>À>ÌiÊ-+ÌiÊL>ÀiîÊLiV>ÕÃiÊ
they’re statically linked into the luomhepa binaries.
If you’re on Linux, check whether your distribution’s package-management system offers
a package called lupdkj)omhepa/, omhepa)lupdkj, luomhepa, or something similar.
CHAPTER 2 N GETTING STARTED 17
Using Django with MySQL
Dj>}ÊÀiµÕÀiÃÊÞ-+Ê{°äÊÀÊ>LÛi°Ê/iÊΰx versions don’t support nested subqueries and
ÃiÊÌiÀÊv>ÀÞÊÃÌ>`>À`Ê-+ÊÃÌ>ÌiiÌð
You’ll also need to install the IuOMH`^ package from dppl6++sss*`f]jcklnkfa_p*_ki+n+
lupdkj)iuomh+.
If you’re on Linux, check whether your distribution’s package-management system offers
a package called lupdkj)iuomh, lupdkj)iuomh`^, iuomh)lupdkj, or something similar.
Using Django with Oracle
Django works with Oracle Database Server versions 9i and higher.
If you’re using Oracle, you’ll need to install the _t[Kn]_ha library, available at dppl6++
_t)kn]_ha*okqn_abknca*jap+. Use version 4.3.1 or higher, but avoid version 5.0 because of a
bug in that version of the driver.
Using Django Without a Database
As mentioned earlier, Django doesn’t actually require a database. If you just want to use it to
serve dynamic pages that don’t hit a database, that’s perfectly fine.
With that said, bear in mind that some of the extra tools bundled with Django do require
a database, so if you choose not to use a database, you’ll miss out on those features. (We high-
light these features throughout this book.)
Starting a Project
Once you’ve installed Python, Django, and (optionally) your database server/library, you can
take the first step of developing a Django application by creating a project.
A project is a collection of settings for an instance of Django, including database configu-
ration, Django-specific options, and application-specific settings.
If this is your first time using Django, you’ll have to take care of some initial setup. Create
a new directory to start working in, perhaps something like +dkia+qoanj]ia+`f_k`a+.
WHERE SHOULD THIS DIRECTORY LIVE?
If your background is in PHP, you’re probably used to putting code under the Web server’s document root (in
a location such as +r]n+sss). With Django, you don’t do that. It’s not a good idea to put any of this Python
code within your Web server’s document root because in doing so you risk the possibility that people will be
able to view your raw source code over the Web. That’s not good.
Put your code in a directory outside of the document root.
CHAPTER 2 N GETTING STARTED
18
Change into the directory you created and run the command `f]jck)]`iej*lu
op]nplnkfa_piuoepa. This will create a iuoepa directory in your current directory.
NNote `f]jck)]`iej*lu should be on your system path if you installed Django via its oapql*lu utility.
If you’re using trunk, you’ll find `f]jck)]`iej*lu in `fpnqjg+`f]jck+^ej. Because you’ll be using
`f]jck)]`iej*lu often, consider adding it to the system path. On Unix, you can do so by symlinking from
+qon+hk_]h+^ej by using a command such as oq`khj)o+l]pd+pk+`f]jck+^ej+`f]jck)]`iej*lu
+qon+hk_]h+^ej+`f]jck)]`iej*lu. On Windows, you’ll need to update your L=PD environment variable.
If you installed Django from a packaged version for your Linux distribution, `f]jck)]`iej*lu might be
called `f]jck)]`iej instead.
If you see a “permission denied” message when running `f]jck)]`iej*luop]nplnkfa_p,
you’ll need to change the file’s permissions. To do this, navigate to the directory where `f]jck)
]`iej*lu is installed (for example, _`+qon+hk_]h+^ej) and run the command _dik`'t
`f]jck)]`iej*lu.
The op]nplnkfa_p command creates a directory containing four files:
iuoepa+
[[ejep[[*lu
i]j]ca*lu
oappejco*lu
qnho*lu
These files are as follows:
ÊUÊ[[ejep[[*lu: A file required for Python to treat the iuoepa directory as a package (a
group of Python modules). It’s an empty file, and you normally won’t add anything to it.
ÊUÊi]j]ca*lu: A command-line utility that lets you interact with this Django project in
various ways. Type lupdkji]j]ca*ludahl to get a feel for what it can do. You should
never have to edit this file; it’s created in the directory purely for convenience.
ÊUÊoappejco*lu: Settings/configuration for this Django project. Take a look at it to get an
idea of the types of settings available, along with their default values.
ÊUÊqnho*lu: The URLs for this Django project. Think of it as the “table of contents” of
your Django-powered site. At the moment, it’s empty.
Despite their small size, these files already constitute a working Django application.
Running the Development Server
For more post-installation positive feedback, let’s run the Django development server to see
the bare-bones application in action.
The Django development server (also called the runserver after the command that
launches it) is a built-in, lightweight Web server you can use while developing your site. It’s
included with Django so you can develop your site rapidly, without having to deal with con-
figuring your production server (Apache, for example) until you’re ready for production. The
CHAPTER 2 N GETTING STARTED 19
development server watches your code and automatically reloads it, making it easy for you to
change your code without needing to restart anything.
To start the server, change into the project directory (_`iuoepa) if you haven’t already,
and run this command:
lupdkji]j]ca*lunqjoanran
You’ll see something like this:
R]he`]pejcik`aho***
,annknobkqj`*
@f]jckranoekj-*,(qoejcoappejco#iuoepa*oappejco#
@arahkliajpoanraneonqjjejc]pdppl6++-.3*,*,*-64,,,+
Mqeppdaoanransepd?KJPNKH)?*
This launches the server locally on port 8000, accessible only to connections from your
own computer. Now that it’s running, visit dppl6++-.3*,*,*-64,,,+ with your Web browser.
You’ll see a “Welcome to Django” page shaded in a pleasant pastel blue. It worked!
One final important note about the development server is worth mentioning before pro-
ceeding. Although this server is convenient for development, resist the temptation to use it in
anything resembling a production environment. The development server can handle only a
single request at a time reliably, and it has not gone through a security audit of any sort. When
the time comes to launch your site, see Chapter 12 for information on how to deploy Django.
CHANGING THE DEVELOPMENT SERVER'S HOST OR PORT
By default, the nqjoanran command starts the development server on port 8000, listening only for local
connections. If you want to change the server’s port, pass it as a command-line argument:
lupdkji]j]ca*lunqjoanran4,4,
When you specify an IP address, you tell the server to allow nonlocal connections, which is especially
helpful if you want to share a development site with other members of your team. The IP address ,*,*,*,
tells the server to listen on any network interface:
lupdkji]j]ca*lunqjoanran,*,*,*,64,,,
After this is done, other computers on your local network will be able to view your Django site by visiting
your IP address in their Web browsers (for example, dppl6++-5.*-24*-*-,/64,,,+)
Note that you’ll have to consult your network settings to determine your IP address on the local network.
Unix users can run eb_kjbec in a command prompt to get this information; Windows users can run el_kjbec.
What's Next?
Now that you have everything installed and the development server running, you’re ready to
learn the basics of serving Web pages with Django in Chapter 2.
CHAPTER 3
Views and URLconfs
In the previous chapter, we explained how to set up a Django project and run the Django
development server. In this chapter, you’ll learn the basics of creating dynamic Web pages
with Django.
Your First Django-Powered Page: Hello World
As a first goal, let’s create a Web page that outputs that famous example message: “Hello world.”
If you were publishing a simple “Hello world” Web page without a Web framework, you’d
simply type “Hello world” into a text file, call it dahhk*dpih, and upload it to a directory on a
Web server somewhere. Notice that you specified two key pieces of information about that
Web page: its contents (the string Dahhksknh`) and its URL (dppl6++sss*at]ilha*_ki+dahhk*
dpih, or maybe dppl6++sss*at]ilha*_ki+behao+dahhk*dpih if you put it in a subdirectory).
With Django, you specify those same two things, but in a different way. The contents of
the page are produced by a view function, and the URL is specified in a URLconf. First, let’s
write the “Hello world” view function.
Your First View
Within the iuoepa directory that `f]jck)]`iej*luop]nplnkfa_p made in the last chapter, cre-
ate an empty file called reaso*lu. This Python module will contain the views for this chapter.
Note that there’s nothing special about the name reaso*lu—Django doesn’t care what the file
is called, as you’ll see in a bit—but it’s a good idea to call it reaso*lu as a convention for the
benefit of other developers reading your code.
A “Hello world” view is simple. Here’s the entire function, plus eilknp statements, which
you should type into the reaso*lu file:
bnki`f]jck*dppleilknpDpplNaolkjoa
`abdahhk$namqaop%6
napqnjDpplNaolkjoa$Dahhksknh`%
21
CHAPTER 3 N VIEWS AND URLCONFS
22
Let’s step through this code one line at a time:
Ê UÊ ÀÃÌ]ÊÞÕÊ«ÀÌÊÌiÊV>ÃÃÊDpplNaolkjoa, which lives in the `f]jck*dppl module. You
need to import this class because it’s used later in the code.
Ê iÝÌ]ÊÞÕÊ`iviÊ>ÊvÕVÌÊV>i`Êdahhk—the view function.
Ê UÊ >VÊÛiÜÊvÕVÌÊÌ>iÃÊ>ÌÊi>ÃÌÊiÊ«>À>iÌiÀ]ÊV>i`Ênamqaop by convention. This is
an object that contains information about the current Web request that has triggered
this view, and it’s an instance of the class `f]jck*dppl*DpplNamqaop. In this example,
you don’t do anything with namqaop, but it must be the first parameter of the view
nonetheless.
Ê ÌiÊÌ>ÌÊÌiÊ>iÊvÊÌiÊÛiÜÊvÕVÌÊ`iÃ½ÌÊ>ÌÌiÀÆÊÌÊ`iÃ½ÌÊ>ÛiÊÌÊLiÊ>i`Ê
in a certain way for Django to recognize it. We called it dahhk because that name clearly
indicates the gist of the view, but it could just as well be named dahhk[skj`anbqh[
^a]qpebqh[sknh`, or something equally revolting. The next section, “Your First
URLconf,” will shed light on how Django finds this function.
Ê UÊ /iÊvÕVÌÊÃÊ>ÊÃ«iÊiiÀ\ÊÌÊiÀiÞÊÀiÌÕÀÃÊ>ÊDpplNaolkjoa object that has
been instantiated with the text Dahhksknh`.
The main lesson is this: a view is just a Python function that takes an DpplNamqaop as its
first parameter and returns an instance of DpplNaolkjoa. In order for a Python function to be a
Django view, it must do these two things. (There are exceptions, but we’ll get to them later.)
Your First URLconf
If at this point you run lupdkji]j]ca*lunqjoanran again, you’ll still see the “Welcome to
Django” message, with no trace of the “Hello world” view anywhere. That’s because the iuoepa
project doesn’t yet know about the dahhk viewÆÊÞÕÊii`ÊÌÊÌiÊ>}ÊiÝ«VÌÞÊÌ>ÌÊÞÕ½ÀiÊ
activating this view at a particular URL. (Continuing the previous analogy of publishing static
HTML files, at this point you’ve created the HTML file but haven’t uploaded it to a directory on
the server yet.) To hook a view function to a particular URL with Django, use a URLconf.
A URLconf is like a table of contents for a Django-powered Web site. Basically, it’s a map-
ping between URLs and the view functions that should be called for those URLs. It’s how you
tell Django, “For this URL, call this code, and for that URL, call that code.” For example, “When
somebody visits the URL +bkk+, call the view function bkk[reas$%, which lives in the Python
module reaso*lu.”
When you executed `f]jck)]`iej*luop]nplnkfa_p in the previous chapter, the script cre-
ated a URLconf for you automatically: the file qnho*lu. By default, it looks something like this:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
Qj_kiiajppdajatppskhejaopkaj]^hapda]`iej6
bnki`f]jck*_kjpne^eilknp]`iej
]`iej*]qpk`eo_kran$%
CHAPTER 3 N VIEWS AND URLCONFS 23
qnhl]ppanjo9l]ppanjo$##(
At]ilha6
$n#Ziuoepa+#(ej_hq`a$#iuoepa*bkk*qnho#%%(
Qj_kiiajppda]`iej+`k_heja^ahks]j`]``#`f]jck*_kjpne^*]`iej`k_o#
pkEJOP=HHA@[=LLOpkaj]^ha]`iej`k_qiajp]pekj6
$n#Z]`iej+`k_+#(ej_hq`a$#`f]jck*_kjpne^*]`iej`k_o*qnho#%%(
Qj_kiiajppdajatphejapkaj]^hapda]`iej6
$n#Z]`iej+#(ej_hq`a$]`iej*oepa*qnho%%(
%
This default URLconf includes some commonly used Django features commented out, so
activating those features is as easy as uncommenting the appropriate lines. If you ignore the
commented-out code, here’s the essence of a URLconf:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
qnhl]ppanjo9l]ppanjo$##(
%
Let’s step through this code one line at a time:
Ê UÊ /iÊvÀÃÌÊiÊ«ÀÌÃÊ>ÊLiVÌÃÊvÀÊÌiÊ`f]jck*_kjb*qnho*`ab]qhpo module, which is
Django’s URLconf infrastructure. This includes a function called l]ppanjo.
Ê UÊ /iÊÃiV`ÊiÊV>ÃÊÌiÊvÕVÌÊl]ppanjo and saves the result into a variable called
qnhl]ppanjo. The l]ppanjo function gets passed only a single argument: the empty
string. (The string can be used to supply a common prefix for view functions, which
we’ll cover in Chapter 8.)
The main thing to note is the variable qnhl]ppanjo, which Django expects to find in the
URLconf module. This variable defines the mapping between URLs and the code that handles
those URLs. By default, the URLconf is empty—the Django application is a blank slate.
NNote That’s how Django knew to show you the “Welcome to Django” page in the last chapter. If your
URLconf is empty, Django assumes that you just started a new project, so it displays that message.
To add a URL and view to the URLconf, just add a Python tuple mapping a URL pattern to
the view function. Here’s how to hook in the dahhk view:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnkiiuoepa*reasoeilknpdahhk
qnhl]ppanjo9l]ppanjo$##(
$#Zdahhk+ #(dahhk%(
%
CHAPTER 3 N VIEWS AND URLCONFS
24
NNote We removed the commented-out code for brevity. You can choose to leave those lines in if you want.
Two changes were made:
Ê UÊ ÀÃÌ]ÊÌiÊdahhk view was imported from its module: iuoepa+reaso*lu, which translates
into iuoepa*reaso in Python import syntax. (This assumes that iuoepa+reaso*lu is on
ÌiÊ*ÞÌÊ«>ÌÆÊÃiiÊÌiÊÃ`iL>ÀÊvÀÊ`iÌ>ð®
Ê iÝÌ]ÊÌiÊiÊ$#Zdahhk+ #(dahhk% was added to qnhl]ppanjo. This line is referred to as
a URLpattern. It’s a Python tuple in which the first element is a pattern-matching string
>ÊÀi}Õ>ÀÊiÝ«ÀiÃÃÆÊÀiÊÊÌÃÊÊ>ÊLÌ®Ê>`ÊÌiÊÃiV`ÊiiiÌÊÃÊÌiÊÛiÜÊvÕV-
tion to use for that pattern.
In a nutshell, Django was told that any request to the URL +dahhk+ should be handled by
the dahhk view function.
PYTHON PATH
The Python path is the list of directories on your system where Python looks when you use the Python eilknp
statement.
For example, let’s say your Python path is set to W##(#+qon+he^+lupdkj.*0+oepa)l]_g]cao#(
#+dkia+qoanj]ia+`f_k`a#Y. If you execute the Python statement bnkibkkeilknp^]n, Python will
look for a module called bkk*lu in the current directory. (The first entry in the Python path, an empty string,
means “the current directory.”) If that file doesn’t exist, Python will look for the file +qon+he^+lupdkj.*0+
oepa)l]_g]cao+bkk*lu. If that file doesn’t exist, it will try +dkia+qoanj]ia+`f_k`a+bkk*lu. Finally, if
that file doesn’t exist, it will raise EilknpAnnkn.
If you’re interested in seeing the value of your Python path, start the Python interactive interpreter and
type this:
:::eilknpouo
:::lnejpouo*l]pd
You usually don’t have to worry about setting your Python path—Python and Django take care of things
for you automatically behind the scenes. (Setting the Python path is one of the things that the i]j]ca*lu
script does.)
It’s worth discussing the syntax of this URLpattern because it might not be immediately
obvious. Although you want to match the URL +dahhk+, the pattern looks a bit different from
that. Here’s why:
CHAPTER 3 N VIEWS AND URLCONFS 25
Ê UÊ >}ÊÀiÛiÃÊÌiÊÃ>ÃÊvÀÊÌiÊvÀÌÊvÊiÛiÀÞÊV}Ê1,ÊLivÀiÊÌÊViVÃÊ
the URLpatterns. This means that the URLpattern doesn’t include the leading slash
in +dahhk+. (At first, this requirement might seem counterintuitive, but it simplifies
things—such as the inclusion of URLconfs within other URLconfs, which we’ll cover
in Chapter 8.)
Ê UÊ /iÊ«>ÌÌiÀÊVÕ`iÃÊ>ÊV>ÀiÌÊZ) and a dollar sign ( ). These regular expression char-
acters have a special meaning: the caret means “require that the pattern matches the
start of the string,” and the dollar sign means “require that the pattern matches the end
of the string.”
Ê UÊ /ÃÊVVi«ÌÊÃÊLiÃÌÊiÝ«>i`ÊLÞÊ>ÊiÝ>«i°ÊvÊÞÕÊ>`ÊÕÃi`ÊÌiÊ«>ÌÌiÀÊ#Zdahhk+#
(without a dollar sign at the end), any URL starting with +dahhk+ would match (for
example, +dahhk+bkk and +dahhk+^]n, not just +dahhk+). Similarly, if you leave off the
initial caret character (for example, #dahhk+ #), Django would match any URL that
ends with dahhk+, such as +bkk+^]n+dahhk+. If you simply use dahhk+ without a caret
or a dollar sign, any URL containing dahhk+ would match (for example, +bkk+dahhk+
^]n). Thus, you use both the caret and dollar sign to ensure that only the URL +dahhk+
matches—nothing more, nothing less.
Ê UÊ ÃÌÊ1,«>ÌÌiÀÃÊÃÌ>ÀÌÊÜÌÊV>ÀiÌÃÊ>`Êi`ÊÜÌÊ`>ÀÊÃ}Ã]ÊLÕÌÊ̽ÃÊViÊÌÊ>ÛiÊÌiÊ
flexibility to perform more sophisticated matches.
Ê UÊ 9ÕÊ}ÌÊLiÊÜ`iÀ}ÊÜ>ÌÊ>««iÃÊvÊÃiiÊÀiµÕiÃÌÃÊÌiÊ1,Ê+dahhk (that is,
without a trailing slash). Because the URLpattern requires a trailing slash, that URL
would not match. However, by default, any request to a URL that doesn’t match a
URLpattern and doesn’t end with a slash will be redirected to the same URL with a
trailing slash. (This is regulated by the =LLAJ@[OH=OD Django setting, which is covered
in Appendix D.)
Ê UÊ vÊÞÕ½ÀiÊÌiÊÌÞ«iÊvÊ«iÀÃÊÜÊiÃÊ>Ê1,ÃÊÌÊi`ÊÜÌÊÃ>ÃiÃÊÜVÊÃÊÌiÊ
preference of Django’s developers), all you need to do is add a trailing slash to each
URLpattern and leave =LLAJ@[OH=OD set to Pnqa. If you prefer your URLs not to have
trailing slashes, or if you want to decide it on a per-URL basis, set =LLAJ@[OH=OD to
B]hoa and put trailing slashes in your URLpatterns as you see fit.
The other thing to note about this URLconf is that the dahhk view function was passed as
an object without calling the function. This is a key feature of Python (and other dynamic lan-
guages): functions are first-class objects, which means that you can pass them around just like
any other variables. Cool stuff, eh?
To test the changes to the URLconf, start the Django development server, as you did in
Chapter 2, by running the command lupdkji]j]ca*lunqjoanran. (If you left it running,
that’s fine, too. The development server automatically detects changes to your Python code
and reloads as necessary, so you don’t have to restart the server between changes.) The
server is running at the address dppl6++-.3*,*,*-64,,,+, so open up a Web browser and go
to dppl6++-.3*,*,*-64,,,+dahhk+. You should see the text “Hello world”—the output of your
Django view.
Hooray! You made your first Django-powered Web page.
CHAPTER 3 N VIEWS AND URLCONFS
26
REGULAR EXPRESSIONS
You can use a regular expression (regex) as a compact way of specifying patterns in text. While Django
URLconfs allow arbitrary regexes for powerful URL matching, you’ll probably only use a few regex symbols in
practice. Here’s a selection of common symbols.
Symbol Matches
* (dot) Any single character
X` Any single digit
W=)VY Any character between = and V (uppercase)
W])vY Any character between ] and v (lowercase)
W=)V])vY Any character between ] and v (case-insensitive)
'One or more of the previous expression (for example, X`' matches one or more
digits)
WZ+Y' One or more characters until (and not including) a forward slash
;Zero or one of the previous expression (for example, X`; matches zero or one
digits)
&Zero or more of the previous expression (for example, X`& matches zero, one or
more than one digit)
w-(/y Between one and three (inclusive) of the previous expression (for example,
X`w-(/y matches one, two, or three digits)
For more on regular expressions, see dppl6++sss*`f]jcklnkfa_p*_ki+n+lupdkj+na)ik`qha+.
A Quick Note About 404 Errors
At this point, the URLconf defines only a single URLpattern: the one that handles requests to
the URL +dahhk+. What happens when you request a different URL?
To find out, try running the Django development server and visiting a page such as
dppl6++-.3*,*,*-64,,,+ckk`^ua+, dppl6++-.3*,*,*-64,,,+dahhk+oq^`ena_pknu+, or even
dppl6++-.3*,*,*-64,,,+ (the site “root”). You should see a “Page not found” message (see
Figure 3-1). Django displays this message because you requested a URL that’s not defined in
your URLconf.
The utility of this page goes beyond the basic 404 error message. It also tells you precisely
which URLconf Django used and every pattern in that URLconf. From that information, you
should be able to tell why the requested URL threw a 404.
Naturally, this is sensitive information intended only for you, the Web developer. If this
were a production site deployed live on the Internet, you wouldn’t want to expose that infor-
mation to the public. For that reason, this “Page not found” page is displayed only if your
Django project is in debug mode. We’ll explain how to deactivate debug mode later. For now,
just know that every Django project is in debug mode when you first create it, and if the proj-
ect is not in debug mode, Django outputs a different 404 response.
CHAPTER 3 N VIEWS AND URLCONFS 27
Figure 3-1. Django’s 404 page
A Quick Note About the Site Root
As explained in the last section, you’ll see a 404 error message if you view the site root:
dppl6++-.3*,*,*-64,,,+°Ê>}Ê`iÃ½ÌÊ>}V>ÞÊ>``Ê>ÞÌ}ÊÌÊÌiÊÃÌiÊÀÌÆÊÌ>ÌÊ1,ÊÃÊ
not special-cased in any way. It’s up to you to assign it to a URLpattern, just like every other
entry in your URLconf.
The URLpattern to match the site root is a bit counterintuitive, though, so it’s worth men-
tioning. When you’re ready to implement a view for the site root, use the URLpattern #Z #,
which matches an empty string. Here’s an example:
bnkiiuoepa*reasoeilknpdahhk(iu[dkial]ca[reas
qnhl]ppanjo9l]ppanjo$##(
$#Z #(iu[dkial]ca[reas%(
***
%
CHAPTER 3 N VIEWS AND URLCONFS
28
How Django Processes a Request
Before continuing to the second view function, let’s pause to learn a little more about how
Django works. Specifically, when you view your “Hello world” message by visiting dppl6++-.3*
,*,*-64,,,+dahhk+ in your Web browser, what does Django do behind the scenes?
It all starts with the settings file. When you run lupdkji]j]ca*lunqjoanran, the script
looks for a file called oappejco*lu in the same directory as i]j]ca*lu. This file contains all sorts
of configuration for this particular Django project, all in uppercase: PAILH=PA[@ENO, @=P=>=OA[
J=IA, and so on. The most important setting is called NKKP[QNH?KJB. NKKP[QNH?KJB tells Django
which Python module should be used as the URLconf for this Web site.
Remember when `f]jck)]`iej*luop]nplnkfa_p created the files oappejco*lu and qnho*lu?
The autogenerated oappejco*lu contains a NKKP[QNH?KJB setting that points to the autogen-
erated qnho*lu. Open the oappejco*luÊviÊ>`ÊÃiiÊvÀÊÞÕÀÃivÆÊÌÊÃÕ`ÊÊiÊÌÃ\
NKKP[QNH?KJB9#iuoepa*qnho#
This corresponds to the file iuoepa+qnho*lu. When a request comes in for a particular
URL—say, a request for +dahhk+—Django loads the URLconf pointed to by the NKKP[QNH?KJB
setting. Then it checks each of the URLpatterns in that URLconf, in order, comparing the
requested URL with the patterns one at a time, until it finds one that matches. When it
finds one that matches, it calls the view function associated with that pattern, passing it an
DpplNamqaop object as the first parameter. (We’ll cover the specifics of DpplNamqaop later.)
As you saw in the first view example, a view function must return an DpplNaolkjoa. Once
it does this, Django does the rest, converting the Python object to a proper Web response with
the appropriate HTTP headers and body (the content of the Web page).
In summary, here are the steps:
1. A request comes in to +dahhk+.
2. Django determines the root URLconf by looking at the NKKP[QNH?KJB setting.
3. Django looks at all the URLpatterns in the URLconf for the first one that matches
+dahhk+.
4. If it finds a match, it calls the associated view function.
5. The view function returns an DpplNaolkjoa.
6. Django converts the DpplNaolkjoa to the proper HTTP response, which results in a
Web page.
You now know the basics of how to make Django-powered pages. It’s quite simple, really:
just write view functions and map them to URLs via URLconfs.
Your Second View: Dynamic Content
The “Hello world” view was instructive for demonstrating the basics of how Django works,
but it wasn’t an example of a dynamic Web page because the contents of the page are always
ÌiÊÃ>i°ÊÛiÀÞÊÌiÊÞÕÊÛiÜÊ+dahhk+]ÊÞÕ½ÊÃiiÊÌiÊÃ>iÊÌ}ÆÊÌÊ}ÌÊ>ÃÊÜiÊLiÊ>ÊÃÌ>ÌVÊ
HTML file.
CHAPTER 3 N VIEWS AND URLCONFS 29
For the second view, let’s create something more dynamic: a Web page that displays the
current date and time. This is a nice and simple next step because it doesn’t involve a database
ÀÊ>ÞÊÕÃiÀÊ«ÕÌÆÊÕÃÌÊÌiÊÕÌ«ÕÌÊvÊÌiÊÃiÀÛiÀ½ÃÊÌiÀ>ÊVV°Ê̽ÃÊÞÊ>À}>ÞÊÀiÊiÝVÌ-
ing than “Hello world,” but it will demonstrate a few new concepts.
This view needs to do two things: calculate the current date and time, and return an
DpplNaolkjoa containing that value. If you have experience with Python, you know that Python
includes a `]papeia module for calculating dates. Here’s how to use it:
:::eilknp`]papeia
:::jks9`]papeia*`]papeia*jks$%
:::jks
`]papeia*`]papeia$.,,4(-.(-/(-0(5(/5(.3/-%
:::lnejpjks
.,,4)-.)-/-06,56/5*,,.3/-
That’s simple enough, and it has nothing to do with Django. It’s just Python code. (We
want to emphasize that you should be aware of what code is “just Python” vs. code that is
Django-specific. As you learn Django, we want you to be able to apply your knowledge to other
Python projects that don’t necessarily use Django.)
To make a Django view that displays the current date and time, you just need to hook this
`]papeia*`]papeia*jks$% statement into a view and return an DpplNaolkjoa. Here’s how it looks:
bnki`f]jck*dppleilknpDpplNaolkjoa
eilknp`]papeia
`ab_qnnajp[`]papeia$namqaop%6
jks9`]papeia*`]papeia*jks$%
dpih98dpih:8^k`u:Epeojks!o*8+^k`u:8+dpih:!jks
napqnjDpplNaolkjoa$dpih%
As with the dahhk view function, this should live in reaso*lu. Note that we hid the dahhk
function from this example for brevity, but for the sake of completeness, here’s what the entire
reaso*lu looks like:
bnki`f]jck*dppleilknpDpplNaolkjoa
eilknp`]papeia
`abdahhk$namqaop%6
napqnjDpplNaolkjoa$Dahhksknh`%
`ab_qnnajp[`]papeia$namqaop%6
jks9`]papeia*`]papeia*jks$%
dpih98dpih:8^k`u:Epeojks!o*8+^k`u:8+dpih:!jks
napqnjDpplNaolkjoa$dpih%
NNote From now on, we won’t display previous code in code examples except when necessary. You
should be able to tell from context which parts of an example are new and which are old.
CHAPTER 3 N VIEWS AND URLCONFS
30
Let’s step through the changes made to reaso*lu to accommodate the _qnnajp[`]papeia
view:
Ê UÊ Êeilknp`]papeia was added to the top of the module, so you can calculate dates.
Ê UÊ /iÊiÜÊ_qnnajp[`]papeia function calculates the current date and time as a `]papeia*
`]papeia object and then stores it as the local variable jks.
Ê UÊ /iÊÃiV`ÊiÊvÊV`iÊÜÌÊÌiÊÛiÜÊVÃÌÀÕVÌÃÊ>Ê/ÊÀiëÃiÊÕÃ}Ê*ÞÌ½ÃÊ
“format-string” capability. The !o within the string is a placeholder, and the percent
sign after the string means “Replace the !o in the preceding string with the value of the
variable jks.” The jks variable is technically a `]papeia*`]papeia object, not a string,
but the !o format character converts it to its string representation, which is some-
thing like this: .,,4)-.)-/-06,56/5*,,.3/-. It will result in an HTML string such as
8dpih:8^k`u:Epeojks.,,4)-.)-/-06,56/5*,,.3/-*8+^k`u:8+dpih:.
Ê UÊ 9iÃ]ÊÌiÊ/ÊÃÊÛ>`]ÊLÕÌÊÜi½ÀiÊÌÀÞ}ÊÌÊii«ÊÌiÊiÝ>«iÊÃ«iÊ>`ÊÃÀÌ°
Ê UÊ >Þ]ÊÌiÊÛiÜÊÀiÌÕÀÃÊ>ÊDpplNaolkjoa object that contains the generated
response—just as we did in dahhk.
After adding that to reaso*lu, add the URLpattern to qnho*lu to tell Django which URL
should handle this view. Something like +peia+ would make sense:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnkiiuoepa*reasoeilknpdahhk(_qnnajp[`]papeia
qnhl]ppanjo9l]ppanjo$##(
$#Zdahhk+ #(dahhk%(
$#Zpeia+ #(_qnnajp[`]papeia%(
%
Two changes were made. First, we imported the _qnnajp[`]papeia function at the top.
Second, and more importantly, we added a URLpattern mapping the URL +peia+ to that new
view. Getting the hang of this?
With the view written and URLconf updated, fire up the nqjoanran and visit
dppl6++-.3*,*,*-64,,,+peia+ in your browser. You should see the current date and time.
DJANGO'S TIME ZONE
Depending on your computer, the date and time might be a few hours off. That’s because Django is time
zone–aware and defaults to the =iane_]+?de_]ck time zone. (It has to default to something, and that’s the
time zone where the original developers live.) If you live elsewhere, you’ll want to change it in oappejco*lu.
See the comment in that file for a link to an up-to-date list of worldwide time zone options.
CHAPTER 3 N VIEWS AND URLCONFS 31
URLconfs and Loose Coupling
Now is a good time to highlight a key philosophy behind URLconfs and behind Django in
general: the principle of loose coupling. Simply put, loose coupling is a software-development
approach that values the importance of making pieces interchangeable. If two pieces of code
are loosely coupled, changes made to one of the pieces will have little or no effect on the other.
Django’s URLconfs are a good example of this principle in practice. In a Django Web appli-
V>Ì]ÊÌiÊ1,Ê`ivÌÃÊ>`ÊÌiÊÛiÜÊvÕVÌÃÊÌiÞÊV>Ê>ÀiÊÃiÞÊVÕ«i`ÆÊÌ>ÌÊÃ]ÊÌiÊ
decision of what the URL should be for a given function and the implementation of the function
itself resides in two separate places. This lets you switch out one piece without affecting the other.
For example, consider the _qnnajp[`]papeia view. If you wanted to change the URL for
the application—say, to move it from +peia+ to +_qnnajp)peia+—you could make a quick
change to the URLconf without having to worry about the view itself. Similarly, if you wanted
to change the view function—altering its logic somehow—you could do that without affecting
the URL to which the function is bound.
Furthermore, if you wanted to expose the current-date functionality at several URLs, you
could easily take care of that by editing the URLconf, without having to touch the view code. In
this example, the _qnnajp[`]papeia is available at two URLs. It’s a contrived example, but this
technique can come in handy:
qnhl]ppanjo9l]ppanjo$##(
$#Zdahhk+ #(dahhk%(
$#Zpeia+ #(_qnnajp[`]papeia%(
$#Z]jkpdan)peia)l]ca+ #(_qnnajp[`]papeia%(
%
URLconfs and views are loose coupling in action. We’ll continue to point out examples of
this important philosophy throughout this book.
Your Third View: Dynamic URLs
In the _qnnajp[`]papeia view, the contents of the page—the current date/time—were
dynamic, but the URL (+peia+) was static. In most dynamic Web applications, though, a URL
contains parameters that influence the output of the page. For example, an online bookstore
might give each book its own URL (for example, +^kkgo+.0/+ and +^kkgo+4--52+).
Let’s create a third view that displays the current date and time offset by a certain number
of hours. The goal is to craft a site so that the page +peia+lhqo+-+ displays the date/time one
hour into the future, the page +peia+lhqo+.+ displays the date/time two hours into the future,
the page +peia+lhqo+/+ displays the date/time three hours into the future, and so on.
A novice might think to code a separate view function for each hour offset, which might
result in a URLconf like this:
qnhl]ppanjo9l]ppanjo$##(
$#Zpeia+ #(_qnnajp[`]papeia%(
$#Zpeia+lhqo+-+ #(kja[dkqn[]da]`%(
$#Zpeia+lhqo+.+ #(psk[dkqno[]da]`%(
$#Zpeia+lhqo+/+ #(pdnaa[dkqno[]da]`%(
$#Zpeia+lhqo+0+ #(bkqn[dkqno[]da]`%(
%
CHAPTER 3 N VIEWS AND URLCONFS
32
Clearly, this line of thought is flawed. Not only would this result in redundant view func-
tions but also the application is fundamentally limited to supporting only the predefined hour
ranges: one, two, three, or four hours. If you decided to create a page that displayed the time
five hours into the future, you’d have to create a separate view and URLconf line for that, fur-
thering the duplication. You need to do some abstraction here.
A WORD ABOUT PRETTY URLS
If you’re experienced in another Web development platform, such as PHP or Java, you might want to use a
query string parameter—something like +peia+lhqo;dkqno9/, in which the hours would be designated by
the dkqno parameter in the URL’s query string (the part after the ;).
You can do that with Django (and we’ll tell you how in Chapter 8 but one of Django’s core philosophies
is that URLs should be beautiful. The URL +peia+lhqo+/+ is far cleaner, simpler, more readable, easier to
recite to somebody aloud, and just plain prettier than its query string counterpart. Pretty URLs are a charac-
teristic of a quality Web application.
Django’s URLconf system encourages pretty URLs by making it easier to use pretty URLs than not to.
How then do you design the application to handle arbitrary hour offsets? The key is to use
wildcard URLpatterns°ÊÃÊiÌi`Ê«ÀiÛÕÃÞ]Ê>Ê1,«>ÌÌiÀÊÃÊ>ÊÀi}Õ>ÀÊiÝ«ÀiÃÃÆÊiVi]Ê
you can use the regular expression pattern X`' to match one or more digits:
qnhl]ppanjo9l]ppanjo$##(
***
$n#Zpeia+lhqo+X`'+ #(dkqno[]da]`%(
***
%
(We’re using the *** to imply there might be other URLpatterns that we trimmed from
this example.)
This new URLpattern will match any URL such as +peia+lhqo+.+, +peia+lhqo+.1+, or even
+peia+lhqo+-,,,,,,,,,,,+. Come to think of it, let’s limit it so that the maximum allowed off-
set is 99 hours. That means we want to allow either one- or two-digit numbers—and in regular
expression syntax, that translates into X`w-(.y:
$n#Zpeia+lhqo+X`w-(.y+ #(dkqno[]da]`%(
NNote When building Web applications, it’s always important to consider the most outlandish data input
possible and decide whether the application should support that input. We’ve curtailed the outlandishness
here by limiting the offset to 99 hours.
CHAPTER 3 N VIEWS AND URLCONFS 33
One important detail introduced here is that n character in front of the regular expres-
sion string. This character tells Python that the string is a “raw string”—its contents should
not interpret backslashes. In normal Python strings, backslashes are used for escaping special
characters—such as in the string #Xj#, which is a one-character string containing a newline.
When you add the n to make it a raw string, Python does not apply its backslash escaping, so
n#Xj# is a two-character string containing a literal backslash and a lowercase n. There’s a natu-
ral collision between Python’s use of backslashes and the backslashes that are found in regular
expressions, so it’s strongly suggested that you use raw strings any time you’re defining a regu-
lar expression in Python. From now on, all the URLpatterns in this book will be raw strings.
Now that a wildcard is designated for the URL, you need a way of passing that wildcard
data to the view function, so that you can use a single view function for any arbitrary hour off-
set. You can do this by placing parentheses around the data in the URLpattern that you want
to save. In the case of the example, you want to save whatever number was entered in the URL,
so put parentheses around X`w-(.y, like this:
$n#Zpeia+lhqo+$X`w-(.y%+ #(dkqno[]da]`%(
vÊÞÕ½ÀiÊv>>ÀÊÜÌÊÀi}Õ>ÀÊiÝ«ÀiÃÃÃ]ÊÞÕ½ÊLiÊÀ}ÌÊ>ÌÊiÊiÀiÆÊÞÕ½ÀiÊÕÃ}Ê
parentheses to capture data from the matched text.
The final URLconf, including the previous two views, looks like this:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnkiiuoepa*reasoeilknpdahhk(_qnnajp[`]papeia(dkqno[]da]`
qnhl]ppanjo9l]ppanjo$##(
$n#Zdahhk+ #(dahhk%(
$n#Zpeia+ #(_qnnajp[`]papeia%(
$n#Zpeia+lhqo+$X`w-(.y%+ #(dkqno[]da]`%(
%
With that taken care of, let’s write the dkqno[]da]` view.
CODING ORDER
In this example, the URLpattern was written first and the view was written second, but in the previous exam-
ples, the view was written first and then the URLpattern was written. Which technique is better? Well, every
developer is different.
If you’re a big-picture type of person, it might make the most sense to you to write all the URLpatterns
for your application at the same time, at the start of your project, and then code up the views. This has the
advantage of giving you a clear to-do list, and it essentially defines the parameter requirements for the view
functions you’ll need to write.
If you’re more of a bottom-up developer, you might prefer to write the views first and then anchor them
to URLs afterward. That’s OK, too.
In the end, it comes down to which technique fits your brain the best. Both approaches are valid.
CHAPTER 3 N VIEWS AND URLCONFS
34
dkqno[]da]` is very similar to the _qnnajp[`]papeia view written earlier with one key dif-
ference: it takes an extra argument the number of hours of offset. Here’s the view code:
bnki`f]jck*dppleilknpDppl0,0(DpplNaolkjoa
eilknp`]papeia
`abdkqno[]da]`$namqaop(kbboap%6
pnu6
kbboap9ejp$kbboap%
at_alpR]hqaAnnkn6
n]eoaDppl0,0$%
`p9`]papeia*`]papeia*jks$%'`]papeia*peia`ahp]$dkqno9kbboap%
dpih98dpih:8^k`u:Ej!odkqn$o%(epsehh^a!o*8+^k`u:8+dpih:!$kbboap(`p%
napqnjDpplNaolkjoa$dpih%
Let’s step through this code one line at a time:
Ê UÊ /iÊÛiÜÊvÕVÌ]Êdkqno[]da]`, takes two parameters: namqaop and kbboap.
ÊUÊnamqaop is an DpplNamqaop object, just as in dahhk and _qnnajp[`]papeia. We’ll say it
again: each view always takes an DpplNamqaop object as its first parameter.
ÊUÊkbboap is the string captured by the parentheses in the URLpattern. For example, if
the requested URL were +peia+lhqo+/+, kbboap would be the string #/#. If the requested
URL were +peia+lhqo+.-+, kbboap would be the string #.-#. Note that captured values
will always be strings, not integers, even if the string is composed of only digits such
as #.-#.
NNote Technically, captured values will always be Unicode objects, not plain Python byte strings, but don’t
worry about this distinction at the moment.
Ê UÊ 7iÊ`iV`i`ÊÌÊV>ÊÌiÊÛ>À>LiÊkbboap, but you can call it whatever you want as long as
̽ÃÊ>ÊÛ>`Ê*ÞÌÊ`iÌviÀ°Ê/iÊÛ>À>LiÊ>iÊ`iÃ½ÌÊ>ÌÌiÀÆÊ>ÊÌ>ÌÊ>ÌÌiÀÃÊÃÊÌ>ÌÊ
it’s the second argument to the function, after namqaop. (It’s also possible to use key-
word, instead of positional, arguments in a URLconf. We cover that in Chapter 8.)
Ê UÊ /iÊvÀÃÌÊÌ}ÊÞÕÊ`ÊÜÌÊÌiÊvÕVÌÊÃÊV>Êejp$% on kbboap. This converts the
string value to an integer.
Ê ÌiÊÌ>ÌÊ*ÞÌÊÜÊÀ>ÃiÊ>ÊR]hqaAnnkn exception if you call ejp$% on a value that
cannot be converted to an integer, such as the string #bkk#. In this example, if you
encounter the R]hqaAnnkn, you raise the exception `f]jck*dppl*Dppl0,0, which, as you
can imagine, results in a 404 “Page not found” error.
CHAPTER 3 N VIEWS AND URLCONFS 35
Ê UÊ ÃÌÕÌiÊÀi>`iÀÃÊÜÊÜ`iÀÊÜÊÜiÊVÕ`ÊiÛiÀÊÀi>VÊÌiÊR]hqaAnnkn case, given that
the regular expression in the URLpattern—$X`w-(.y%—captures only digits, and there-
fore kbboap will only ever be a string composed of digits. The answer is that we won’t
because the URLpattern provides a modest but useful level of input validation, but we
still check for the R]hqaAnnkn in case this view function ever gets called in some other
way. It’s good practice to implement view functions such that they don’t make any
assumptions about their parameters. Loose coupling, remember?
Ê UÊ ÊÌiÊiÝÌÊiÊvÊÌiÊvÕVÌ]ÊÜiÊV>VÕ>ÌiÊÌiÊVÕÀÀiÌÊ`>ÌiÉÌiÊ>`Ê>``ÊÌiÊ
appropriate number of hours. You’ve already seen `]papeia*`]papeia*jks$% from
the _qnnajp[`]papeia viewÆÊÌiÊiÜÊVVi«ÌÊiÀiÊÃÊÌ>ÌÊÞÕÊV>Ê«iÀvÀÊ`>ÌiÉÌiÊ
arithmetic by creating a `]papeia*peia`ahp] object and adding to a `]papeia*`]papeia
object. The result is stored in the variable `p.
Ê UÊ /ÃÊiÊ>ÃÊÃÜÃÊÜÞÊÜiÊV>i`Êejp$% on kbboap—the `]papeia*peia`ahp] function
requires the dkqno parameter to be an integer.
Ê iÝÌ]ÊÌiÊ/ÊÕÌ«ÕÌÊvÊÌÃÊÛiÜÊvÕVÌÊÃÊVÃÌÀÕVÌi`]ÊÕÃÌÊ>ÃÊÜÌÊ_qnnajp[
`]papeia. A small difference in this line from the previous line is that it uses Python’s
format-string capability with two values, not just one. Hence, there are two !o symbols
in the string and a tuple of values to insert: $kbboap(`p%.
Ê UÊ >Þ]Ê>ÊDpplNaolkjoa of the HTML is returned. By now, this is old hat.
With that view function and URLconf written, start the Django development server (if
it’s not already running), and visit dppl6++-.3*,*,*-64,,,+peia+lhqo+/+ to verify it works.
Then try dppl6++-.3*,*,*-64,,,+peia+lhqo+1+. Then dppl6++-.3*,*,*-64,,,+peia+lhqo+.0+.
Finally, visit dppl6++-.3*,*,*-64,,,+peia+lhqo+-,,+ to verify that the pattern in the URLconf
>VVi«ÌÃÊÞÊiÊÀÊÌÜ`}ÌÊÕLiÀÃÆÊ>}ÊÃÕ`Ê`ë>ÞÊ>ʺ*>}iÊÌÊvÕ`»ÊiÀÀÀÊÊ
ÌÃÊV>Ãi]ÊÕÃÌÊ>ÃÊÞÕÊÃ>ÜÊÊÌiÊÃiVÌʺÊ+ÕVÊ ÌiÊLÕÌÊ{ä{ÊÀÀÀûÊi>ÀiÀ°Ê/iÊ1,Ê
dppl6++-.3*,*,*-64,,,+peia+lhqo+ (with no hour designation) should also throw a 404.
Django’s Pretty Error Pages
Take a moment to admire the fine Web application you’ve made so far and now you’ll break it!
Let’s deliberately introduce a Python error into the reaso*lu file by commenting out the
kbboap9ejp$kbboap% lines in the dkqno[]da]` view:
`abdkqno[]da]`$namqaop(kbboap%6
pnu6
kbboap9ejp$kbboap%
at_alpR]hqaAnnkn6
n]eoaDppl0,0$%
`p9`]papeia*`]papeia*jks$%'`]papeia*peia`ahp]$dkqno9kbboap%
dpih98dpih:8^k`u:Ej!odkqn$o%(epsehh^a!o*8+^k`u:8+dpih:!$kbboap(`p%
napqnjDpplNaolkjoa$dpih%
Load up the development server and navigate to +peia+lhqo+/+. You’ll see an error page
with a significant amount of information, including a PulaAnnkn message displayed at the very
top: qjoqllknpa`pulabknpeia`ahp]dkqno_kilkjajp6qje_k`a.
CHAPTER 3 N VIEWS AND URLCONFS
36
What happened? Well, the `]papeia*peia`ahp] function expects the dkqno parameter to be
an integer, and the bit of code that converted kbboap to an integer was commented out. That
caused `]papeia*peia`ahp] to raise the PulaAnnkn. It’s the typical kind of small bug that every
programmer runs into at some point.
The point of this example was to demonstrate Django error pages. Take some time to
explore the error page and get to know the various bits of information it gives you.
Here are some things to notice:
Ê UÊ ÌÊÌiÊÌ«ÊvÊÌiÊ«>}i]ÊÞÕÊ}iÌÊÌiÊiÞÊvÀ>ÌÊ>LÕÌÊÌiÊiÝVi«Ì\ÊÌiÊÌÞ«iÊvÊ
exception, any parameters to the exception (the qjoqllknpa`pula message in this
case), the file in which the exception was raised, and the offending line number.
Ê UÊ 1`iÀÊÌiÊiÞÊiÝVi«ÌÊvÀ>Ì]ÊÌiÊ«>}iÊ`ë>ÞÃÊÌiÊvÕÊ*ÞÌÊÌÀ>ViL>VÊvÀÊ
this exception. This is similar to the standard traceback you get in Python’s command-
line interpreter, except it’s more interactive. For each level (“frame”) in the stack,
Django displays the name of the file, the function/method name, the line number,
and the source code of that line.
Ê UÊ VÊÌiÊiÊvÊÃÕÀViÊV`iÊÊ`>ÀÊ}À>Þ®]Ê>`ÊÞÕ½ÊÃiiÊÃiÛiÀ>ÊiÃÊvÀÊLivÀiÊ>`Ê
after the erroneous line, to give you context.
Ê UÊ VʺV>ÊÛ>ÀûÊÕ`iÀÊ>ÞÊvÀ>iÊÊÌiÊÃÌ>VÊÌÊÛiÜÊ>ÊÌ>LiÊvÊ>ÊV>ÊÛ>À>LiÃÊ>`Ê
their values, in that frame, at the exact point in the code at which the exception was
raised. This debugging information can be a great help.
Ê ÌiÊÌiʺ-ÜÌVÊÌÊV«Þ>`«>ÃÌiÊÛiÜ»ÊÌiÝÌÊÕ`iÀÊÌiʺ/À>ViL>V»Êi>`iÀ°ÊVÊ
those words, and the traceback will switch to an alternate version that can be easily
copied and pasted. Use this when you want to share your exception traceback with
others to get technical support—such as the kind folks in the Django IRC chat room
or on the Django users’ mailing list.
Ê UÊ 1`iÀi>Ì]ÊÌiʺ->ÀiÊÌÃÊÌÀ>ViL>VÊÊ>Ê«ÕLVÊ7iLÊÃÌi»ÊLÕÌÌÊÜÊ`ÊÌÃÊÜÀÊ
for you in just one click. Click it to post the traceback to dppl6++sss*`l]opa*_ki+,
where you’ll get a distinct URL that you can share with other people.
Ê iÝÌ]ÊÌiʺ,iµÕiÃÌÊvÀ>Ì»ÊÃiVÌÊVÕ`iÃÊ>ÊÜi>ÌÊvÊvÀ>ÌÊ>LÕÌÊÌiÊ
V}Ê7iLÊÀiµÕiÃÌÊÌ>ÌÊë>Üi`ÊÌiÊiÀÀÀ\Ê/Ê>`Ê*"-/ÊvÀ>Ì]ÊViÊ
values, and metainformation, such as Common Gateway Interface (CGI) headers.
Appendix G has a complete reference of all the information that a request object
contains.
Ê UÊ iÜÊÌiʺ,iµÕiÃÌÊvÀ>Ì»ÊÃiVÌ]ÊÌiʺ-iÌÌ}ûÊÃiVÌÊÃÌÃÊ>ÊÌiÊÃiÌÌ}ÃÊ
for this particular Django installation. (We already mentioned NKKP[QNH?KJB and we’ll
show you various Django settings throughout the book. All the available settings are
covered in detail in Appendix D.)
CHAPTER 3 N VIEWS AND URLCONFS 37
The Django error page is capable of displaying more information in certain special cases,
such as the case of template syntax errors. We’ll get to those later, when we discuss the Django
template system. For now, uncomment the kbboap9ejp$kbboap% lines to get the view func-
tion working properly again.
Are you the type of programmer who likes to debug with the help of carefully placed lnejp
statements? You can use the Django error page to do so—just without the lnejp statements.
At any point in your view, temporarily insert an ]ooanpB]hoa to trigger the error page. Then
you can view the local variables and state of the program. Here’s an example using the dkqno[
]da]` view:
`abdkqno[]da]`$namqaop(kbboap%6
pnu6
kbboap9ejp$kbboap%
at_alpR]hqaAnnkn6
n]eoaDppl0,0$%
`p9`]papeia*`]papeia*jks$%'`]papeia*peia`ahp]$dkqno9kbboap%
]ooanpB]hoa
dpih98dpih:8^k`u:Ej!odkqn$o%(epsehh^a!o*8+^k`u:8+dpih:!$kbboap(`p%
napqnjDpplNaolkjoa$dpih%
Finally, it’s obvious that much of this information is sensitive—it exposes the innards of
your Python code and Django configuration—and it would be foolish to show this informa-
tion on the public Internet. A malicious person could use it to attempt to reverse-engineer
your Web application and do nasty things. For that reason, the Django error page is displayed
only when your Django project is in debug mode. We’ll explain how to deactivate debug mode
in Chapter 12. For now, just know that every Django project is in debug mode automatically
when you start it. (Sound familiar? The “Page not found” errors, described earlier in this chap-
ter, work the same way.)
What's Next?
So far, we’ve been writing the view functions with HTML hard-coded directly in the Python
code. We’ve done that to keep things simple while we demonstrated core concepts, but in the
real world, this is nearly always a bad idea.
Django ships with a simple yet powerful template engine that allows you to separate the
design of the page from the underlying code. You’ll dive into Django’s template engine in the
next chapter.
CHAPTER 4
Templates
In the previous chapter, you may have noticed something peculiar in how we returned the
text in our example views. Namely, the HTML was hard-coded directly in our Python code,
like this:
`ab_qnnajp[`]papeia$namqaop%6
jks9`]papeia*`]papeia*jks$%
dpih98dpih:8^k`u:Epeojks!o*8+^k`u:8+dpih:!jks
napqnjDpplNaolkjoa$dpih%
Although this technique was convenient for the purpose of explaining how views work, it’s
not a good idea to hard-code HTML directly in your views. Here’s why:
Ê UÊ ÞÊV>}iÊÌÊÌiÊ`iÃ}ÊvÊÌiÊ«>}iÊÀiµÕÀiÃÊ>ÊV>}iÊÌÊÌiÊ*ÞÌÊV`i. The design
of a site tends to change far more frequently than the underlying Python code, so it
would be convenient if the design could change without needing to modify the Python
code.
Ê UÊ 7ÀÌ}Ê*ÞÌÊV`iÊ>`Ê`iÃ}}Ê/Ê>ÀiÊÌÜÊ`vviÀiÌÊ`ÃV«iÃ]Ê>`ÊÃÌÊ«À-
viÃÃ>Ê7iL`iÛi«iÌÊiÛÀiÌÃÊëÌÊÌiÃiÊÀiëÃLÌiÃÊLiÌÜiiÊÃi«>À>ÌiÊ
people (or even separate departments). Designers and HTML/CSS coders shouldn’t be
required to edit Python code to get their job done.
Ê UÊ ̽ÃÊÃÌÊivvViÌÊvÊ«À}À>iÀÃÊV>ÊÜÀÊÊ*ÞÌÊV`iÊ>`Ê`iÃ}iÀÃÊV>ÊÜÀÊÊ
templates at the same time, rather than one person waiting for the other to finish edit-
ing a single file that contains both Python and HTML.
For these reasons, it’s much cleaner and more maintainable to separate the design of the
«>}iÊvÀÊÌiÊ*ÞÌÊV`iÊÌÃiv°Ê7iÊV>Ê`ÊÌÃÊÜÌÊ>}½ÃÊtemplate system, which we dis-
cuss in this chapter.
39
CHAPTER 4 N TEMPLATES
40
Template-System Basics
A Django template is a string of text that is intended to separate the presentation of a docu-
ment from its data. A template defines placeholders and various bits of basic logic (template
tags) that regulate how the document should be displayed. Usually templates are used for pro-
ducing HTML, but Django templates are equally capable of generating any text-based format.
Let’s start with a simple example template. This Django template describes an HTML page
that thanks a person for placing an order with a company. Think of it as a form letter:
8dpih:
8da]`:8pepha:Kn`anejcjkpe_a8+pepha:8+da]`:
8^k`u:
8d-:Kn`anejcjkpe_a8+d-:
8l:@a]nwwlanokj[j]iayy(8+l:
8l:Pd]jgobknlh]_ejc]jkn`anbnkiww_kil]juyy*Ep#oo_da`qha`pk
odelkjwwodel[`]pax`]pa6Bf(Uyy*8+l:
8l:Dana]napdaepaioukq#rakn`ana`68+l:
8qh:
w!bknepaiejepai[heop!y
8he:wwepaiyy8+he:
w!aj`bkn!y
8+qh:
w!ebkn`ana`[s]nn]jpu!y
8l:Ukqns]nn]jpuejbkni]pekjsehh^aej_hq`a`ejpdal]_g]cejc*8+l:
w!ahoa!y
8l:Ukq`e`j#pkn`an]s]nn]jpu(okukq#nakjukqnksjsdaj
pdalnk`q_poejarep]^huopklskngejc*8+l:
w!aj`eb!y
8l:Oej_anahu(8^n+:ww_kil]juyy8+l:
8+^k`u:
8+dpih:
CHAPTER 4 N TEMPLATES 41
This template is basic HTML with some variables and template tags thrown in. Let’s step
through it:
Ê UÊ ÞÊÌiÝÌÊÃÕÀÀÕ`i`ÊLÞÊ>Ê«>ÀÊvÊLÀ>ViÃÊi°}°]Êwwlanokj[j]iayy) is a variable. This
means “insert the value of the variable with the given name.” How do we specify the
Û>ÕiÃÊvÊÌiÊÛ>À>LiöÊ7i½Ê}iÌÊÌÊÌ>ÌÊÊ>ÊiÌ°
Ê UÊ ÞÊÌiÝÌÊÌ>̽ÃÊÃÕÀÀÕ`i`ÊLÞÊVÕÀÞÊLÀ>ViÃÊ>`Ê«iÀViÌÊÃ}ÃÊi°}°]Êw!ebkn`ana`[
s]nn]jpu!y) is a template tag. The definition of a tag is quite broad: a tag just tells the
template system to “do something.”
This example template contains a bkn tag (w!bknepaiejepai[heop!y) and an eb tag
(w!ebkn`ana`[s]nn]jpu!y).
A bkn tag works very much like a bkn statement in Python, letting you loop over each
item in a sequence. An ebÊÌ>}]Ê>ÃÊÞÕÊ>ÞÊiÝ«iVÌ]Ê>VÌÃÊ>ÃÊ>Ê}V>ʺv»ÊÃÌ>ÌiiÌ°ÊÊ
this particular case, the tag checks whether the value of the kn`ana`[s]nn]jpu variable
evaluates to Pnqa°ÊvÊÌÊ`iÃ]ÊÌiÊÌi«>ÌiÊÃÞÃÌiÊÜÊ`ë>ÞÊiÛiÀÞÌ}ÊLiÌÜiiÊÌiÊw!
ebkn`ana`[s]nn]jpu!y and w!ahoa!y°ÊvÊÌ]ÊÌiÊÌi«>ÌiÊÃÞÃÌiÊÜÊ`ë>ÞÊiÛiÀÞ-
thing between w!ahoa!y and w!aj`eb!y. Note that the w!ahoa!y is optional.
Ê UÊ >Þ]ÊÌiÊÃiV`Ê«>À>}À>«ÊvÊÌÃÊÌi«>ÌiÊVÌ>ÃÊ>ÊiÝ>«iÊvÊ>Êfilter, which is
ÌiÊÃÌÊVÛiiÌÊÜ>ÞÊÌÊ>ÌiÀÊÌiÊvÀ>ÌÌ}ÊvÊ>ÊÛ>À>Li°ÊÊÌÃÊiÝ>«i]Êwwodel[
`]pax`]pa6Bf(Uyy, we’re passing the odel[`]pa variable to the `]pa filter, giving
the `]pa filter the argument Bf(U. The `]pa filter formats dates in a given format,
as specified by that argument. Filters are attached using a pipe character (x), as a refer-
ence to Unix pipes.
Each Django template has access to several built-in tags and filters, many of which are
discussed in the sections that follow. Appendix F contains the full list of tags and filters, and
̽ÃÊ>Ê}`Ê`i>ÊÌÊv>>ÀâiÊÞÕÀÃivÊÜÌÊÌ>ÌÊÃÌÊÃÊÞÕÊÜÊÜ>̽ÃÊ«ÃÃLi°Ê̽ÃÊ>ÃÊ«Ã-
sible to create your own filters and tags; we’ll cover that in Chapter 9.
Using the Template System
Let’s dive into Django’s template system so you can see how it works—but we’re not yet going
to integrate it with the views that we created in the previous chapter. Our goal here is to show
you how the system works independent of the rest of Django. (Usually you’ll use the template
system within a Django view, but we want to make it clear that the template system is just a
Python library that you can use anywhere, not just in Django views.)
Here is the most basic way you can use Django’s template system in Python code:
1. Create a Pailh]pa object by providing the raw template code as a string.
2. Call the naj`an$% method of the Pailh]pa object with a given set of variables (the con-
text). This returns a fully rendered template as a string, with all of the variables and
template tags evaluated according to the context.
CHAPTER 4 N TEMPLATES
42
ÊV`i]ÊÌÊÃÊiÊÌÃ\
:::bnki`f]jckeilknppailh]pa
:::p9pailh]pa*Pailh]pa$#Iuj]iaeowwj]iayy*#%
:::_9pailh]pa*?kjpatp$w#j]ia#6#=`ne]j#y%
:::lnejpp*naj`an$_%
Iuj]iaeo=`ne]j*
:::_9pailh]pa*?kjpatp$w#j]ia#6#Bna`#y%
:::lnejpp*naj`an$_%
Iuj]iaeoBna`*
The following sections describe these steps in much more detail.
Creating Template Objects
The easiest way to create a Pailh]pa object is to instantiate it directly. The Pailh]pa class lives
in the `f]jck*pailh]pa module, and the constructor takes one argument, the raw template
code. Let’s dip into the Python interactive interpreter to see how this works in code.
From the iuoepa project directory created by `f]jck)]`iej*luop]nplnkfa_p (as covered
in Chapter 2), type lupdkji]j]ca*luodahh to start the interactive interpreter.
A SPECIAL PYTHON PROMPT
If you’ve used Python before, you may be wondering why we’re running lupdkji]j]ca*luodahh instead
of just lupdkj. Both commands will start the interactive interpreter, but the i]j]ca*luodahh command
has one key difference from lupdkj: before starting the interpreter, it tells Django which settings file to use.
Many parts of Django—including the template system—rely on your settings, and you won’t be able to use
them unless the framework knows which settings to use.
If you’re curious, here’s how it works behind the scenes. Django looks for an environment variable
called @F=JCK[OAPPEJCO[IK@QHA, which should be set to the import path of your oappejco*lu. For
example, @F=JCK[OAPPEJCO[IK@QHA might be set to #iuoepa*oappejco#, assuming iuoepa is on your
Python path.
When you run lupdkji]j]ca*luodahh, the command takes care of setting @F=JCK[OAPPEJCO[
IK@QHA for you. We’re encouraging you to use lupdkji]j]ca*luodahh in these examples to minimize
the amount of tweaking and configuring you have to do.
As you become more familiar with Django, you’ll likely stop using i]j]ca*luodahh and will set
@F=JCK[OAPPEJCO[IK@QHA manually in your *^]od[lnkbeha or other shell-environment configuration file.
Let’s go through some template-system basics:
:::bnki`f]jck*pailh]paeilknpPailh]pa
:::p9Pailh]pa$#Iuj]iaeowwj]iayy*#%
:::lnejpp
vÊÞÕ½ÀiÊvÜ}Ê>}ÊÌiÀ>VÌÛiÞ]ÊÞÕ½ÊÃiiÊÃiÌ}ÊiÊÌÃ\
8`f]jck*pailh]pa*Pailh]pak^fa_p]p,t^3`1b.0_:
CHAPTER 4 N TEMPLATES 43
That ,t^3`1b.0_ will be different every time, but it isn’t relevant; it’s a Python thing (the
Python “identity” of the Pailh]pa object, if you must know).
7iÊÞÕÊVÀi>ÌiÊ>ÊPailh]pa object, the template system compiles the raw template code
into an internal, optimized form, ready for rendering. But if your template code includes any
syntax errors, the call to Pailh]pa$% will cause a Pailh]paOujp]tAnnkn exception:
:::bnki`f]jck*pailh]paeilknpPailh]pa
:::p9Pailh]pa$#w!jkp]p]c!y#%
Pn]_a^]_g$ikopna_ajp_]hhh]op%6
Beha8op`ej:(heja-(ej;
***
`f]jck*pailh]pa*Pailh]paOujp]tAnnkn6Ejr]he`^hk_gp]c6#jkp]p]c#
The term block tag here refers to w!jkp]p]c!y. Block tag and template tag are
synonymous.
The system raises a Pailh]paOujp]tAnnkn exception for any of the following cases:
Ê UÊ Û>`ÊÌ>}Ã
Ê UÊ Û>`Ê>À}ÕiÌÃÊÌÊÛ>`ÊÌ>}Ã
Ê UÊ Û>`ÊvÌiÀÃ
Ê UÊ Û>`Ê>À}ÕiÌÃÊÌÊÛ>`ÊvÌiÀÃ
Ê UÊ Û>`ÊÌi«>ÌiÊÃÞÌ>Ý
Ê UÊ 1VÃi`ÊÌ>}ÃÊvÀÊÌ>}ÃÊÌ>ÌÊÀiµÕÀiÊVÃ}ÊÌ>}s)
Rendering a Template
Once you have a Pailh]pa object, you can pass it data by giving it a context. A context is sim-
ply a set of template variable names and their associated values. A template uses a context to
populate its variables and evaluate its tags.
A context is represented in Django by the ?kjpatp class, which lives in the `f]jck*pailh]pa
`Õi°ÊÌÃÊVÃÌÀÕVÌÀÊÌ>iÃÊiÊ«Ì>Ê>À}ÕiÌ\Ê>Ê`VÌ>ÀÞÊ>««}ÊÛ>À>LiÊ>iÃÊÌÊ
variable values. Call the Pailh]pa object’s naj`an$% method with the context to “fill” the template:
:::bnki`f]jck*pailh]paeilknp?kjpatp(Pailh]pa
:::p9Pailh]pa$#Iuj]iaeowwj]iayy*#%
:::_9?kjpatp$w#j]ia#6#Opald]ja#y%
:::p*naj`an$_%
q#Iuj]iaeoOpald]ja*#
7iÊÃÕ`Ê«ÌÊÕÌÊiÀiÊÌ>ÌÊÌiÊÀiÌÕÀÊÛ>ÕiÊvÊp*naj`an$_% is a Unicode object—not
a normal Python string. You can tell this by the q in front of the string. Django uses Unicode
LiVÌÃÊÃÌi>`ÊvÊÀ>ÊÃÌÀ}ÃÊÌÀÕ}ÕÌÊÌiÊvÀ>iÜÀ°ÊvÊÞÕÊÕ`iÀÃÌ>`ÊÌiÊÀi«iÀVÕÃ-
sions of that, be thankful for the sophisticated things Django does behind the scenes to make
ÌÊÜÀ°ÊvÊÞÕÊ`½ÌÊÕ`iÀÃÌ>`ÊÌiÊÀi«iÀVÕÃÃÃÊvÊÌ>Ì]Ê`½ÌÊÜÀÀÞÊvÀÊÜÆÊÕÃÌÊÜÊÌ>ÌÊ
Django’s Unicode support makes it relatively painless for your applications to support a wide
variety of character sets beyond the basic “A–Z” of the English language.
CHAPTER 4 N TEMPLATES
44
DICTIONARIES AND CONTEXTS
A Python dictionary is a mapping between known keys and variable values. A ?kjpatp is similar to a diction-
ary, but a ?kjpatp provides additional functionality, as covered in Chapter 9.
Variable names must begin with a letter (A–Z or a–z) and may contain additional letters,
digits, underscores, and dots. (Dots are a special case we’ll discuss in the section “Context
Variable Lookup.”) Variable names are case-sensitive.
Here’s an example of template compilation and rendering, using a template similar to the
example at the beginning of this chapter:
:::bnki`f]jck*pailh]paeilknpPailh]pa(?kjpatp
:::n]s[pailh]pa98l:@a]nwwlanokj[j]iayy(8+l:
***
***8l:Pd]jgobknlh]_ejc]jkn`anbnkiww_kil]juyy*Ep#oo_da`qha`pk
***odelkjwwodel[`]pax`]pa6Bf(Uyy*8+l:
***
***w!ebkn`ana`[s]nn]jpu!y
***8l:Ukqns]nn]jpuejbkni]pekjsehh^aej_hq`a`ejpdal]_g]cejc*8+l:
***w!ahoa!y
***8l:Ukq`e`j#pkn`an]s]nn]jpu(okukq#nakjukqnksjsdaj
***pdalnk`q_poejarep]^huopklskngejc*8+l:
***w!aj`eb!y
***
***8l:Oej_anahu(8^n+:ww_kil]juyy8+l:
:::p9Pailh]pa$n]s[pailh]pa%
:::eilknp`]papeia
:::_9?kjpatp$w#lanokj[j]ia#6#FkdjOiepd#(
***#_kil]ju#6#Kqp`kknAmqeliajp#(
***#odel[`]pa#6`]papeia*`]pa$.,,5(0(.%(
***#kn`ana`[s]nn]jpu#6B]hoay%
:::p*naj`an$_%
q8l:@a]nFkdjOiepd(8+l:XjXj8l:Pd]jgobknlh]_ejc]jkn`anbnkiKqp`kkn
Amqeliajp*Ep#oo_da`qha`pkXjodelkj=lneh.(.,,5*8+l:XjXjXj8l:Ukq
`e`j#pkn`an]s]nn]jpu(okukq#nakjukqnksjsdajXjpdalnk`q_po
ejarep]^huopklskngejc*8+l:XjXjXj8l:Oej_anahu(8^n+:Kqp`kknAmqeliajp
8+l:
Let’s step through this code one statement at a time:
1. First we import the classes Pailh]pa and ?kjpatp, which both live in the module
`f]jck*pailh]pa.
2. 7iÊÃ>ÛiÊÌiÊÀ>ÜÊÌiÝÌÊvÊÕÀÊÌi«>ÌiÊÌÊÌiÊÛ>À>LiÊn]s[pailh]pa. Note that we use
triple quotation marks to designate the string, because it wraps over multiple lines; in
contrast, strings within single quotation marks cannot be wrapped over multiple lines.
CHAPTER 4 N TEMPLATES 45
3. Next we create a template object, p, by passing n]s[pailh]pa to the Pailh]pa class
constructor.
4. 7iÊ«ÀÌÊÌiÊ`]papeia module from Python’s standard library because we’ll need it in
the following statement.
5. 7iÊVÀi>ÌiÊ>Ê?kjpatp object, _. The ?kjpatp constructor takes a Python dictionary, which
maps variable names to values. Here, for example, we specify that the lanokj[j]ia is
#FkdjOiepd#, _kil]ju is #Kqp`kknAmqeliajp#, and so forth.
6. Finally, we call the naj`an$% method on our template object, passing it the context.
This returns the rendered template—that is, it replaces template variables with the
actual values of the variables, and it executes any template tags.
Note that the “You didn’t order a warranty” paragraph was displayed because the
kn`ana`[s]nn]jpu variable evaluated to B]hoa. Also note the date, =lneh.(.,,5, which
is displayed according to the format string #Bf(U#°Ê7i½ÊiÝ«>ÊvÀ>ÌÊÃÌÀ}ÃÊvÀÊ
the `]pa filter in Appendix E.)
vÊÞÕ½ÀiÊiÜÊÌÊ*ÞÌ]ÊÞÕÊ>ÞÊÜ`iÀÊÜÞÊÌÃÊÕÌ«ÕÌÊVÕ`iÃÊiÜiÊV>À>VÌiÀÃÊ
(#Xj#) rather than displaying the line breaks. That’s happening because of a subtlety
in the Python interactive interpreter: the call to p*naj`an$_% returns a string, and
by default the interactive interpreter displays the representation of the string rather
Ì>ÊÌiÊ«ÀÌi`ÊÛ>ÕiÊvÊÌiÊÃÌÀ}°ÊvÊÞÕÊÜ>ÌÊÌÊÃiiÊÌiÊÃÌÀ}ÊÜÌÊiÊLÀi>ÃÊ
displayed as true line breaks rather than #Xj# characters, use the lnejp statement:
lnejpp*naj`an$_%.
Those are the fundamentals of using the Django template system: just write a template
string, create a Pailh]pa object, create a ?kjpatp, and call the naj`an$% method.
Multiple Contexts, Same Template
Once you have a Pailh]pa object, you can render multiple contexts through it. Consider this
example:
:::bnki`f]jck*pailh]paeilknpPailh]pa(?kjpatp
:::p9Pailh]pa$#Dahhk(wwj]iayy#%
:::lnejpp*naj`an$?kjpatp$w#j]ia#6#Fkdj#y%%
Dahhk(Fkdj
:::lnejpp*naj`an$?kjpatp$w#j]ia#6#Fqhea#y%%
Dahhk(Fqhea
:::lnejpp*naj`an$?kjpatp$w#j]ia#6#L]p#y%%
Dahhk(L]p
7iiÛiÀÊÞÕ½ÀiÊÕÃ}ÊÌiÊÃ>iÊÌi«>ÌiÊÃÕÀViÊÌÊÀi`iÀÊÕÌ«iÊVÌiÝÌÃÊiÊÌÃ]Ê̽ÃÊ
more efficient to create the Pailh]pa object once, and then call naj`an$% on it multiple times:
>]`
bknj]iaej$#Fkdj#(#Fqhea#(#L]p#%6
p9Pailh]pa$#Dahhk(wwj]iayy#%
lnejpp*naj`an$?kjpatp$w#j]ia#6j]iay%%
CHAPTER 4 N TEMPLATES
46
Ckk`
p9Pailh]pa$#Dahhk(wwj]iayy#%
bknj]iaej$#Fkdj#(#Fqhea#(#L]p#%6
lnejpp*naj`an$?kjpatp$w#j]ia#6j]iay%%
Django’s template parsing is quite fast. Behind the scenes, most of the parsing hap-
pens via a call to a single regular expression. This is in stark contrast to XML-based template
engines, which incur the overhead of an XML parser and tend to be orders of magnitude
slower than Django’s template-rendering engine.
Context Variable Lookup
n the examples so far, we’ve passed simple values in the contexts—mostly strings, plus a
`]papeia*`]pa example. However, the template system elegantly 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, methods, or indices of an object.
This is best illustrated with a few examples. For instance, suppose you’re passing a Python
dictionary to a template. To access the values of that dictionary by dictionary key, use a dot:
:::bnki`f]jck*pailh]paeilknpPailh]pa(?kjpatp
:::lanokj9w#j]ia#6#O]hhu#(#]ca#6#0/#y
:::p9Pailh]pa$#wwlanokj*j]iayyeowwlanokj*]cayyua]nokh`*#%
:::_9?kjpatp$w#lanokj#6lanokjy%
:::p*naj`an$_%
q#O]hhueo0/ua]nokh`*#
Similarly, dots also allow access of object attributes. For example, a Python `]papeia*`]pa
object has ua]n, ikjpd, and `]u attributes, and you can use a dot to access those attributes in a
Django template:
:::bnki`f]jck*pailh]paeilknpPailh]pa(?kjpatp
:::eilknp`]papeia
:::`9`]papeia*`]pa$-55/(1(.%
:::`*ua]n
-55/
:::`*ikjpd
1
:::`*`]u
.
:::p9Pailh]pa$#Pdaikjpdeoww`]pa*ikjpdyy]j`pdaua]neoww`]pa*ua]nyy*#%
:::_9?kjpatp$w#`]pa#6`y%
:::p*naj`an$_%
q#Pdaikjpdeo1]j`pdaua]neo-55/*#
CHAPTER 4 N TEMPLATES 47
This example uses a custom class, demonstrating that variable dots also allow attribute
access on arbitrary objects:
:::bnki`f]jck*pailh]paeilknpPailh]pa(?kjpatp
:::_h]ooLanokj$k^fa_p%6
***`ab[[ejep[[$oahb(benop[j]ia(h]op[j]ia%6
***oahb*benop[j]ia(oahb*h]op[j]ia9benop[j]ia(h]op[j]ia
:::p9Pailh]pa$#Dahhk(wwlanokj*benop[j]iayywwlanokj*h]op[j]iayy*#%
:::_9?kjpatp$w#lanokj#6Lanokj$#Fkdj#(#Oiepd#%y%
:::p*naj`an$_%
q#Dahhk(FkdjOiepd*#
Dots can also refer to methods on objects. For example, each Python string has the meth-
ods qllan$% and eo`ecep$%, and you can call those in Django templates using the same dot
syntax:
:::bnki`f]jck*pailh]paeilknpPailh]pa(?kjpatp
:::p9Pailh]pa$#wwr]nyyÍwwr]n*qllanyyÍwwr]n*eo`ecepyy#%
:::p*naj`an$?kjpatp$w#r]n#6#dahhk#y%%
q#dahhkÍDAHHKÍB]hoa#
:::p*naj`an$?kjpatp$w#r]n#6#-./#y%%
q#-./Í-./ÍPnqa#
Note that you do not include parentheses in the method calls. Also, it’s not possible to
pass arguments to the methods; you can only call methods that have no required arguments.
7iÊiÝ«>ÊÌÃÊ«Ã«ÞÊ>ÌiÀÊÊÌÃÊV>«ÌiÀ°®
Finally, dots are also used to access list indices, as in this example:
:::bnki`f]jck*pailh]paeilknpPailh]pa(?kjpatp
:::p9Pailh]pa$#Epai.eowwepaio*.yy*#%
:::_9?kjpatp$w#epaio#6W#]llhao#(#^]j]j]o#(#_]nnkpo#Yy%
:::p*naj`an$_%
q#Epai.eo_]nnkpo*#
Negative list indices are not allowed. For example, the template variable wwepaio*)-yy
would cause a Pailh]paOujp]tAnnkn.
PYTHON LISTS
A reminder: Python lists have 0-based indices. The first item is at index 0, the second is at index 1, and so on.
CHAPTER 4 N TEMPLATES
48
Dot lookups can be summarized like this: when the template system encounters a dot in a
variable name, it tries the following lookups, in this order:
Ê UÊ VÌ>ÀÞÊÕ«Êi°}°]ÊbkkW^]nY)
Ê UÊ ÌÌÀLÕÌiÊÕ«Êi°}°]Êbkk*^]n)
Ê UÊ iÌ`ÊV>Êi°}°]Êbkk*^]n$%)
Ê UÊ ÃÌ`iÝÊÕ«Êi°}°]ÊbkkW.Y)
/iÊÃÞÃÌiÊÕÃiÃÊÌiÊvÀÃÌÊÕ«ÊÌÞ«iÊÌ>ÌÊÜÀðÊ̽ÃÊÃÀÌVÀVÕÌÊ}V°
Dot lookups can be nested multiple levels deep. For instance, the following example uses
wwlanokj*j]ia*qllanyy, which translates into a dictionary lookup (lanokjW#j]ia#Y) and then
a method call (qllan$%):
:::bnki`f]jck*pailh]paeilknpPailh]pa(?kjpatp
:::lanokj9w#j]ia#6#O]hhu#(#]ca#6#0/#y
:::p9Pailh]pa$#wwlanokj*j]ia*qllanyyeowwlanokj*]cayyua]nokh`*#%
:::_9?kjpatp$w#lanokj#6lanokjy%
:::p*naj`an$_%
q#O=HHUeo0/ua]nokh`*#
Method-Call Behavior
Method calls are slightly more complex than the other lookup types. Here are some things to
keep in mind.
v]Ê`ÕÀ}ÊÌiÊiÌ`ÊÕ«]Ê>ÊiÌ`ÊÀ>ÃiÃÊ>ÊiÝVi«Ì]ÊÌiÊiÝVi«ÌÊÜÊLiÊ«À«>-
gated unless the exception has an attribute oehajp[r]ne]^ha[b]ehqna whose value is Pnqa°ÊvÊ
the exception does have a oehajp[r]ne]^ha[b]ehqna attribute, the variable will render as an
empty string, as in this example:
:::p9Pailh]pa$Iuj]iaeowwlanokj*benop[j]iayy*%
:::_h]ooLanokj?h]oo/6
***`abbenop[j]ia$oahb%6
***n]eoa=ooanpekjAnnkn(bkk
:::l9Lanokj?h]oo/$%
:::p*naj`an$?kjpatp$wlanokj6ly%%
Pn]_a^]_g$ikopna_ajp_]hhh]op%6
***
=ooanpekjAnnkn6bkk
:::_h]ooOehajp=ooanpekjAnnkn$=ooanpekjAnnkn%6
***oehajp[r]ne]^ha[b]ehqna9Pnqa
:::_h]ooLanokj?h]oo06
***`abbenop[j]ia$oahb%6
***n]eoaOehajp=ooanpekjAnnkn
:::l9Lanokj?h]oo0$%
:::p*naj`an$?kjpatp$wlanokj6ly%%
q#Iuj]iaeo*#
CHAPTER 4 N TEMPLATES 49
Ê UÊ ÊiÌ`ÊV>ÊÜÊÜÀÊÞÊvÊÌiÊiÌ`Ê>ÃÊÊÀiµÕÀi`Ê>À}ÕiÌðÊ"ÌiÀÜÃi]ÊÌiÊ
system will move to the next lookup type (list-index lookup).
Ê UÊ "LÛÕÃÞ]ÊÃiÊiÌ`ÃÊ>ÛiÊÃ`iÊivviVÌÃÊ>`ÊÌÊÜÕ`ÊLiÊvÃÊ>ÌÊLiÃÌ]Ê>`Ê«ÃÃLÞÊ
even a security hole, to allow the template system to access them.
Say, for instance, you have a >]jg=__kqjp object that has a `ahapa$% method°ÊvÊ>ÊÌi-
plate includes something like ww]__kqjp*`ahapayy, where ]__kqjp is a >]jg=__kqjp
object, the object would be deleted when the template is rendered!
To prevent this, set the function attribute ]hpano[`]p] on the method:
`ab`ahapa$oahb%6
@ahapapda]__kqjp
`ahapa*]hpano[`]p]9Pnqa
Ê UÊ /iÊÌi«>ÌiÊÃÞÃÌiÊÜ½ÌÊiÝiVÕÌiÊ>ÞÊiÌ`Ê>Ài`ÊÊÌÃÊÜ>Þ°ÊÌÕ}Ê
the current example, if a template includes ww]__kqjp*`ahapayy and the `ahapa$%
method has ]hpano[`]p]9Pnqa, then the `ahapa$% method will not be executed when
ÌiÊÌi«>ÌiÊÃÊÀi`iÀi`°ÊÃÌi>`ÊÌÊÜÊv>ÊÃiÌly.
How Invalid Variables Are Handled
By default, if a variable doesn’t exist the template system renders it as an empty string, failing
silently. Consider this example:
:::bnki`f]jck*pailh]paeilknpPailh]pa(?kjpatp
:::p9Pailh]pa$#Ukqnj]iaeowwj]iayy*#%
:::p*naj`an$?kjpatp$%%
q#Ukqnj]iaeo*#
:::p*naj`an$?kjpatp$w#r]n#6#dahhk#y%%
q#Ukqnj]iaeo*#
:::p*naj`an$?kjpatp$w#J=IA#6#dahhk#y%%
q#Ukqnj]iaeo*#
:::p*naj`an$?kjpatp$w#J]ia#6#dahhk#y%%
q#Ukqnj]iaeo*#
The system fails silently rather than raising an exception because it’s intended to be resil-
iÌÊÌÊÕ>ÊiÀÀÀ°ÊÊÌÃÊV>Ãi]Ê>ÊvÊÌiÊÕ«ÃÊv>i`ÊLiV>ÕÃiÊÛ>À>LiÊ>iÃÊ>ÛiÊÌiÊ
ÜÀ}ÊV>ÃiÊÀÊ>i°ÊÊÌiÊÀi>ÊÜÀ`]Ê̽ÃÊÕ>VVi«Ì>LiÊvÀÊ>Ê7iLÊÃÌiÊÌÊLiViÊ>VViÃÃLiÊ
due to a small template syntax error.
Playing with Context Objects
Most of the time, you’ll instantiate ?kjpatp objects by passing in a fully populated dictionary to
?kjpatp$%. But you can add and delete items from a ?kjpatp object once it’s been instantiated,
too, using standard Python dictionary syntax:
CHAPTER 4 N TEMPLATES
50
:::bnki`f]jck*pailh]paeilknp?kjpatp
:::_9?kjpatp$wbkk6^]ny%
:::_W#bkk#Y
#^]n#
:::`ah_W#bkk#Y
:::_W#bkk#Y
Pn]_a^]_g$ikopna_ajp_]hhh]op%6
***
GauAnnkn6#bkk#
:::_W#jasr]ne]^ha#Y9#dahhk#
:::_W#jasr]ne]^ha#Y
#dahhk#
Basic Template Tags and Filters
As we’ve mentioned already, the template system ships with built-in tags and filters. The sec-
tions that follow provide a rundown of the most common tags and filters.
Tags
The following sections outline the common Django tags.
if/else
The w!eb!y tag evaluates a variable, and if that variable is Pnqa (i.e., it exists, is not empty,
and is not a B]hoa Boolean value), the system will display everything between w!eb!y and w!
aj`eb!y, as in this example:
w!ebpk`]u[eo[saagaj`!y
8l:Sah_kiapkpdasaagaj`8+l:
w!aj`eb!y
An w!ahoa!y tag is optional:
w!ebpk`]u[eo[saagaj`!y
8l:Sah_kiapkpdasaagaj`8+l:
w!ahoa!y
8l:Cap^]_gpkskng*8+l:
w!aj`eb!y
CHAPTER 4 N TEMPLATES 51
PYTHON "TRUTHINESS"
In Python and in the Django template system, these objects evaluate to B]hoa in a Boolean context:
s !NEMPTYLISTWY).
s !NEMPTYTUPLE$%).
s !NEMPTYDICTIONARYwy).
s !NEMPTYSTRING##).
s :ERO,).
s 4HESPECIALOBJECTJkja.
s 4HEOBJECTB]hoaOBVIOUSLY
s #USTOMOBJECTSTHATDEFINETHEIROWN"OOLEANCONTEXTBEHAVIOR4HISISADVANCED0YTHONUSAGE
Everything else evaluates to Pnqa.
The w!eb!y tag accepts ]j`, kn, or jkp for testing multiple variables, or to negate a given
variable. Consider this example:
w!eb]pdhapa[heop]j`_k]_d[heop!y
>kpd]pdhapao]j`_k]_dao]na]r]eh]^ha*
w!aj`eb!y
w!ebjkp]pdhapa[heop!y
Pdana]najk]pdhapao*
w!aj`eb!y
w!eb]pdhapa[heopkn_k]_d[heop!y
Pdana]naokia]pdhapaoknokia_k]_dao*
w!aj`eb!y
w!ebjkp]pdhapa[heopkn_k]_d[heop!y
Pdana]najk]pdhapaoknpdana]naokia_k]_dao*
w!aj`eb!y
w!eb]pdhapa[heop]j`jkp_k]_d[heop!y
Pdana]naokia]pdhapao]j`]^okhqpahujk_k]_dao*
w!aj`eb!y
w!eb!y tags don’t allow ]j` and kn clauses within the same tag, because the order of
logic would be ambiguous. For example, this is invalid:
w!eb]pdhapa[heop]j`_k]_d[heopkn_daanha]`an[heop!y
CHAPTER 4 N TEMPLATES
52
/iÊÕÃiÊvÊ«>ÀiÌiÃiÃÊvÀÊVÌÀ}ÊÀ`iÀÊvÊ«iÀ>ÌÃÊÃÊÌÊÃÕ««ÀÌi`°ÊvÊÞÕÊv`Ê
yourself needing parentheses, consider performing logic outside the template and passing the
result of that as a dedicated template variable. Or just use nested w!eb!y tags, like this:
w!eb]pdhapa[heop!y
w!eb_k]_d[heopkn_daanha]`an[heop!y
Sad]ra]pdhapao(]j`aepdan_k]_daokn_daanha]`ano
w!aj`eb!y
w!aj`eb!y
Multiple uses of the same logical operator are fine, but you can’t combine different opera-
tors. For example, this is valid:
w!eb]pdhapa[heopkn_k]_d[heopknl]najp[heopknpa]_dan[heop!y
There is no w!aheb!y tag. Use nested w!eb!y tags to accomplish the same thing:
w!eb]pdhapa[heop!y
8l:Dana]napda]pdhapao6ww]pdhapa[heopyy*8+l:
w!ahoa!y
8l:Jk]pdhapao]na]r]eh]^ha*8+l:
w!eb_k]_d[heop!y
8l:Dana]napda_k]_dao6ww_k]_d[heopyy*8+l:
w!aj`eb!y
w!aj`eb!y
Make sure to close each w!eb!y with an w!aj`eb!y. Otherwise, Django will throw a
Pailh]paOujp]tAnnkn.
for
The w!bkn!y tag allows you to loop over each item in a sequence. As in Python’s bkn state-
ment, the syntax is bknTejU, where U is the sequence to loop over and T is the name of the
variable to use for a particular cycle of the loop. Each time through the loop, the template
system will render everything between w!bkn!y and w!aj`bkn!y.
For example, you could use the following to display a list of athletes given a variable
]pdhapa[heop:
8qh:
w!bkn]pdhapaej]pdhapa[heop!y
8he:ww]pdhapa*j]iayy8+he:
w!aj`bkn!y
8+qh:
Add naranoa` to the tag to loop over the list in reverse:
w!bkn]pdhapaej]pdhapa[heopnaranoa`!y
***
w!aj`bkn!y
CHAPTER 4 N TEMPLATES 53
̽ÃÊ«ÃÃLiÊÌÊiÃÌÊw!bkn!y tags:
w!bkn]pdhapaej]pdhapa[heop!y
8d-:ww]pdhapa*j]iayy8+d-:
8qh:
w!bknolknpej]pdhapa*olknpo[lh]ua`!y
8he:wwolknpyy8+he:
w!aj`bkn!y
8+qh:
w!aj`bkn!y
A common pattern is to check the size of the list before looping over it, and outputting
some special text if the list is empty:
w!eb]pdhapa[heop!y
w!bkn]pdhapaej]pdhapa[heop!y
8l:ww]pdhapa*j]iayy8+l:
w!aj`bkn!y
w!ahoa!y
8l:Pdana]najk]pdhapao*Kjhu_kilqpanlnkcn]iiano*8+l:
w!aj`eb!y
Because this pattern is so common, the bkn tag supports an optional w!ailpu!y clause
that lets you define what to output if the list is empty. This example is equivalent to the previ-
ous one:
w!bkn]pdhapaej]pdhapa[heop!y
8l:ww]pdhapa*j]iayy8+l:
w!ailpu!y
8l:Pdana]najk]pdhapao*Kjhu_kilqpanlnkcn]iiano*8+l:
w!aj`bkn!y
/iÀiÊÃÊÊÃÕ««ÀÌÊvÀʺLÀi>}ÊÕÌ»ÊvÊ>Ê«ÊLivÀiÊÌiÊ«ÊÃÊvÃi`°ÊvÊÞÕÊÜ>ÌÊÌÊ
accomplish this, change the variable you’re looping over so that it includes only the values you
want to loop over. Similarly, there is no support for a “continue” statement that would instruct
the loop processor to return immediately to the front of the loop. (See the section “Philoso-
phies and Limitations” later in this chapter for the reasoning behind this design decision.)
7ÌÊi>VÊw!bkn!y loop, you get access to a template variable called bknhkkl. This
variable has a few attributes that give you information about the progress of the loop:
ÊUÊbknhkkl*_kqjpan is always set to an integer representing the number of times the loop
has been entered. This is one-indexed, so the first time through the loop, bknhkkl*
_kqjpan will be set to -. Here’s an example:
w!bknepaiejpk`k[heop!y
8l:wwbknhkkl*_kqjpanyy6wwepaiyy8+l:
w!aj`bkn!y
ÊUÊbknhkkl*_kqjpan, is like bknhkkl*_kqjpan]ÊiÝVi«ÌÊ̽ÃÊâiÀ`iÝi`°ÊÌÃÊÛ>ÕiÊÜÊLiÊÃiÌÊ
to , the first time through the loop.
CHAPTER 4 N TEMPLATES
54
ÊUÊbknhkkl*nar_kqjpan is always set to an integer representing the number of remaining
items in the loop. The first time through the loop, bknhkkl*nar_kqjpan will be set to
the total number of items in the sequence you’re traversing. The last time through the
loop, bknhkkl*nar_kqjpan will be set to -.
ÊUÊbknhkkl*nar_kqjpan, is like bknhkkl*nar_kqjpan, except it’s zero-indexed. The first time
through the loop, bknhkkl*nar_kqjpan, will be set to the number of elements in the
sequence, minus 1. The last time through the loop, it will be set to ,.
ÊUÊbknhkkl*benop is a Boolean value set to Pnqa if this is the first time through the loop.
This is convenient for special-casing:
w!bknk^fa_pejk^fa_po!y
w!ebbknhkkl*benop!y8he_h]oo9benop:w!ahoa!y8he:w!aj`eb!y
wwk^fa_pyy
8+he:
w!aj`bkn!y
ÊUÊbknhkkl*h]op is a Boolean value set to Pnqa if this is the last time through the loop. A
common use for this is to put pipe characters between a list of links:
w!bknhejgejhejgo!ywwhejgyyw!ebjkpbknhkkl*h]op!yxw!aj`eb!yw!
aj`bkn!y
The preceding template code might output something like this:
Hejg-xHejg.xHejg/xHejg0
Another common use for this is to put a comma between words in a list:
B]rknepalh]_ao6
w!bknlejlh]_ao!ywwlyyw!ebjkpbknhkkl*h]op!y(w!aj`eb!yw!aj`bkn!y
ÊUÊbknhkkl*l]najphkkl is a reference to the bknhkkl object for the parent loop, in case of
nested loops. Here’s an example:
w!bkn_kqjpnuej_kqjpneao!y
8p]^ha:
w!bkn_epuej_kqjpnu*_epu[heop!y
8pn:
8p`:?kqjpnuwwbknhkkl*l]najphkkl*_kqjpanyy8+p`:
8p`:?epuwwbknhkkl*_kqjpanyy8+p`:
8p`:ww_epuyy8+p`:
8+pn:
w!aj`bkn!y
8+p]^ha:
w!aj`bkn!y
The magic bknhkkl variable is available only within loops. After the template parser has
reached w!aj`bkn!y, bknhkkl disappears.
CHAPTER 4 N TEMPLATES 55
CONTEXT AND THE FORLOOP VARIABLE
Inside the w!bkn!y block, the existing variables are moved out of the way to avoid overwriting the magic
bknhkkl variable. Django exposes this moved context in bknhkkl*l]najphkkl. You generally don’t need
to worry about this, but if you supply a template variable named bknhkklTHOUGHWEADVISEAGAINSTIT
because it could confuse fellow template authors), it will be named bknhkkl*l]najphkkl while inside the
w!bkn!y block.
ifequal/ifnotequal
The Django template system deliberately is not a full-fledged programming language and thus
does not allow you to execute arbitrary Python statements. (More on this idea in the section
“Philosophies and Limitations.”) However, it’s quite a common template requirement to com-
pare two values and display something if they’re equal—and Django provides an w!ebamq]h
!y tag for that purpose.
The w!ebamq]h!y tag compares two values and displays everything between w!ebamq]h
!y and w!aj`ebamq]h!y if the values are equal.
This example compares the template variables qoan and _qnnajpqoan:
w!ebamq]hqoan_qnnajpqoan!y
8d-:Sah_kia8+d-:
w!aj`ebamq]h!y
The arguments can be hard-coded strings, with either single or double quotes, so the fol-
lowing is valid:
w!ebamq]hoa_pekj#oepajaso#!y
8d-:OepaJaso8+d-:
w!aj`ebamq]h!y
w!ebamq]hoa_pekj_kiiqjepu!y
8d-:?kiiqjepu8+d-:
w!aj`ebamq]h!y
Just like w!eb!y, the w!ebamq]h!y tag supports an optional w!ahoa!y:
w!ebamq]hoa_pekj#oepajaso#!y
8d-:OepaJaso8+d-:
w!ahoa!y
8d-:JkJasoDana8+d-:
w!aj`ebamq]h!y
Only template variables, strings, integers, and decimal numbers are allowed as arguments
to w!ebamq]h!y. These are valid examples:
w!ebamq]hr]ne]^ha-!y
w!ebamq]hr]ne]^ha-*./!y
w!ebamq]hr]ne]^ha#bkk#!y
w!ebamq]hr]ne]^habkk!y
CHAPTER 4 N TEMPLATES
56
Any other types of variables, such as Python dictionaries, lists, or Booleans, can’t be hard-
coded in w!ebamq]h!y. These are invalid examples:
w!ebamq]hr]ne]^haPnqa!y
w!ebamq]hr]ne]^haW-(.(/Y!y
w!ebamq]hr]ne]^haw#gau#6#r]hqa#y!y
vÊÞÕÊii`ÊÌÊÌiÃÌÊÜiÌiÀÊÃiÌ}ÊÃÊÌÀÕiÊÀÊv>Ãi]ÊÕÃiÊÌiÊw!eb!y tags instead of
w!ebamq]h!y.
Comments
Just as in HTML or Python, the Django template language allows for comments. To designate a
comment, use wy:
wPdeoeo]_kiiajpy
The comment will not be output when the template is rendered.
Comments using this syntax cannot span multiple lines. This limitation improves tem-
«>ÌiÊ«>ÀÃ}Ê«iÀvÀ>Vi°ÊÊÌiÊvÜ}ÊÌi«>Ìi]ÊÌiÊÀi`iÀi`ÊÕÌ«ÕÌÊÜÊÊiÝ>VÌÞÊÌiÊ
same as the template (i.e., the comment tag will not be parsed as a comment):
Pdeoeo]wpdeoeojkp
]_kiiajpy
paop*
vÊÞÕÊÜ>ÌÊÌÊÕÃiÊÕÌiÊViÌÃ]ÊÕÃiÊÌiÊw!_kiiajp!y template tag, like this:
w!_kiiajp!y
Pdeoeo]
iqhpeheja_kiiajp*
w!aj`_kiiajp!y
Filters
As explained earlier in this chapter, template filters are simple ways of altering the value of
variables before they’re displayed. Filters use a pipe character, like this:
wwj]iaxhksanyy
This displays the value of the wwj]iayy variable after being filtered through the hksan
filter, which converts text to lowercase.
Filters can be chained—that is, they can be used in tandem such that the output of one filter
is applied to the next. Here’s an example that converts the first element in a list to uppercase:
wwiu[heopxbenopxqllanyy
CHAPTER 4 N TEMPLATES 57
Some filters take arguments. A filter argument comes after a colon and is always in double
quotes. Here’s an example:
ww^ekxpnqj_]paskn`o6/,yy
This displays the first 30 words of the ^ek variable.
The following are a few of the most important filters. Appendix F covers the rest.
ÊUÊ]``oh]odao: Adds a backslash before any backslash, single quote, or double quote. This
is useful if the produced text is included in a JavaScript string.
ÊUÊ`]pa: Formats a `]pa or `]papeia object according to a format string given in the
parameter, as in this example:
wwlq^[`]pax`]pa6Bf(Uyy
Format strings are defined in Appendix F.
ÊUÊhajcpd: Returns the length of the value. For a list, this returns the number of elements.
For a string, this returns the number of characters. (Python experts, note that this
works on any Python object that knows how to determine its own length—that is, any
object that has a [[haj[[$% method.)
Philosophies and Limitations
Now that you’ve gotten a feel for the Django template language, we should point out some of
its intentional limitations, along with some philosophies behind why it works the way it works.
ÀiÊÌ>Ê>ÞÊÌiÀÊV«iÌÊvÊ7iLÊ>««V>ÌÃ]ÊÌi«>ÌiÊÃÞÌ>ÝÊÃÊ}ÞÊÃÕLiV-
tive, and programmers’ opinions vary wildly. The fact that Python alone has dozens, if not
hundreds, of open source template-language implementations supports this point. Each was
iÞÊVÀi>Ìi`ÊLiV>ÕÃiÊÌÃÊ`iÛi«iÀÊ`iii`Ê>ÊiÝÃÌ}ÊÌi«>ÌiÊ>}Õ>}iÃÊ>`iµÕ>Ìi°ÊÊ
fact, it is said to be a rite of passage for a Python developer to write his or her own template
>}Õ>}itÊvÊÞÕÊ>Ûi½ÌÊ`iÊÌÃÊÞiÌ]ÊVÃ`iÀÊÌ°Ê̽ÃÊ>ÊvÕÊiÝiÀVÃi°®
7ÌÊÌ>ÌÊÊ`]ÊÞÕÊ}ÌÊLiÊÌiÀiÃÌi`ÊÌÊÜÊÌ>ÌÊ>}Ê`iÃ½ÌÊÀiµÕÀiÊÞÕÊÌÊ
ÕÃiÊÌÃÊÌi«>ÌiÊ>}Õ>}i°ÊiV>ÕÃiÊ>}ÊÃÊÌi`i`ÊÌÊLiÊ>ÊvÕÃÌ>VÊ7iLÊvÀ>iÜÀÊÌ>ÌÊ
«ÀÛ`iÃÊ>ÊÌiÊ«iViÃÊiViÃÃ>ÀÞÊvÀÊ7iLÊ`iÛi«iÀÃÊÌÊLiÊ«À`ÕVÌÛi]Ê>ÞÊÌiÃÊ̽ÃÊÀiÊ
convenient to use Django’s template system than other Python template libraries, but it’s not
a strict requirement in any sense. As you’ll see in the upcoming section “Using Templates in
Views,” it’s very easy to use another template language with Django.
Still, it’s clear we have a strong preference for the way Django’s template language works.
/iÊÌi«>ÌiÊÃÞÃÌiÊ>ÃÊÀÌÃÊÊÜÊ7iLÊ`iÛi«iÌÊÃÊ`iÊ>ÌÊ7À`Ê"iÊ>`ÊÌiÊ
combined experience of Django’s creators. Here are a few of our philosophies:
CHAPTER 4 N TEMPLATES
58
ÊUÊBusiness logic should be separated from presentation logic. Django’s developers see a
template system as a tool that controls presentation and presentation-related logic—
and that’s it. The template system shouldn’t support functionality that goes beyond
this basic goal.
For that reason, it’s impossible to call Python code directly within Django templates.
All “programming” is fundamentally limited to the scope of what template tags can
`°ÊÌÊis possible to write custom template tags that do arbitrary things, but the out-
of-the-box Django template tags intentionally do not allow for arbitrary Python-code
execution.
ÊUÊSyntax should be decoupled from HTML/XML. Although Django’s template system
is used primarily to produce HTML, it’s intended to be just as usable for non-HTML
formats, such as plain text. Some other template languages are XML based, placing all
template logic within XML tags or attributes, but Django deliberately avoids this limita-
tion. Requiring valid XML for writing templates introduces a world of human mistakes
and hard-to-understand error messages, and using an XML engine to parse templates
incurs an unacceptable level of overhead in template processing.
ÊUÊDesigners are assumed to be comfortable with HTML code. The template system isn’t
`iÃ}i`ÊÃÊÌ>ÌÊÌi«>ÌiÃÊiViÃÃ>ÀÞÊ>ÀiÊ`ë>Þi`ÊViÞÊÊ79-79Êi`ÌÀÃÊÃÕVÊ
as Dreamweaver. That is too severe a limitation and wouldn’t allow the syntax to be
as friendly as it is. Django expects template authors to be comfortable editing HTML
directly.
ÊUÊDesigners are assumed not to be Python programmers. The template-system authors
ÀiV}âiÊÌ>ÌÊ7iL«>}iÊÌi«>ÌiÃÊ>ÀiÊÃÌÊvÌiÊÜÀÌÌiÊLÞÊdesigners, not program-
mers, and therefore should not assume Python knowledge.
However, the system also intends to accommodate small teams in which the templates
areÊVÀi>Ìi`ÊLÞÊ*ÞÌÊ«À}À>iÀðÊÌÊvviÀÃÊ>ÊÜ>ÞÊÌÊiÝÌi`ÊÌiÊÃÞÃÌi½ÃÊÃÞÌ>ÝÊLÞÊ
writing raw Python code. (More on this in Chapter 9.)
ÊUÊThe goal is not to invent a programming language. The goal is to offer just as much
programming-esque functionality, such as branching and looping, that is essential for
making presentation-related decisions.
Using Templates in Views
You’ve learned the basics of using the template system; now let’s use this knowledge to create
a view. Recall the _qnnajp[`]papeia view in iuoepa*reaso, which we started in the previous
chapter. Here’s what it looks like:
bnki`f]jck*dppleilknpDpplNaolkjoa
eilknp`]papeia
`ab_qnnajp[`]papeia$namqaop%6
jks9`]papeia*`]papeia*jks$%
dpih98dpih:8^k`u:Epeojks!o*8+^k`u:8+dpih:!jks
napqnjDpplNaolkjoa$dpih%
CHAPTER 4 N TEMPLATES 59
Let’s change this view to use Django’s template system. At first you might think to do
something like this:
bnki`f]jck*pailh]paeilknpPailh]pa(?kjpatp
bnki`f]jck*dppleilknpDpplNaolkjoa
eilknp`]papeia
`ab_qnnajp[`]papeia$namqaop%6
jks9`]papeia*`]papeia*jks$%
p9Pailh]pa$8dpih:8^k`u:Epeojksww_qnnajp[`]payy*8+^k`u:8+dpih:%
dpih9p*naj`an$?kjpatp$w#_qnnajp[`]pa#6jksy%%
napqnjDpplNaolkjoa$dpih%
Sure, that uses the template system, but it doesn’t solve the problems we pointed out in
the introduction of this chapter. Namely, the template is still embedded in the Python code, so
true separation of data and presentation isn’t achieved. Let’s fix that by putting the template in
a separate file, which this view will load.
You might first consider saving your template somewhere on your filesystem and using
Python’s built-in file-opening functionality to read the contents of the template. Here’s what
that might look like, assuming the template was saved as the file +dkia+`f]jckqoan+pailh]pao+
iupailh]pa*dpih:
bnki`f]jck*pailh]paeilknpPailh]pa(?kjpatp
bnki`f]jck*dppleilknpDpplNaolkjoa
eilknp`]papeia
`ab_qnnajp[`]papeia$namqaop%6
jks9`]papeia*`]papeia*jks$%
Oeilhas]ukbqoejcpailh]paobnkipdabehaouopai*
Pdeoeo>=@^a_]qoaep`kaoj#p]__kqjpbknieooejcbehao
bl9klaj$#+dkia+`f]jckqoan+pailh]pao+iupailh]pa*dpih#%
p9Pailh]pa$bl*na]`$%%
bl*_hkoa$%
dpih9p*naj`an$?kjpatp$w#_qnnajp[`]pa#6jksy%%
napqnjDpplNaolkjoa$dpih%
This approach, however, is inelegant for these reasons:
Ê UÊ ÌÊ`iÃ½ÌÊ>`iÊÌiÊV>ÃiÊvÊ>ÊÃÃ}Êvi]Ê>ÃÊÌi`ÊÊÌiÊV`i°ÊvÊÌiÊviÊiupailh]pa*
dpih doesn’t exist or isn’t readable, the klaj$% call will raise an EKAnnkn exception.
Ê UÊ ÌÊ>À`V`iÃÊÞÕÀÊÌi«>ÌiÊV>Ì°ÊvÊÞÕÊÜiÀiÊÌÊÕÃiÊÌÃÊÌiVµÕiÊvÀÊiÛiÀÞÊÛiÜÊ
function, you’d be duplicating the template locations—not to mention that it involves
a lot of typing!
Ê UÊ ÌÊVÕ`iÃÊ>ÊÌÊvÊLÀ}ÊLiÀ«>ÌiÊV`i°Ê9Õ½ÛiÊ}ÌÊLiÌÌiÀÊÌ}ÃÊÌÊ`ÊÌ>ÊÌÊÜÀÌiÊ
calls to klaj$%, bl*na]`$%, and bl*_hkoa$% each time you load a template.
To solve these issues, we’ll use template loading and template inheritance.
CHAPTER 4 N TEMPLATES
60
Template Loading
D>}Ê«ÀÛ`iÃÊ>ÊVÛiiÌÊ>`Ê«ÜiÀvÕÊ*ÊvÀÊ>`}ÊÌi«>ÌiÃÊvÀÊÌiÊviÃÞÃÌi]Ê
with the goal of removing redundancy both in your template-loading calls and in your tem-
plates themselves.
/ÊÕÃiÊÌÃÊÌi«>Ìi>`}Ê*]ÊvÀÃÌÊÞÕ½Êii`ÊÌÊÌiÊÌiÊvÀ>iÜÀÊÜiÀiÊÞÕÊÃÌÀiÊ
your templates. The place to do this is in your settings file—the oappejco*lu file that we men-
tioned in the last chapter, when we introduced the NKKP[QNH?KJB setting.
vÊÞÕ½ÀiÊvÜ}Ê>}]Ê«iÊoappejco*lu and find the PAILH=PA[@ENO setting. By default,
it’s an empty tuple, likely containing some autogenerated comments:
PAILH=PA[@ENO9$
Lqpopnejcodana(hega+dkia+dpih+`f]jck[pailh]pao
kn?6+sss+`f]jck+pailh]pao*
=hs]uoqoabkns]n`oh]odao(arajkjSej`kso*
@kj#pbkncappkqoa]^okhqpal]pdo(jkpnah]peral]pdo*
%
This setting tells Django’s template-loading mechanism where to look for templates.
Pick a directory where you’d like to store your templates and add it to PAILH=PA[@ENO, like so:
PAILH=PA[@ENO9$
#+dkia+`f]jck+iuoepa+pailh]pao#(
%
There are a few things to note:
Ê UÊ 9ÕÊV>ÊëiVvÞÊ>ÞÊ`ÀiVÌÀÞÊÞÕÊÜ>Ì]Ê>ÃÊ}Ê>ÃÊÌiÊ`ÀiVÌÀÞÊ>`ÊÌi«>ÌiÃÊÜÌÊ
Ì>ÌÊ`ÀiVÌÀÞÊ>ÀiÊÀi>`>LiÊLÞÊÌiÊÕÃiÀÊ>VVÕÌÊÕ`iÀÊÜVÊÞÕÀÊ7iLÊÃiÀÛiÀÊÀÕðÊvÊ
you can’t think of an appropriate place to put your templates, we recommend creating
a pailh]pao directory within your project (i.e., within the iuoepa directory you created
in Chapter 2).
Ê UÊ vÊÞÕÀÊPAILH=PA[@ENO contains only one directory, don’t forget the comma at the end of
the directory string!
Bad:
Ieooejc_kii]
PAILH=PA[@ENO9$
#+dkia+`f]jck+iuoepa+pailh]pao#
%
Ê Ê `\
?kii]_knna_phuejlh]_a*
PAILH=PA[@ENO9$
#+dkia+`f]jck+iuoepa+pailh]pao#(
%
Python requires commas within single-element tuples to disambiguate the tuple from
a parenthetical expression. This is a common newbie gotcha.
CHAPTER 4 N TEMPLATES 61
Ê UÊ vÊÞÕ½ÀiÊÊ7`ÜÃ]ÊVÕ`iÊÞÕÀÊ`ÀÛiÊiÌÌiÀÊ>`ÊÕÃiÊ1ÝÃÌÞiÊvÀÜ>À`ÊÃ>ÃiÃÊ
rather than backslashes, as follows:
PAILH=PA[@ENO9$
#?6+sss+`f]jck+pailh]pao#(
%
Ê UÊ ̽ÃÊÃ«iÃÌÊÌÊÕÃiÊ>LÃÕÌiÊ«>ÌÃÊ°i°]Ê`ÀiVÌÀÞÊ«>ÌÃÊÌ>ÌÊÃÌ>ÀÌÊ>ÌÊÌiÊÀÌÊvÊÌiÊ
viÃÞÃÌi®°ÊvÊÞÕÊÜ>ÌÊÌÊLiÊ>ÊLÌÊÀiÊviÝLiÊ>`Ê`iVÕ«i`]ÊÌÕ}]ÊÞÕÊV>ÊÌ>iÊ
advantage of the fact that Django settings files are just Python code by constructing the
contents of PAILH=PA[@ENO dynamically, as in this example:
eilknpko*l]pd
PAILH=PA[@ENO9$
ko*l]pd*fkej$ko*l]pd*`enj]ia$[[beha[[%(#pailh]pao#%*nalh]_a$#XX#(#+#%(
%
This example uses the “magic” Python variable [[beha[[, which is automatically set
ÌÊÌiÊviÊ>iÊvÊÌiÊ*ÞÌÊ`ÕiÊÊÜVÊÌiÊV`iÊÛiðÊÌÊ}iÌÃÊÌiÊ>iÊvÊÌiÊ
directory that contains oappejco*lu (ko*l]pd*`enj]ia), joins that with pailh]pao in a
cross-platform way (ko*l]pd*fkej), then ensures that everything uses forward slashes
ÃÌi>`ÊvÊL>VÃ>ÃiÃÊÊÌiÊV>ÃiÊvÊ7`Üî°
Ê Ê 7iÊÜi½ÀiÊÊÌiÊÌ«VÊvÊ`Þ>VÊ*ÞÌÊV`iÊÊÃiÌÌ}ÃÊviÃ]ÊÜiÊÃÕ`Ê«ÌÊÕÌÊ
Ì>ÌÊ̽ÃÊÛiÀÞÊ«ÀÌ>ÌÊÌÊ>Û`Ê*ÞÌÊiÀÀÀÃÊÊÞÕÀÊÃiÌÌ}ÃÊvi°ÊvÊÞÕÊÌÀ`ÕViÊ>Ê
syntax error or a runtime error, your Django-powered site will likely crash.
7ÌÊPAILH=PA[@ENO set, the next step is to change the view code to use Django’s template-
loading functionality rather than hard-coding the template paths. Returning to our _qnnajp[
`]papeia view, let’s change it like so:
bnki`f]jck*pailh]pa*hk]`aneilknpcap[pailh]pa
bnki`f]jck*pailh]paeilknp?kjpatp
bnki`f]jck*dppleilknpDpplNaolkjoa
eilknp`]papeia
`ab_qnnajp[`]papeia$namqaop%6
jks9`]papeia*`]papeia*jks$%
p9cap[pailh]pa$#_qnnajp[`]papeia*dpih#%
dpih9p*naj`an$?kjpatp$w#_qnnajp[`]pa#6jksy%%
napqnjDpplNaolkjoa$dpih%
ÊÌÃÊiÝ>«i]ÊÜi½ÀiÊÕÃ}ÊÌiÊvÕVÌÊ`f]jck*pailh]pa*hk]`an*cap[pailh]pa$%rather
than loading the template from the filesystem manually. The cap[pailh]pa$% function takes a
template name as its argument, figures out where the template lives on the filesystem, opens
that file, and returns a compiled Pailh]pa object.
Our template in this example is _qnnajp[`]papeia*dpih, but there’s nothing special about
that *dpih extension. You can give your templates whatever extension makes sense for your
application, or you can leave off extensions entirely.
CHAPTER 4 N TEMPLATES
62
To determine the location of the template on your filesystem, cap[pailh]pa$% combines
your template directories from PAILH=PA[@ENO with the template name that you pass to cap[
pailh]pa$%. For example, if your PAILH=PA[@ENO is set to #+dkia+`f]jck+iuoepa+pailh]pao#,
the cap[pailh]pa$% call would look for the template +dkia+`f]jck+iuoepa+pailh]pao+
_qnnajp[`]papeia*dpih.
vÊcap[pailh]pa$% cannot find the template with the given name, it raises a
Pailh]pa@kaoJkpAteop exception. To see what that looks like, fire up the Django development
server by running lupdkji]j]ca*lunqjoanran within your Django project’s directory.
Then point your browser at the page that activates the _qnnajp[`]papeia view (e.g., dppl6++
-.3*,*,*-64,,,+peia+). Assuming @A>QC is set to Pnqa and you haven’t yet created a
_qnnajp[`]papeia*dpih template, you should see a Django error page highlighting the
Pailh]pa@kaoJkpAteop error, as shown in Figure 4-1.
Figure 4-1. The error page shown when a template cannot be found
This error page is similar to the one we explained in Chapter 3, with one additional piece
of debugging information: a “Template-loader postmortem” section. This section tells you
which templates Django tried to load, along with the reason each attempt failed (e.g., “File
does not exist”). This information is invaluable when you’re trying to debug template-loading
errors.
Moving along, create the _qnnajp[`]papeia*dpih file within your template directory using
the following template code:
8dpih:8^k`u:Epeojksww_qnnajp[`]payy*8+^k`u:8+dpih:
,ivÀiÃÊÌiÊ«>}iÊÊÞÕÀÊ7iLÊLÀÜÃiÀ]Ê>`ÊÞÕÊÃÕ`ÊÃiiÊÌiÊvÕÞÊÀi`iÀi`Ê«>}e.
CHAPTER 4 N TEMPLATES 63
render_to_response()
7i’ve shown you how to load a template, fill a ?kjpatp, and return an DpplNaolkjoa object
ÜÌÊÌiÊÀiÃÕÌÊvÊÌiÊÀi`iÀi`ÊÌi«>Ìi°Ê7i½ÛiÊ«Ìâi`ÊÌÊÌÊÕÃiÊcap[pailh]pa$% instead of
hard-coding templates and template paths. But it still requires a fair amount of typing to do
those things. Because these steps are such a common idiom, Django provides a shortcut that
lets you load a template, render it, and return an DpplNaolkjoa—all in one line of code.
This shortcut is a function called naj`an[pk[naolkjoa$%, which lives in the module `f]jck*
odknp_qpo. Most of the time you’ll be using naj`an[pk[naolkjoa$% rather than loading tem-
plates and creating ?kjpatp and DpplNaolkjoa objects manually—unless your employer judges
your work by total lines of code written.
Here’s the ongoing _qnnajp[`]papeia example rewritten to use naj`an[pk[naolkjoa$%:
bnki`f]jck*odknp_qpoeilknpnaj`an[pk[naolkjoa
eilknp`]papeia
`ab_qnnajp[`]papeia$namqaop%6
jks9`]papeia*`]papeia*jks$%
napqnjnaj`an[pk[naolkjoa$#_qnnajp[`]papeia*dpih#(w#_qnnajp[`]pa#6jksy%
7>ÌÊ>Ê`vviÀiVitÊi̽ÃÊÃÌi«ÊÌÀÕ}ÊÌiÊV`iÊV>}iÃ\
Ê UÊ 7iÊÊ}iÀÊ>ÛiÊÌÊ«ÀÌÊcap[pailh]pa, Pailh]pa, ?kjpatp, or DpplNaolkjoa.
ÃÌi>`]ÊÜiÊ«ÀÌÊ`f]jck*odknp_qpo*naj`an[pk[naolkjoa. The eilknp`]papeia
remains.
Ê UÊ 7ÌÊÌiÊ_qnnajp[`]papeia function, we still calculate jks, but the template loading,
context creation, template rendering, and DpplNaolkjoa creation are all taken care of by
the naj`an[pk[naolkjoa$% call. Because naj`an[pk[naolkjoa$% returns an DpplNaolkjoa
object, we can simply return that value in the view.
The first argument to naj`an[pk[naolkjoa$% is the name of the template to use. The sec-
ond argument, if given, should be a dictionary to use in creating a ?kjpatpÊvÀÊÌ>ÌÊÌi«>Ìi°ÊvÊ
you don’t provide a second argument, naj`an[pk[naolkjoa$% will use an empty dictionary.
The locals() Trick
Consider our latest incarnation of _qnnajp[`]papeia:
`ab_qnnajp[`]papeia$namqaop%6
jks9`]papeia*`]papeia*jks$%
napqnjnaj`an[pk[naolkjoa$#_qnnajp[`]papeia*dpih#(w#_qnnajp[`]pa#6jksy%
Many times, as in this example, you’ll find yourself calculating some values, storing them
in variables (e.g., jks in the preceding code), and sending those variables to the template. Par-
ticularly lazy programmers should note that it’s slightly redundant to have to give names for
temporary variables andÊ}ÛiÊ>iÃÊvÀÊÌiÊÌi«>ÌiÊÛ>À>LiðÊÌÊ>ÃÊi>ÃÊiÝÌÀ>ÊÌÞ«}°
CHAPTER 4 N TEMPLATES
64
So if you’re one of those lazy programmers and you like keeping code particularly concise,
you can take advantage of a built-in Python function called hk_]ho$%°ÊÌÊÀiÌÕÀÃÊ>Ê`VÌ>ÀÞÊ
mapping all local variable names to their values, where local means all variables that have
been defined within the current scope. Thus, the preceding view could be rewritten like so:
`ab_qnnajp[`]papeia$namqaop%6
_qnnajp[`]pa9`]papeia*`]papeia*jks$%
napqnjnaj`an[pk[naolkjoa$#_qnnajp[`]papeia*dpih#(hk_]ho$%%
Here, instead of manually specifying the context dictionary as before, we pass the value of
hk_]ho$%, which will include all variables defined at that point in the function’s execution. As
a consequence, we’ve renamed the jks variable to _qnnajp[`]pa, because that’s the variable
>iÊÌ>ÌÊÌiÊÌi«>ÌiÊiÝ«iVÌðÊÊÌÃÊiÝ>«i]Êhk_]ho$% doesn’t offer a huge improvement,
but this technique can save you some typing if you have several template variables to define—
or if you’re lazy.
One thing to watch out for when using hk_]ho$% is that it includes every local variable,
ÜVÊ>ÞÊV«ÀÃiÊÀiÊÛ>À>LiÃÊÌ>ÊÞÕÊ>VÌÕ>ÞÊÜ>ÌÊÞÕÀÊÌi«>ÌiÊÌÊ>ÛiÊ>VViÃÃÊÌ°ÊÊ
the previous example, hk_]ho$% will also include namqaop°Ê7iÌiÀÊÌÃÊ>ÌÌiÀÃÊÌÊÞÕÊ`i«i`ÃÊ
on your application and your level of perfectionism.
Subdirectories in get_template()
ÌÊcan get unwieldy to store all of your templates in a single directory. You might like to store
Ìi«>ÌiÃÊÊÃÕL`ÀiVÌÀiÃÊvÊÞÕÀÊÌi«>ÌiÊ`ÀiVÌÀÞ]Ê>`ÊÌ>̽ÃÊvi°ÊÊv>VÌ]ÊÜiÊÀiVi`Ê
doing so; some more-advanced Django features (such as the generic views system, which we
cover in Chapter 11) expect this template layout as a default convention.
-ÌÀ}ÊÌi«>ÌiÃÊÊÃÕL`ÀiVÌÀiÃÊvÊÞÕÀÊÌi«>ÌiÊ`ÀiVÌÀÞÊÃÊi>ÃÞ°ÊÊÞÕÀÊV>ÃÊÌÊcap[
pailh]pa$%, just include the subdirectory name and a slash before the template name, like so:
p9cap[pailh]pa$#`]pa]ll+_qnnajp[`]papeia*dpih#%
Because naj`an[pk[naolkjoa$% is a small wrapper around cap[pailh]pa$%, you can do the
same thing with the first argument to naj`an[pk[naolkjoa$%, like this:
napqnjnaj`an[pk[naolkjoa$#`]pa]ll+_qnnajp[`]papeia*dpih#(w#_qnnajp[`]pa#6jksy%
There’s no limit to the depth of your subdirectory tree. Feel free to use as many subdirec-
tories as you like.
NNote Windows users, be sure to use forward slashes rather than backslashes. cap[pailh]pa$%
assumes a Unix-style file-name designation.
CHAPTER 4 N TEMPLATES 65
The include Template Tag
Now that we’ve covered the template-loading mechanism, we can introduce a built-in tem-
plate tag that takes advantage of it: w!ej_hq`a!y. This 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 sin-
gle or double quotes. Anytime you have the same code in multiple templates, consider using
w!ej_hq`a!y to remove the duplication.
These two examples include the contents of the template j]r*dpih. The examples are
equivalent and illustrate that either single or double quotes are allowed:
w!ej_hq`a#j]r*dpih#!y
w!ej_hq`aj]r*dpih!y
This example includes the contents of the template ej_hq`ao+j]r*dpih:
w!ej_hq`a#ej_hq`ao+j]r*dpih#!y
The following example includes the contents of the template whose name is contained in
the variable pailh]pa[j]ia:
w!ej_hq`apailh]pa[j]ia!y
As in cap[pailh]pa$%, the template’s file name is determined by adding the template
directory from PAILH=PA[@ENO to the requested template name.
VÕ`i`ÊÌi«>ÌiÃÊ>ÀiÊiÛ>Õ>Ìi`ÊÜÌÊÌiÊVÌiÝÌÊvÊÌiÊÌi«>ÌiÊÌ>̽ÃÊVÕ`}ÊÌi°Ê
For example, consider these two templates:
iul]ca*dpih
8dpih:
8^k`u:
w!ej_hq`aej_hq`ao+j]r*dpih!y
8d-:wwpephayy8+d-:
8+^k`u:
8+dpih:
ej_hq`ao+j]r*dpih
8`ere`9j]r:
Ukq]naej6ww_qnnajp[oa_pekjyy
8+`er:
vÊÞÕÊÀi`iÀÊiul]ca*dpih with a context containing _qnnajp[oa_pekj, then the variable
will be available in the ej_hq`ad template, as you would expect.
CHAPTER 4 N TEMPLATES
66
v]ÊÊ>Êw!ej_hq`a!y tag, a template with the given name isn’t found, Django will do one
of two things:
Ê UÊ vÊ@A>QC is set to Pnqa, you’ll see the Pailh]pa@kaoJkpAteop exception on a Django error
page.
Ê UÊ vÊ@A>QC is set to B]hoa, the tag will fail silently, displaying nothing in the place of the tag.
Template Inheritance
Our template examples so far have been tiny HTML snippets, but in the real world you’ll
be using Django’s template system to create entire HTML pages. This leads to a common
7iL`iÛi«iÌÊ«ÀLi\Ê>VÀÃÃÊ>Ê7iLÊÃÌi]ÊÜÊ`iÃÊiÊÀi`ÕViÊÌiÊ`Õ«V>ÌÊ>`Ê
redundancy of common page areas, such as sitewide navigation?
A classic way of solving this problem is to use server-side includes, directives you can embed
ÜÌÊÞÕÀÊ/Ê«>}iÃÊÌÊVÕ`iÊiÊ7iLÊ«>}iÊÃ`iÊ>ÌiÀ°Ê`ii`]Ê>}ÊÃÕ««ÀÌÃÊÌ>ÌÊ
approach, with the w!ej_hq`a!y template tag just described. But the preferred way of solving
this problem with Django is to use a more elegant strategy called template inheritance.
ÊiÃÃiVi]ÊÌi«>ÌiÊiÀÌ>ViÊiÌÃÊÞÕÊLÕ`Ê>ÊL>ÃiʺÃiiÌ»ÊÌi«>ÌiÊÌ>ÌÊVÌ>ÃÊ
all the common parts of your site and defines “blocks” that child templates can override.
Let’s see an example of this by creating a more complete template for our _qnnajp[
`]papeia view, by editing the _qnnajp[`]papeia*dpih file:
8@K?PULADPIHLQ>HE?)++S/?++@P@DPIH0*,-++AJ:
8dpihh]jc9aj:
8da]`:
8pepha:Pda_qnnajppeia8+pepha:
8+da]`:
8^k`u:
8d-:Iudahlbqhpeiaop]iloepa8+d-:
8l:Epeojksww_qnnajp[`]payy*8+l:
8dn:
8l:Pd]jgobknreoepejciuoepa*8+l:
8+^k`u:
8+dpih:
That looks just fine, but what happens when we want to create a template for another
view—say, the dkqno[]da]` viewÊvÀÊ>«ÌiÀÊζÊvÊÜiÊÜ>ÌÊ>}>ÊÌÊ>iÊ>ÊVi]ÊÛ>`]ÊvÕÊ
HTML template, we’d create something like this:
8@K?PULADPIHLQ>HE?)++S/?++@P@DPIH0*,-++AJ:
8dpihh]jc9aj:
8da]`:
8pepha:Bqpqnapeia8+pepha:
8+da]`:
CHAPTER 4 N TEMPLATES 67
8^k`u:
8d-:Iudahlbqhpeiaop]iloepa8+d-:
8l:Ejwwdkqn[kbboapyydkqn$o%(epsehh^awwjatp[peiayy*8+l:
8dn:
8l:Pd]jgobknreoepejciuoepa*8+l:
8+^k`u:
8+dpih:
i>ÀÞ]ÊÜi½ÛiÊÕÃÌÊ`Õ«V>Ìi`Ê>ÊÌÊvÊ/°Ê>}iÊvÊÜiÊ>`Ê>ÊÀiÊÌÞ«V>ÊÃÌi]ÊVÕ`-
ing a navigation bar, a few style sheets, perhaps some JavaScript—we’d end up putting all sorts
of redundant HTML into each template.
The server-side include solution to this problem is to factor out the common bits in both
templates and save them in separate template snippets, which are then included in each tem-
plate. Perhaps you’d store the top bit of the template in a file called da]`an*dpih:
8@K?PULADPIHLQ>HE?)++S/?++@P@DPIH0*,-++AJ:
8dpihh]jc9aj:
8da]`:
And perhaps you’d store the bottom bit in a file called bkkpan*dpih:
8dn:
8l:Pd]jgobknreoepejciuoepa*8+l:
8+^k`u:
8+dpih:
7ÌÊ>ÊVÕ`iL>Ãi`ÊÃÌÀ>Ìi}Þ]Êi>`iÀÃÊ>`ÊvÌiÀÃÊ>ÀiÊi>ÃÞ°Ê̽ÃÊÌiÊ``iÊ}ÀÕ`ÊÌ>̽ÃÊ
iÃÃÞ°ÊÊÌÃÊiÝ>«i]ÊLÌÊ«>}iÃÊvi>ÌÕÀiÊ>ÊÌÌip8d-:Iudahlbqhpeiaop]iloepa8+d-:
but that title can’t fit into da]`an*dpih because the 8pepha:ÊÊLÌÊ«>}iÃÊÃÊ`vviÀiÌ°ÊvÊÜiÊ
included the 8d-: in the header, we’d have to include the 8pepha:, which wouldn’t allow us to
customize it per page. See where this is going?
Django’s template-inheritance system solves these problems. You can think of it as an
Ã`iÕÌÊÛiÀÃÊvÊÃiÀÛiÀÃ`iÊVÕ`iðÊÃÌi>`ÊvÊ`iv}ÊÌiÊÃ««iÌÃÊÌ>ÌÊ>ÀiÊcommon,
you define the snippets that are different.
The first step is to define a base template—a skeleton of your page that child templates will
later fill in. Here’s a base template for our ongoing example:
8@K?PULADPIHLQ>HE?)++S/?++@P@DPIH0*,-++AJ:
8dpihh]jc9aj:
8da]`:
8pepha:w!^hk_gpepha!yw!aj`^hk_g!y8+pepha:
8+da]`:
8^k`u:
8d-:Iudahlbqhpeiaop]iloepa8+d-:
w!^hk_g_kjpajp!yw!aj`^hk_g!y
w!^hk_gbkkpan!y
8dn:
8l:Pd]jgobknreoepejciuoepa*8+l:
w!aj`^hk_g!y
8+^k`u:
8+dpih:
CHAPTER 4 N TEMPLATES
68
This template, which we’ll call ^]oa*dpih, defines a simple HTML skeleton document
Ì>ÌÊÜi½ÊÕÃiÊvÀÊ>ÊÌiÊ«>}iÃÊÊÌiÊÃÌi°Ê̽ÃÊÌiÊLÊvÊV`ÊÌi«>ÌiÃÊÌÊÛiÀÀ`i]Ê>``ÊÌ]ÊÀÊ
i>ÛiÊ>iÊÌiÊVÌiÌÃÊvÊÌiÊLVðÊvÊÞÕ½ÀiÊvÜ}Ê>}]ÊÃ>ÛiÊÌÃÊviÊÌÊÞÕÀÊÌi«>ÌiÊ
directory as ^]oa*dpih.)
7i½ÀiÊÕÃ}Ê>ÊÌi«>ÌiÊÌ>}ÊiÀiÊÌ>ÌÊÞÕÊ>Ûi½ÌÊÃiiÊLivÀi\ÊÌiÊw!^hk_g!y tag. All the
w!^hk_g!y tags do is tell the template engine that a child template may override those por-
tions of the template.
Now that we have this base template, we can modify our existing _qnnajp[`]papeia*dpih
template to use it:
w!atpaj`o^]oa*dpih!y
w!^hk_gpepha!yPda_qnnajppeiaw!aj`^hk_g!y
w!^hk_g_kjpajp!y
8l:Epeojksww_qnnajp[`]payy*8+l:
w!aj`^hk_g!y
7iÊÜi½ÀiÊ>ÌÊÌ]Êi̽ÃÊVÀi>ÌiÊ>ÊÌi«>ÌiÊvÀÊÌiÊdkqno[]da]` viewÊvÀÊ>«ÌiÀÊΰÊvÊÞÕ½ÀiÊ
following along with code, we’ll leave it up to you to change dkqno[]da]` to use the template
system instead of hard-coded HTML.) Here’s what that could look like:
w!atpaj`o^]oa*dpih!y
w!^hk_gpepha!yBqpqnapeiaw!aj`^hk_g!y
w!^hk_g_kjpajp!y
8l:Ejwwdkqn[kbboapyydkqn$o%(epsehh^awwjatp[peiayy*8+l:
w!aj`^hk_g!y
Ã½ÌÊÌÃÊLi>ÕÌvÕ¶Ê>VÊÌi«>ÌiÊVÌ>ÃÊÞÊÌiÊV`iÊÌ>̽ÃÊunique to that template.
ÊÀi`Õ`>VÞÊii`i`°ÊvÊÞÕÊii`ÊÌÊ>iÊ>ÊÃÌiÜ`iÊ`iÃ}ÊV>}i]ÊÕÃÌÊ>iÊÌiÊV>}iÊÌÊ
^]oa*dpih, and all of the other templates will immediately reflect the change.
iÀi½ÃÊÜÊÌÊÜÀðÊ7iÊÞÕÊ>`ÊÌiÊÌi«>ÌiÊ_qnnajp[`]papeia*dpih, the template
engine sees the w!atpaj`o!y tag, noting that this template is a child template. The engine
immediately loads the parent template—in this case, ^]oa*dpih.
At that point, the template engine notices the three w!^hk_g!y tags in ^]oa*dpih and
replaces those blocks with the contents of the child template. So, the title we’ve defined in w!
^hk_gpepha!y will be used, as will the w!^hk_g_kjpajp!y.
Note that since the child template doesn’t define the bkkpan block, the template system
uses the value from the parent template instead. Content within a w!^hk_g!y tag in a parent
template is always used as a fallback.
iÀÌ>ViÊ`iÃ½ÌÊ>vviVÌÊÌiÊÌi«>ÌiÊVÌiÝÌ°ÊÊÌiÀÊÜÀ`Ã]Ê>ÞÊÌi«>ÌiÊÊÌiÊiÀ-
itance tree will have access to every one of your template variables from the context.
CHAPTER 4 N TEMPLATES 69
You can use as many levels of inheritance as needed. One common way of using inheri-
tance is the following three-level approach:
1. Create a ^]oa*dpih template that holds the main look and feel of your site. This is the
stuff that rarely, if ever, changes.
2. Create a ^]oa[OA?PEKJ*dpih template for each “section” of your site (e.g., ^]oa[ldkpko*
dpih and ^]oa[bknqi*dpih). These templates extend ^]oa*dpih and include section-
specific styles/design.
3. Create individual templates for each type of page, such as a forum page or a photo gal-
lery. These templates extend the appropriate section template.
This approach maximizes code reuse and makes it easy to add items to shared areas, such
as sectionwide navigation.
Here are some guidelines for working with template inheritance:
Ê UÊ vÊÞÕÊÕÃiÊw!atpaj`o!y in a template, it must be the first template tag in that tem-
plate. Otherwise, template inheritance won’t work.
Ê UÊ iiÀ>Þ]ÊÌiÊÀiÊw!^hk_g!y tags in your base templates, the better. Remember,
child templates don’t have to define all parent blocks, so you can fill in reasonable
defaults in a number of blocks and then define only the ones you need in the child
Ìi«>ÌiðÊ̽ÃÊLiÌÌiÀÊÌÊ>ÛiÊÀiÊÃÊÌ>ÊviÜiÀÊð
Ê UÊ vÊÞÕÊv`ÊÞÕÀÃivÊ`Õ«V>Ì}ÊV`iÊÊ>ÊÕLiÀÊvÊÌi«>ÌiÃ]ÊÌÊ«ÀL>LÞÊi>ÃÊÞÕÊ
should move that code to a w!^hk_g!y in a parent template.
Ê UÊ vÊÞÕÊii`ÊÌÊ}iÌÊÌiÊVÌiÌÊvÊÌiÊLVÊvÀÊÌiÊ«>ÀiÌÊÌi«>Ìi]ÊÕÃiÊww^hk_g*
oqlanyy, which is a “magic” variable providing the rendered text of the parent tem-
plate. This is useful if you want to add to the contents of a parent block instead of
completely overriding it.
Ê UÊ 9ÕÊ>ÞÊÌÊ`iviÊÕÌ«iÊw!^hk_g!y tags with the same name in the same tem-
plate. This limitation exists because a block tag works in both directions. That is, a
block tag doesn’t just provide a hole to fill; it also defines the content that fills the hole
in the parent°ÊvÊÌiÀiÊÜiÀiÊÌÜÊÃ>ÀÞÊ>i`Êw!^hk_g!y tags in a template, that
template’s parent wouldn’t know which one of the blocks’ content to use.
Ê UÊ /iÊÌi«>ÌiÊ>iÊÞÕÊ«>ÃÃÊÌÊw!atpaj`o!y is loaded using the same method that
cap[pailh]pa$% uses. That is, the template name is appended to your PAILH=PA[@ENO
setting.
Ê UÊ ÊÃÌÊV>ÃiÃ]ÊÌiÊ>À}ÕiÌÊÌÊw!atpaj`o!y will be a string, but it can be a variable if
you don’t know the name of the parent template until runtime. This lets you do some
cool, dynamic stuff.
CHAPTER 4 N TEMPLATES
70
What's Next?
9ÕÊÜÊ>ÛiÊÌiÊL>ÃVÃÊvÊ>}½ÃÊÌi«>ÌiÊÃÞÃÌiÊÕ`iÀÊÞÕÀÊLiÌ°Ê7>̽ÃÊiÝ̶
>ÞÊ`iÀÊ7iLÊÃÌiÃÊ>ÀiÊdatabase-driven\ÊÌiÊVÌiÌÊvÊÌiÊ7iLÊÃÌiÊÃÊÃÌÀi`ÊÊ>Ê
relational database. This allows a clean separation of data and logic (in the same way views
and templates allow the separation of logic and display).
The next chapter covers the tools Django gives you to interact with a database.
CHAPTER 5
Models
In Chapter 3, we covered the fundamentals of building dynamic Web sites with Django: set-
ting up views and URLconfs. As we explained, a view is responsible for doing some arbitrary
logic, and then returning a response. In one of the examples, our arbitrary logic was to calcu-
late the current date and time.
In modern Web applications, the arbitrary logic often involves interacting with a database.
Behind the scenes, a database-driven Web site connects to a database server, retrieves some
data out of it, and displays that data on a Web page. The site might also provide ways for site
visitors to populate the database on their own.
Many complex Web sites provide some combination of the two. Amazon.com, for
instance, is a great example of a database-driven site. Each product page is essentially a query
into Amazon’s product database formatted as HTML, and when you post a customer review, it
gets inserted into the database of reviews.
Django is well suited for making database-driven Web sites because it comes with easy yet
powerful tools for performing database queries using Python. This chapter explains that func-
tionality: Django’s database layer.
NNote While it’s not strictly necessary to know basic relational database theory and SQL in order to use
Django’s database layer, it’s highly recommended. An introduction to those concepts is beyond the scope
of this book, but keep reading even if you’re a database newbie. You’ll probably be able to follow along and
grasp concepts based on the context.)
The “Dumb” Way to Do Database Queries in Views
Just as Chapter 3 detailed a “dumb” way to produce output within a view (by hard-coding the
text directly within the view), there’s a “dumb” way to retrieve data from a database in a view.
It’s simple: just use any existing Python library to execute an SQL query and do something
with the results.
71
CHAPTER 5 N MODELS
72
In this example view, we use the IuOMH`^ library (available via dppl6++sss*`f]jcklnkfa_p*
_ki+n+lupdkj)iuomh+) to connect to a MySQL database, retrieve some records, and feed them
to a template for display as a Web page:
bnki`f]jck*odknp_qpoeilknpnaj`an[pk[naolkjoa
eilknpIuOMH`^
`ab^kkg[heop$namqaop%6
`^9IuOMH`^*_kjja_p$qoan9#ia#(`^9#iu`^#(l]oos`9#oa_nap#(dkop9#hk_]hdkop#%
_qnokn9`^*_qnokn$%
_qnokn*ata_qpa$#OAHA?Pj]iaBNKI^kkgoKN@AN>Uj]ia#%
j]iao9WnksW,Ybknnksej_qnokn*bap_d]hh$%Y
`^*_hkoa$%
napqnjnaj`an[pk[naolkjoa$#^kkg[heop*dpih#(w#j]iao#6j]iaoy%
This approach works, but some problems should jump out at you immediately:
Ê UÊ 7i½ÀiÊ>À`V`}ÊÌiÊ`>Ì>L>ÃiÊViVÌÊ«>À>iÌiÀðÊ`i>Þ]ÊÌiÃiÊ«>À>iÌiÀÃÊ
would be stored in the Django configuration.
Ê UÊ 7i½ÀiÊ>Û}ÊÌÊÜÀÌiÊ>Êv>ÀÊLÌÊvÊLiÀ«>ÌiÊV`i\ÊVÀi>Ì}Ê>ÊViVÌ]ÊVÀi>Ì}Ê>Ê
cursor, executing a statement, and closing the connection. Ideally, all we’d have to do
is specify which results we want.
Ê UÊ ÌÊÌiÃÊÕÃÊÌÊÞ-+°Êv]Ê`ÜÊÌiÊÀ>`]ÊÜiÊÃÜÌVÊvÀÊÞ-+ÊÌÊ*ÃÌ}Ài-+]ÊÜi½Ê>ÛiÊ
to use a different database adapter (e.g., lou_klc rather than IuOMH`^), alter the con-
nection parameters, and—depending on the nature of the SQL statement—possibly
rewrite the SQL. Ideally, the database server we’re using would be abstracted, so that
a database server change could be made in a single place. (This feature is particularly
useful if you’re building an open source Django application that you want to be used
by as many people as possible.)
As you might expect, Django’s database layer aims to solve these problems. Here’s a sneak
preview of how the previous view can be rewritten using Django’s database API:
bnki`f]jck*odknp_qpoeilknpnaj`an[pk[naolkjoa
bnkiiuoepa*^kkgo*ik`ahoeilknp>kkg
`ab^kkg[heop$namqaop%6
^kkgo9>kkg*k^fa_po*kn`an[^u$#j]ia#%
napqnjnaj`an[pk[naolkjoa$#^kkg[heop*dpih#(w#^kkgo#6^kkgoy%
We’ll explain this code a little later in the chapter. For now, just get a feel for how it looks.
The MTV (or MVC) Development Pattern
Before we delve into any more code, let’s take a moment to consider the overall design of a
database-driven Django Web application.
As we mentioned in previous chapters, Django is designed to encourage loose coupling
and strict separation between pieces of an application. If you follow this philosophy, it’s easy
to make changes to one particular piece of the application without affecting the other pieces.
CHAPTER 5 N MODELS 73
In view functions, for instance, we discussed the importance of separating the business logic
from the presentation logic by using a template system. With the database layer, we’re apply-
ing that same philosophy to data access logic.
Those three pieces together—data access logic, business logic, and presentation logic—
comprise a concept that’s sometimes called the Model-View-Controller (MVC) pattern of
software architecture. In this pattern, “Model” refers to the data access layer, “View” refers to
the part of the system that selects what to display and how to display it, and “Controller” refers
to the part of the system that decides which view to use, depending on user input, accessing
the model as needed.
WHY THE ACRONYM?
The goal of explicitly defining patterns such as MVC is mostly to streamline communication among develop-
ers. Instead of having to tell your coworkers, “Let’s make an abstraction of the data access, then let’s have a
separate layer that handles data display, and let’s put a layer in the middle that regulates this,” you can take
advantage of a shared vocabulary and say, “Let’s use the MVC pattern here.”
Django follows this MVC pattern closely enough that it can be called an MVC framework.
Here’s roughly how the M, V, and C break down in Django:
ÊUÊM, the data-access portion, is handled by Django’s database layer, which is described
in this chapter.
ÊUÊV, the portion that selects which data to display and how to display it, is handled by
views and templates.
ÊUÊC, the portion that delegates to a view depending on user input, is handled by the
framework itself by following your URLconf and calling the appropriate Python func-
tion for the given URL.
Because the “C” is handled by the framework itself and most of the excitement in Django
happens in models, templates, and views, Django has been referred to as an MTV framework.
In the MTV development pattern,
ÊUÊM stands for “Model,” the data access layer. This layer contains anything and every-
thing about the data: how to access it, how to validate it, which behaviors it has, and
the relationships between the data.
ÊUÊT stands for “Template,” the presentation layer. This layer contains presentation-
related decisions: how something should be displayed on a Web page or other type of
document.
ÊUÊV stands for “View,” the business logic layer. This layer contains the logic that accesses
the model and defers to the appropriate template(s). You can think of it as the bridge
between models and templates.
If you’re familiar with other MVC Web-development frameworks, such as Ruby on
Rails, you may consider Django views to be the “controllers” and Django templates to be the
“views.” This is an unfortunate confusion brought about by differing interpretations of MVC.
CHAPTER 5 N MODELS
74
In Django’s interpretation of MVC, the “view” describes the data that gets presented to the
user; it’s not necessarily just how the data looks, but which data is presented. In contrast, Ruby
on Rails and similar frameworks suggest that the controller’s job includes deciding which data
gets presented to the user, whereas the view is strictly how the data looks, not which data is
presented.
Neither interpretation is more “correct” than the other. The important thing is to under-
stand the underlying concepts.
Configuring the Database
With all of that philosophy in mind, let’s start exploring Django’s database layer. First, we need
to take care of some initial configuration; we need to tell Django which database server to use
and how to connect to it.
We’ll assume you’ve set up a database server, activated it, and created a database within
it (e.g., using a ?NA=PA@=P=>=OA statement). If you’re using SQLite, no such setup is required
because SQLite uses standalone files on the filesystem to store its data.
As with PAILH=PA[@ENO in the previous chapter, database configuration lives in the Django
settings file, called oappejco*lu by default. Edit that file and look for the database settings:
@=P=>=OA[AJCEJA9##
@=P=>=OA[J=IA9##
@=P=>=OA[QOAN9##
@=P=>=OA[L=OOSKN@9##
@=P=>=OA[DKOP9##
@=P=>=OA[LKNP9##
Here’s a rundown of each setting.
ÊUÊ@=P=>=OA[AJCEJA tells Django which database engine to use. If you’re using a database
with Django, @=P=>=OA[AJCEJA must be set to one of the strings shown in Table 5-1.
Table 5-1. Database Engine Settings
Setting Database Required Adapter
lkopcnaomh PostgreSQL lou_klc version 1.x, dppl6++sss*`f]jcklnkfa_p*
_ki+n+lupdkj)lcomh+-+.
lkopcnaomh[lou_klc. PostgreSQL lou_klc version 2.x, dppl6++sss*`f]jcklnkfa_p*
_ki+n+lupdkj)lcomh+.
iuomh MySQL IuOMH`^, dppl6++sss*`f]jcklnkfa_p*_ki+n+
lupdkj)iuomh+.
omhepa/ SQLite No adapter needed if using Python 2.5+. Otherwise,
luomhepa, dppl6++sss*`f]jcklnkfa_p*_ki+n+
lupdkj)omhepa+.
kn]_ha Oracle _t[Kn]_ha, dppl6++sss*`f]jcklnkfa_p*_ki+n+
lupdkj)kn]_ha+.
CHAPTER 5 N MODELS 75
Ê ÌiÊÌ>ÌÊvÀÊÜViÛiÀÊ`>Ì>L>ÃiÊL>Vi`ÊÞÕÊÕÃi]ÊÞÕ½Êii`ÊÌÊ`Ü>`Ê>`Ê
install the appropriate database adapter. Each one is available for free on the Web; just
follow the links in the “Required Adapter” column in Table 5-1. If you’re on Linux, your
distribution’s package-management system might offer convenient packages. (Look
for packages called lupdkj)lkopcnaomh or lupdkj)lou_klc.) For example:
@=P=>=OA[AJCEJA9#lkopcnaomh[lou_klc.#
ÊUÊ@=P=>=OA[J=IA tells Django the name of your database. For example:
@=P=>=OA[J=IA9#iu`^#
If you’re using SQLite, specify the full filesystem path to the database file on your
filesystem. For example:
@=P=>=OA[J=IA9#+dkia+`f]jck+iu`]p]*`^#
As for where to put that SQLite database, we’re using the +dkia+`f]jck directory in
this example, but you should pick a directory that works best for you.
ÊUÊ@=P=>=OA[QOAN tells Django which username to use when connecting to your database.
If you’re using SQLite, leave this blank.
ÊUÊ@=P=>=OA[L=OOSKN@ tells Django which password to use when connecting to your
database. If you’re using SQLite or have an empty password, leave this blank.
ÊUÊ@=P=>=OA[DKOP tells Django which host to use when connecting to your database.
If your database is on the same computer as your Django installation (i.e., localhost),
leave this blank. If you’re using SQLite, leave this blank.
MySQL is a special case here. If this value starts with a forward slash (#+#) and you’re
using MySQL, MySQL will connect via a Unix socket to the specified socket, for
example:
@=P=>=OA[DKOP9#+r]n+nqj+iuomh#
Once you’ve entered those settings and saved oappejco*lu, it’s a good idea to test your
configuration. To do this, run lupdkji]j]ca*luodahh, as in the last chapter, from within the
iuoepa project directory. (As discussed in the previous chapter, i]j]ca*luodahh is a way to run
the Python interpreter with the correct Django settings activated. This is necessary in our case
because Django needs to know which settings file to use in order to get your database connec-
tion information.)
In the shell, type these commands to test your database configuration:
:::bnki`f]jck*`^eilknp_kjja_pekj
:::_qnokn9_kjja_pekj*_qnokn$%
If nothing happens, then your database is configured properly. Otherwise, check the error
message for clues about what’s wrong. Table 5-2 shows some common errors.
CHAPTER 5 N MODELS
76
Table 5-2. Database Configuration Error Messages
Error Message Solution
You haven’t set the
@=P=>=OA[AJCEJA setting yet.
Set the @=P=>=OA[AJCEJA setting to something other
than an empty string. Valid values are shown in
Table 5-1.
Environment variable
@F=JCK[OAPPEJCO[IK@QHA is undefined.
Run the command lupdkji]j]ca*luodahh rather
than lupdkj.
Error loading _____ module:
No module named _____.
You haven’t installed the appropriate database-
specific adapter (e.g., lou_klc or IuOMH`^). Adapters
are not bundled with Django, so it’s your responsi-
bility to download and install them on your own.
_____ isn’t an available database back-end. Set your @=P=>=OA[AJCEJA setting to one of the valid
engine settings described previously. Perhaps you
made a typo?
Database _____ does not exist Change the @=P=>=OA[J=IA setting to point to a
database that exists, or execute the appropriate
?NA=PA@=P=>=OA statement in order to create it.
Role _____ does not exist Change the @=P=>=OA[QOAN setting to point to a user
that exists, or create the user in your database.
Could not connect to server Make sure @=P=>=OA[DKOP and @=P=>=OA[LKNP are
set correctly, and make sure the database server is
running.
Your First App
Now that you’ve verified the connection is working, it’s time to create a Django app—a bundle
of Django code, including models and views, that lives together in a single Python package and
represents a full Django application.
It’s worth explaining the terminology here, because this tends to trip up beginners. We
already created a project in Chapter 2, so what’s the difference between a project and an app?
The difference is that of configuration vs. code:
Ê UÊ Ê«ÀiVÌ is an instance of a certain set of Django apps, plus the configuration for
those apps.
Ê UÊ /iVV>Þ]ÊÌiÊÞÊÀiµÕÀiiÌÊvÊ>Ê«ÀiVÌÊÃÊÌ>ÌÊÌÊÃÕ««iÃÊ>ÊÃiÌÌ}ÃÊvi]ÊÜVÊ
defines the database connection information, the list of installed apps, the PAILH=PA[
@ENO, and so forth.
Ê UÊ Ê>««ÊÃÊ>Ê«ÀÌ>LiÊÃiÌÊvÊ>}ÊvÕVÌ>ÌÞ]ÊÕÃÕ>ÞÊVÕ`}Ê`iÃÊ>`ÊÛiÜÃ]Ê
that lives together in a single Python package.
Ê UÊ ÀÊiÝ>«i]Ê>}ÊViÃÊÜÌÊ>ÊÕLiÀÊvÊ>««Ã, such as a commenting system and
an automatic admin interface. A key thing to note about these apps is that they’re por-
table and reusable across multiple projects.
CHAPTER 5 N MODELS 77
There are very few hard-and-fast rules about how you fit your Django code into this
scheme. If you’re building a simple Web site, you may use only a single app. If you’re building
a complex Web site with several unrelated pieces such as an e-commerce system and a mes-
sage board, you’ll probably want to split those into separate apps so that you’ll be able to reuse
them individually in the future.
Indeed, you don’t necessarily need to create apps at all, as evidenced by the example
view functions we’ve created so far in this book. In those cases, we simply created a file called
reaso*lu, filled it with view functions, and pointed our URLconf at those functions. No “apps”
were needed.
However, there’s one requirement regarding the app convention: if you’re using Django’s
database layer (models), you must create a Django app. Models must live within apps. Thus, in
order to start writing our models, we’ll need to create a new app.
Within the iuoepa project directory, type this command to create a ^kkgo app:
lupdkji]j]ca*luop]np]ll^kkgo
This command does not produce any output, but it does create a ^kkgo directory within
the iuoepa directory. Let’s look at the contents of that directory:
^kkgo+
[[ejep[[*lu
ik`aho*lu
paopo*lu
reaso*lu
These files will contain the models and views for this app.
Have a look at ik`aho*lu and reaso*lu in your favorite text editor. Both files are empty,
except for comments and an import in ik`aho*lu. This is the blank slate for your Django app.
Defining Models in Python
As we discussed earlier in this chapter, the “M” in “MTV” stands for “Model.” A Django model
is a description of the data in your database, represented as Python code. It’s your data lay-
out—the equivalent of your SQL ?NA=PAP=>HA statements—except it’s in Python instead of
SQL, and it includes more than just database column definitions. Django uses a model to exe-
cute SQL code behind the scenes and return convenient Python data structures representing
the rows in your database tables. Django also uses models to represent higher-level concepts
that SQL can’t necessarily handle.
If you’re familiar with databases, your immediate thought might be, “Isn’t it redundant
to define data models in Python instead of in SQL?” Django works the way it does for several
reasons:
CHAPTER 5 N MODELS
78
Ê UÊ ÌÀëiVÌÊÀiµÕÀiÃÊÛiÀi>`Ê>`ÊÃÊ«iÀviVÌ°ÊÊÀ`iÀÊÌÊ«ÀÛ`iÊVÛiiÌÊ
data-access APIs, Django needs to know the database layout somehow, and there
are two ways of accomplishing this. The first way is to explicitly describe the data in
Python, and the second way is to introspect the database at runtime to determine the
data models.
Ê UÊ /ÃÊÃiV`ÊÜ>ÞÊÃiiÃÊVi>iÀ]ÊLiV>ÕÃiÊÌiÊiÌ>`>Ì>Ê>LÕÌÊÞÕÀÊÌ>LiÃÊÛiÃÊÊÞÊ
one place, but it introduces a few problems. First, introspecting a database at runtime
obviously requires overhead. If the framework had to introspect the database each time
it processed a request, or even only when the Web server was initialized, this would
incur an unacceptable level of overhead. (While some believe that level of overhead is
acceptable, Django’s developers aim to trim as much framework overhead as possible.)
Second, some databases, notably older versions of MySQL, do not store sufficient
metadata for accurate and complete introspection.
Ê UÊ 7ÀÌ}Ê*ÞÌÊÃÊvÕ]Ê>`Êii«}ÊiÛiÀÞÌ}ÊÊ*ÞÌÊÌÃÊÌiÊÕLiÀÊvÊÌiÃÊ
your brain has to do a “context switch.” It helps productivity if you keep yourself in a
single programming environment/mentality for as long as possible. Having to write
SQL, then Python, and then SQL again is disruptive.
Ê UÊ >Û}Ê`>Ì>Ê`iÃÊÃÌÀi`Ê>ÃÊV`iÊÀ>ÌiÀÊÌ>ÊÊÞÕÀÊ`>Ì>L>ÃiÊ>iÃÊÌÊi>ÃiÀÊÌÊii«Ê
your models under version control. This way, you can easily keep track of changes to
your data layouts.
Ê UÊ -+Ê>ÜÃÊvÀÊÞÊ>ÊViÀÌ>ÊiÛiÊvÊiÌ>`>Ì>Ê>LÕÌÊ>Ê`>Ì>Ê>ÞÕÌ°ÊÃÌÊ`>Ì>L>ÃiÊ
systems, for example, do not provide a specialized data type for representing e-mail
addresses or URLs. Django models do. The advantage of higher-level data types is
higher productivity and more reusable code.
Ê UÊ -+ÊÃÊVÃÃÌiÌÊ>VÀÃÃÊ`>Ì>L>ÃiÊ«>ÌvÀðÊvÊÞÕ½ÀiÊ`ÃÌÀLÕÌ}Ê>Ê7iLÊ>««V>Ì]Ê
for example, it’s much more pragmatic to distribute a Python module that describes
your data layout than separate sets of ?NA=PAP=>HA statements for MySQL, PostgreSQL,
and SQLite.
A drawback of this approach, however, is that it’s possible for the Python code to get out
of sync with what’s actually in the database. If you make changes to a Django model, you’ll
need to make the same changes inside your database to keep your database consistent with
the model. We’ll discuss some strategies for handling this problem later in this chapter.
Finally, we should note that Django includes a utility that can generate models by intro-
specting an existing database. This is useful for quickly getting up and running with legacy
data. We’ll cover this in Chapter 18.
Your First Model
As an ongoing example in this chapter and the next chapter, we’ll focus on a basic book/
author/publisher data layout. We use this as our example because the conceptual relation-
ships between books, authors, and publishers are well known, and this is a common data
layout used in introductory SQL textbooks. You’re also reading a book that was written by
authors and produced by a publisher!
CHAPTER 5 N MODELS 79
We’ll suppose the following concepts, fields, and relationships:
Ê UÊ Ê>ÕÌÀÊ>ÃÊ>ÊvÀÃÌÊ>i]Ê>Ê>ÃÌÊ>i]Ê>`Ê>Êi>Ê>``ÀiÃð
Ê UÊ Ê«ÕLÃiÀÊ>ÃÊ>Ê>i]Ê>ÊÃÌÀiiÌÊ>``ÀiÃÃ]Ê>ÊVÌÞ]Ê>ÊÃÌ>ÌiÉ«ÀÛVi]Ê>ÊVÕÌÀÞ]Ê>`Ê>Ê
Web site.
Ê UÊ ÊLÊ>ÃÊ>ÊÌÌiÊ>`Ê>Ê«ÕLV>ÌÊ`>Ìi°ÊÌÊ>ÃÊ>ÃÊiÊÀÊÀiÊ>ÕÌÀÃÊ>Ê>Þ
to-many relationship with authors) and a single publisher (a one-to-many relationship—
aka foreign key—to publishers).
The first step in using this database layout with Django is to express it as Python code. In
the ik`aho*lu file that was created by the op]np]ll command, enter the following:
bnki`f]jck*`^eilknpik`aho
_h]ooLq^heodan$ik`aho*Ik`ah%6
j]ia9ik`aho*?d]nBeah`$i]t[hajcpd9/,%
]``naoo9ik`aho*?d]nBeah`$i]t[hajcpd91,%
_epu9ik`aho*?d]nBeah`$i]t[hajcpd92,%
op]pa[lnkrej_a9ik`aho*?d]nBeah`$i]t[hajcpd9/,%
_kqjpnu9ik`aho*?d]nBeah`$i]t[hajcpd91,%
sa^oepa9ik`aho*QNHBeah`$%
_h]oo=qpdkn$ik`aho*Ik`ah%6
benop[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd9/,%
h]op[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd90,%
ai]eh9ik`aho*Ai]ehBeah`$%
_h]oo>kkg$ik`aho*Ik`ah%6
pepha9ik`aho*?d]nBeah`$i]t[hajcpd9-,,%
]qpdkno9ik`aho*I]juPkI]juBeah`$=qpdkn%
lq^heodan9ik`aho*BknaecjGau$Lq^heodan%
lq^he_]pekj[`]pa9ik`aho*@]paBeah`$%
Let’s quickly examine this code to cover the basics. The first thing to notice is that each
model is represented by a Python class that is a subclass of `f]jck*`^*ik`aho*Ik`ah. The
parent class, Ik`ah, contains all the machinery necessary to make these objects capable of
interacting with a database—and that leaves our models responsible solely for defining their
fields, in a nice and compact syntax. Believe it or not, this is all the code we need to write to
have basic data access with Django.
Each model generally corresponds to a single database table, and each attribute on a
model generally corresponds to a column in that database table. The attribute name cor-
responds to the column’s name, and the type of field (e.g., ?d]nBeah`) corresponds to the
database column type (e.g., r]n_d]n). For example, the Lq^heodan model is equivalent to the
following table (assuming PostgreSQL ?NA=PAP=>HA syntax):
CHAPTER 5 N MODELS
80
?NA=PAP=>HA^kkgo[lq^heodan$
e`oane]hJKPJQHHLNEI=NUGAU(
j]iar]n_d]n$/,%JKPJQHH(
]``naoor]n_d]n$1,%JKPJQHH(
_epur]n_d]n$2,%JKPJQHH(
op]pa[lnkrej_ar]n_d]n$/,%JKPJQHH(
_kqjpnur]n_d]n$1,%JKPJQHH(
sa^oepar]n_d]n$.,,%JKPJQHH
%7
Indeed, Django can generate that ?NA=PAP=>HA statement automatically, as we’ll show
you in a moment.
The exception to the one-class-per-database-table rule is the case of many-to-many rela-
tionships. In our example models, >kkg has a I]juPkI]juBeah` called ]qpdkno. This designates
that a book has one or many authors, but the >kkg database table doesn’t get an ]qpdkno col-
umn. Rather, Django creates an additional table—a many-to-many “join table”—that handles
the mapping of books to authors.
For a full list of field types and model syntax options, see Appendix B.
Finally, note we haven’t explicitly defined a primary key in any of these models. Unless you
instruct it otherwise, Django automatically gives every model an autoincrementing integer pri-
mary key field called e`. Each Django model is required to have a single-column primary key.
Installing the Model
We’ve written the code; now let’s create the tables in our database. In order to do that, the first
step is to activate these models in our Django project. We do that by adding the ^kkgo app to
the list of “installed apps” in the settings file.
Edit the oappejco*lu file again, and look for the EJOP=HHA@[=LLO setting. EJOP=HHA@[=LLO
tells Django which apps are activated for a given project. By default, it looks something like this:
EJOP=HHA@[=LLO9$
#`f]jck*_kjpne^*]qpd#(
#`f]jck*_kjpne^*_kjpajppulao#(
#`f]jck*_kjpne^*oaooekjo#(
#`f]jck*_kjpne^*oepao#(
%
Temporarily comment out all four of those strings by putting a hash character () in front
of them. (They’re included by default as a common-case convenience, but we’ll activate and
discuss them in subsequent chapters.) While you’re at it, comment out the default IE@@HAS=NA[
?H=OOAO setting, too; the default values in IE@@HAS=NA[?H=OOAO depend on some of the apps we
just commented out. Then, add #iuoepa*^kkgo# to the EJOP=HHA@[=LLO list, so the setting ends
up looking like this:
IE@@HAS=NA[?H=OOAO9$
#`f]jck*ie``has]na*_kiikj*?kiikjIe``has]na#(
#`f]jck*_kjpne^*oaooekjo*ie``has]na*OaooekjIe``has]na#(
#`f]jck*_kjpne^*]qpd*ie``has]na*=qpdajpe_]pekjIe``has]na#(
%
CHAPTER 5 N MODELS 81
EJOP=HHA@[=LLO9$
#`f]jck*_kjpne^*]qpd#(
#`f]jck*_kjpne^*_kjpajppulao#(
#`f]jck*_kjpne^*oaooekjo#(
#`f]jck*_kjpne^*oepao#(
#iuoepa*^kkgo#(
%
As discussed in the last chapter, when you set PAILH=PA[@ENO, be sure to include the trail-
ing comma in EJOP=HHA@[=LLO because it’s a single-element tuple. By the way, this book’s
authors prefer to put a comma after every element of a tuple, regardless of whether the tuple
has only a single element. This avoids the issue of forgetting commas, and there’s no penalty
for using that extra comma.
#iuoepa*^kkgo# refers to the ^kkgo app we’re working on. Each app in EJOP=HHA@[=LLO is
represented by its full Python path—that is, the path of packages, separated by dots, leading to
the app package.
Now that the Django app has been activated in the settings file, we can create the data-
base tables in our database. First, let’s validate the models by running this command:
lupdkji]j]ca*lur]he`]pa
The r]he`]pa command checks whether your models’ syntax and logic are correct. If all
is well, you’ll see the message ,annknobkqj`. If you don’t, make sure you typed in the model
code correctly. The error output should give you helpful information about what was wrong
with the code.
Any time you think you have problems with your models, run lupdkji]j]ca*lur]he`]pa.
It tends to catch all the common model problems.
If your models are valid, run the following command for Django to generate ?NA=PAP=>HA
statements for your models in the ^kkgo app (with colorful syntax highlighting available, if
you’re using Unix):
lupdkji]j]ca*luomh]hh^kkgo
In this command, ^kkgo is the name of the app. It’s what you specified when you ran
the command i]j]ca*luop]np]ll. When you run the command, you should see something
like this:
>ACEJ7
?NA=PAP=>HA^kkgo[lq^heodan$
e`oane]hJKPJQHHLNEI=NUGAU(
j]iar]n_d]n$/,%JKPJQHH(
]``naoor]n_d]n$1,%JKPJQHH(
_epur]n_d]n$2,%JKPJQHH(
op]pa[lnkrej_ar]n_d]n$/,%JKPJQHH(
_kqjpnur]n_d]n$1,%JKPJQHH(
sa^oepar]n_d]n$.,,%JKPJQHH
%
7
CHAPTER 5 N MODELS
82
?NA=PAP=>HA^kkgo[]qpdkn$
e`oane]hJKPJQHHLNEI=NUGAU(
benop[j]iar]n_d]n$/,%JKPJQHH(
h]op[j]iar]n_d]n$0,%JKPJQHH(
ai]ehr]n_d]n$31%JKPJQHH
%
7
?NA=PAP=>HA^kkgo[^kkg$
e`oane]hJKPJQHHLNEI=NUGAU(
pephar]n_d]n$-,,%JKPJQHH(
lq^heodan[e`ejpacanJKPJQHHNABANAJ?AO^kkgo[lq^heodan$e`%
@ABANN=>HAEJEPE=HHU@ABANNA@(
lq^he_]pekj[`]pa`]paJKPJQHH
%
7
?NA=PAP=>HA^kkgo[^kkg[]qpdkno$
e`oane]hJKPJQHHLNEI=NUGAU(
^kkg[e`ejpacanJKPJQHHNABANAJ?AO^kkgo[^kkg$e`%
@ABANN=>HAEJEPE=HHU@ABANNA@(
]qpdkn[e`ejpacanJKPJQHHNABANAJ?AO^kkgo[]qpdkn$e`%
@ABANN=>HAEJEPE=HHU@ABANNA@(
QJEMQA$^kkg[e`(]qpdkn[e`%
%
7
?NA=PAEJ@AT^kkgo[^kkg[lq^heodan[e`KJ^kkgo[^kkg$lq^heodan[e`%7
?KIIEP7
Note the following:
Ê UÊ />LiÊ>ià are automatically generated by combining the name of the app (^kkgo)
and the lowercase name of the model (Lq^heodan, >kkg, and =qpdkn). You can override
this behavior, as detailed in Appendix B.
Ê UÊ ÃÊÜiÊiÌi`Êi>ÀiÀ]Ê>}Ê>``ÃÊ>Ê«À>ÀÞÊiÞÊvÀÊi>VÊÌ>LiÊ>ÕÌ>ÌV>ÞpÌiÊ
e` fields. You can override this, too.
Ê UÊ ÞÊVÛiÌ]Ê>}Ê>««i`ÃÊ[e` to the foreign key field name. As you might have
guessed, you can override this behavior, too.
Ê UÊ /iÊvÀi}ÊiÞÊÀi>ÌÃ«ÊÃÊ>`iÊiÝ«VÌÊLÞÊ>ÊNABANAJ?AO statement.
Ê UÊ /iÃiÊ?NA=PAP=>HA statements are tailored to the database you’re using, so database-
specific field types such as ]qpk[ej_naiajp (MySQL), oane]h (PostgreSQL), or ejpacan
lnei]nugau (SQLite) are handled for you automatically. The same goes for quoting of
column names (e.g., using double quotes or single quotes). This example output is in
PostgreSQL syntax.
CHAPTER 5 N MODELS 83
The omh]hh command doesn’t actually create the tables or otherwise touch your data-
base—it just prints output to the screen so you can see what SQL Django would execute if you
asked it. If you wanted to, you could copy and paste this SQL into your database client, or use
Unix pipes to pass it directly (e.g., lupdkji]j]ca*luomh]hh^kkgoxlomhiu`^). However,
Django provides an easier way of committing the SQL to the database: the ouj_`^ command:
lupdkji]j]ca*luouj_`^
Run that command and you’ll see something like this:
?na]pejcp]^ha^kkgo[lq^heodan
?na]pejcp]^ha^kkgo[]qpdkn
?na]pejcp]^ha^kkgo[^kkg
Ejop]hhejcej`atbkn^kkgo*>kkgik`ah
The ouj_`^ command is a simple “sync” of your models to your database. It looks at all of
the models in each app in your EJOP=HHA@[=LLO setting, checks the database to see whether the
appropriate tables exist yet, and creates the tables if they don’t yet exist. Note that ouj_`^ 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, ouj_`^ will not handle that. (More on this in the
“Making Changes to a Database Schema” section toward the end of this chapter.)
If you run lupdkji]j]ca*luouj_`^ again, nothing happens, because you haven’t added
any models to the ^kkgo app or added any apps to EJOP=HHA@[=LLO. Ergo, it’s always safe to run
lupdkji]j]ca*luouj_`^—it won’t clobber things.
If you’re interested, take a moment to dive into your database server’s command-line
client and see the database tables Django created. You can manually run the command-line
client (e.g., lomh for PostgreSQL) or you can run the command lupdkji]j]ca*lu`^odahh,
which will figure out which command-line client to run, depending on your @=P=>=OA[OANRAN
setting. The latter is almost always more convenient.
Basic Data Access
Once you’ve created a model, Django automatically provides a high-level Python API for work-
ing with those models. Try it out by running lupdkji]j]ca*luodahh and typing the following:
:::bnki^kkgo*ik`ahoeilknpLq^heodan
:::l-9Lq^heodan$j]ia9#=lnaoo#(]``naoo9#.411Pahacn]ld=rajqa#(
***_epu9#>angahau#(op]pa[lnkrej_a9#?=#(_kqjpnu9#Q*O*=*#(
***sa^oepa9#dppl6++sss*]lnaoo*_ki+#%
:::l-*o]ra$%
:::l.9Lq^heodan$j]ia9K#Naehhu(]``naoo9#-,B]s_appOp*#(
***_epu9#?]i^ne`ca#(op]pa[lnkrej_a9#I=#(_kqjpnu9#Q*O*=*#(
***sa^oepa9#dppl6++sss*knaehhu*_ki+#%
:::l.*o]ra$%
:::lq^heodan[heop9Lq^heodan*k^fa_po*]hh$%
:::lq^heodan[heop
W8Lq^heodan6Lq^heodank^fa_p:(8Lq^heodan6Lq^heodank^fa_p:Y
CHAPTER 5 N MODELS
84
These few lines of code accomplish quite a bit. Here are the highlights:
Ê UÊ ÀÃÌ]Ê«ÀÌÊÌiÊLq^heodan model class. This lets you interact with the database table
that contains publishers.
Ê UÊ Ài>ÌiÊ>ÊLq^heodan object by instantiating it with values for each field: j]ia, ]``naoo,
and so on.
Ê UÊ /ÊÃ>ÛiÊÌiÊLiVÌÊÌÊÌiÊ`>Ì>L>Ãi]ÊV>ÊÌÃÊo]ra$% method. Behind the scenes, Django
executes an SQL EJOANP statement here.
Ê UÊ /ÊÀiÌÀiÛiÊ«ÕLÃiÀÃÊvÀÊÌiÊ`>Ì>L>Ãi]ÊÕÃiÊÌiÊ>ÌÌÀLÕÌiÊLq^heodan*k^fa_po, which
you can think of as a set of all publishers. Fetch a list of all Lq^heodan objects in the
database with the statement Lq^heodan*k^fa_po*]hh$%. Behind the scenes, Django
executes an SQL OAHA?P statement here.
One thing is worth mentioning, in case it wasn’t clear from this example. When you create
objects using the Django model API, Django doesn’t save the objects to the database until you
call the o]ra$% method:
l-9Lq^heodan$***%
=ppdeolkejp(l-eojkpo]ra`pkpda`]p]^]oauap
l-*o]ra$%
Jksepeo*
If you want to create an object and save it to the database in a single step, use the k^fa_po*
_na]pa$% method. This example is equivalent to the preceding example:
:::l-9Lq^heodan*k^fa_po*_na]pa$j]ia9#=lnaoo#(
***]``naoo9#.411Pahacn]ld=rajqa#(
***_epu9#>angahau#(op]pa[lnkrej_a9#?=#(_kqjpnu9#Q*O*=*#(
***sa^oepa9#dppl6++sss*]lnaoo*_ki+#%
:::l.9Lq^heodan*k^fa_po*_na]pa$j]ia9K#Naehhu(
***]``naoo9#-,B]s_appOp*#(_epu9#?]i^ne`ca#(
***op]pa[lnkrej_a9#I=#(_kqjpnu9#Q*O*=*#(
***sa^oepa9#dppl6++sss*knaehhu*_ki+#%
:::lq^heodan[heop9Lq^heodan*k^fa_po*]hh$%
:::lq^heodan[heop
Naturally, you can do quite a lot with the Django database API—but first, let’s take care of
a small annoyance.
Adding Model String Representations
When we printed out the list of publishers, all we got was this unhelpful display that makes it
difficult to tell the Lq^heodan objects apart:
W8Lq^heodan6Lq^heodank^fa_p:(8Lq^heodan6Lq^heodank^fa_p:Y
CHAPTER 5 N MODELS 85
We can fix this easily by adding a method called [[qje_k`a[[$% to our Lq^heodan class. A
[[qje_k`a[[$% method tells Python how to display the “unicode” representation of an object.
You can see this in action by adding a [[qje_k`a[[$% method to the three models:
bnki`f]jck*`^eilknpik`aho
_h]ooLq^heodan$ik`aho*Ik`ah%6
j]ia9ik`aho*?d]nBeah`$i]t[hajcpd9/,%
]``naoo9ik`aho*?d]nBeah`$i]t[hajcpd91,%
_epu9ik`aho*?d]nBeah`$i]t[hajcpd92,%
op]pa[lnkrej_a9ik`aho*?d]nBeah`$i]t[hajcpd9/,%
_kqjpnu9ik`aho*?d]nBeah`$i]t[hajcpd91,%
sa^oepa9ik`aho*QNHBeah`$%
`ab[[qje_k`a[[$oahb%6
napqnjoahb*j]ia
_h]oo=qpdkn$ik`aho*Ik`ah%6
benop[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd9/,%
h]op[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd90,%
ai]eh9ik`aho*Ai]ehBeah`$%
`ab[[qje_k`a[[$oahb%6
napqnjq#!o!o#!$oahb*benop[j]ia(oahb*h]op[j]ia%
_h]oo>kkg$ik`aho*Ik`ah%6
pepha9ik`aho*?d]nBeah`$i]t[hajcpd9-,,%
]qpdkno9ik`aho*I]juPkI]juBeah`$=qpdkn%
lq^heodan9ik`aho*BknaecjGau$Lq^heodan%
lq^he_]pekj[`]pa9ik`aho*@]paBeah`$%
`ab[[qje_k`a[[$oahb%6
napqnjoahb*pepha
As you can see, a [[qje_k`a[[$% method can do whatever it needs to do in order to return
a representation of an object. Here, the [[qje_k`a[[$% methods for Lq^heodan and >kkg simply
return the object’s name and title, respectively, but the [[qje_k`a[[$% for =qpdkn is slightly
more complex: it pieces together the benop[j]ia and h]op[j]ia fields, separated by a space.
The only requirement for [[qje_k`a[[$% is that it return a Unicode object. If [[qje_k`a[[$%
doesn’t return a Unicode object—if it returns, say, an integer—Python will raise a PulaAnnkn
with a message such as _kan_ejcpkQje_k`a6jaa`opnejckn^qbban(ejpbkqj`.
CHAPTER 5 N MODELS
86
UNICODE OBJECTS
What are Unicode objects?
You can think of a Unicode object as a Python string that can handle more than a million different
types of characters, from accented versions of Latin characters, to non-Latin characters, to curly quotes and
obscure symbols.
Normal Python strings are encoded, which means they use an encoding such as ASCII, ISO-8859-1, or
UTF-8. If you’re storing fancy characters (anything beyond the standard 128 ASCII characters such as 0–9
and A–Z) in a normal Python string, you have to keep track of which encoding your string is using, or else the
fancy characters might appear messed up when they’re displayed or printed. Problems occur when you have
data that’s stored in one encoding and you try to combine it with data in a different encoding, or when you
try to display it in an application that assumes a certain encoding. We’ve all seen Web pages and e-mail that
are littered with “??? ??????” or other characters in odd places; that generally suggests there’s an encoding
problem.
Unicode objects, however, have no encoding; they use a consistent, universal set of characters called,
well, Unicode. When you deal with Unicode objects in Python, you can mix and match them safely without
having to worry about encoding issues.
Django uses Unicode objects throughout the framework. Model objects are retrieved as Unicode objects,
views interact with Unicode data, and templates are rendered as Unicode. You usually won’t have to worry
about making sure that your encodings are right; things should just work.
Note that this has been a very high-level, dumbed-down overview of Unicode objects, and you owe it
to yourself to learn more about the topic. A good place to start is dppl6++sss*fkahkjokbps]na*_ki+
]npe_hao+Qje_k`a*dpih.
For the [[qje_k`a[[$% changes to take effect, exit out of the Python shell and enter it again
with lupdkji]j]ca*luodahh. (This is the simplest way to make code changes take effect.)
Now the list of Lq^heodan objects is much easier to understand:
:::bnki^kkgo*ik`ahoeilknpLq^heodan
:::lq^heodan[heop9Lq^heodan*k^fa_po*]hh$%
:::lq^heodan[heop
W8Lq^heodan6=lnaoo:(8Lq^heodan6K#Naehhu:Y
Make sure any model you define has a [[qje_k`a[[$% method—not only for your own
convenience when using the interactive interpreter, but also because Django uses the output
of [[qje_k`a[[$% in several places when it needs to display objects.
Finally, note that [[qje_k`a[[$% is a good example of adding behavior to models. A Django
model describes more than the database table layout for an object; it also describes any
functionality that an object knows how to do. [[qje_k`a[[$% is one example of such function-
ality—a model knows how to display itself.
Inserting and Updating Data
You’ve already seen this done: to insert a row into your database, first create an instance of
your model using keyword arguments, like so:
CHAPTER 5 N MODELS 87
:::l9Lq^heodan$j]ia9#=lnaoo#(
***]``naoo9#.411Pahacn]ld=ra*#(
***_epu9#>angahau#(
***op]pa[lnkrej_a9#?=#(
***_kqjpnu9#Q*O*=*#(
***sa^oepa9#dppl6++sss*]lnaoo*_ki+#%
This act of instantiating a model class does not touch the database. The record isn’t saved
into the database until you call o]ra$%, like this:
:::l*o]ra$%
In SQL, this can roughly be translated into the following:
EJOANPEJPK^kkgo[lq^heodan
$j]ia(]``naoo(_epu(op]pa[lnkrej_a(_kqjpnu(sa^oepa%
R=HQAO
$#=lnaoo#(#.411Pahacn]ld=ra*#(#>angahau#(#?=#(
#Q*O*=*#(#dppl6++sss*]lnaoo*_ki+#%7
Because the Lq^heodan model uses an autoincrementing primary key e`, the initial call to
o]ra$% does one more thing: it calculates the primary key value for the record and sets it to the
e` attribute on the instance:
:::l*e`
1.pdeosehh`ebban^]oa`kjukqnksj`]p]
Subsequent calls to o]ra$% will save the record in place, without creating a new record
(i.e., performing an SQL QL@=PA statement instead of an EJOANP):
:::l*j]ia9#=lnaooLq^heodejc#
:::l*o]ra$%
The preceding o]ra$% statement will result in roughly the following SQL:
QL@=PA^kkgo[lq^heodanOAP
j]ia9#=lnaooLq^heodejc#(
]``naoo9#.411Pahacn]ld=ra*#(
_epu9#>angahau#(
op]pa[lnkrej_a9#?=#(
_kqjpnu9#Q*O*=*#(
sa^oepa9#dppl6++sss*]lnaoo*_ki#
SDANAe`91.7
Note that all the fields will be updated, not just the ones that have been changed. Depend-
ing on your application, this may cause a race condition. See the section “Updating Multiple
Objects in One Statement” to find out how to execute this (slightly different) query:
QL@=PA^kkgo[lq^heodanOAP
j]ia9#=lnaooLq^heodejc#
SDANAe`91.7
CHAPTER 5 N MODELS
88
Selecting Objects
Knowing how to create and update database records is essential, but chances are that the Web
applications you’ll build will be doing more querying of existing objects than creating new
ones. You’ve already seen a way to retrieve every record for a given model:
:::Lq^heodan*k^fa_po*]hh$%
W8Lq^heodan6=lnaoo:(8Lq^heodan6K#Naehhu:Y
This roughly translates to this SQL:
OAHA?Pe`(j]ia(]``naoo(_epu(op]pa[lnkrej_a(_kqjpnu(sa^oepa
BNKI^kkgo[lq^heodan7
NNote Django doesn’t use OAHA?P& when looking up data and instead lists all fields explicitly. This is by
design: in certain circumstances OAHA?P& can be slower, and (more important) listing fields more closely
follows one tenet of the Zen of Python: “Explicit is better than implicit.” For more on the Zen of Python, try
typing eilknppdeo at a Python prompt.
Let’s take a close look at each part of this Lq^heodan*k^fa_po*]hh$% line:
Ê UÊ ÀÃÌ]ÊÜiÊ>ÛiÊÌiÊ`iÊÜiÊ`ivi`]ÊLq^heodan. No surprise here: when you want to
look up data, you use the model for that data.
Ê iÝÌ]ÊÜiÊ>ÛiÊÌiÊk^fa_po attribute, which is called a manager. Managers are discussed
in detail in Chapter 10. For now, all you need to know is that managers take care of all
“table-level” operations on data including, most important, data lookup.
Ê UÊ Ê`iÃÊ>ÕÌ>ÌV>ÞÊ}iÌÊ>Êk^fa_po manager; you’ll use it any time you want to
look up model instances.
Ê UÊ >Þ]ÊÜiÊ>ÛiÊ]hh$%. This is a method on the k^fa_po manager that returns all the
rows in the database. Though this object looks like a list, it’s actually a MqanuOap—an
object that represents a specific set of rows from the database. Appendix C deals with
MqanuOaps in detail. For the rest of this chapter, we’ll just treat them like the lists they
emulate.
Any database lookup is going to follow this general pattern—we’ll call methods on the
manager attached to the model we want to query against.
Filtering Data
Naturally, it’s rare to want to select everything from a database at once; in most cases, you’ll
want to deal with a subset of your data. In the Django API, you can filter your data using the
behpan$% method:
:::Lq^heodan*k^fa_po*behpan$j]ia9#=lnaoo#%
W8Lq^heodan6=lnaoo:Y
CHAPTER 5 N MODELS 89
behpan$% takes keyword arguments that get translated into the appropriate SQL SDANA
clauses. The preceding example would get translated into something like this:
OAHA?Pe`(j]ia(]``naoo(_epu(op]pa[lnkrej_a(_kqjpnu(sa^oepa
BNKI^kkgo[lq^heodan
SDANAj]ia9#=lnaoo#7
You can pass multiple arguments into behpan$% to narrow down things further:
:::Lq^heodan*k^fa_po*behpan$_kqjpnu9Q*O*=*(op]pa[lnkrej_a9?=%
W8Lq^heodan6=lnaoo:Y
Those multiple arguments get translated into SQL =J@ clauses. Thus, the example in the
code snippet translates into the following:
OAHA?Pe`(j]ia(]``naoo(_epu(op]pa[lnkrej_a(_kqjpnu(sa^oepa
BNKI^kkgo[lq^heodan
SDANA_kqjpnu9#Q*O*=*#
=J@op]pa[lnkrej_a9#?=#7
Notice that by default the lookups use the SQL 9 operator to do exact match lookups.
Other lookup types are available:
:::Lq^heodan*k^fa_po*behpan$j]ia[[_kjp]ejo9lnaoo%
W8Lq^heodan6=lnaoo:Y
That’s a double underscore there between j]ia and _kjp]ejo. Like Python itself, Django
uses the double underscore to signal that something “magic” is happening—here, the
[[_kjp]ejo part gets translated by Django into an SQL HEGA statement:
OAHA?Pe`(j]ia(]``naoo(_epu(op]pa[lnkrej_a(_kqjpnu(sa^oepa
BNKI^kkgo[lq^heodan
SDANAj]iaHEGA#!lnaoo!#7
Many other types of lookups are available, including e_kjp]ejo (case-insensitive HEGA),
op]nposepd and aj`osepd, and n]jca (SQL >APSAAJ queries). Appendix C describes all of these
lookup types in detail.
Retrieving Single Objects
The previous behpan$% examples all returned a MqanuOap, which you can treat like a list. Some-
times it’s more convenient to fetch only a single object instead of a list. That’s what the cap$%
method is for:
:::Lq^heodan*k^fa_po*cap$j]ia9=lnaoo%
8Lq^heodan6=lnaoo:
Instead of a list (rather, MqanuOap), only a single object is returned. Because of that, a query
resulting in multiple objects will cause an exception:
CHAPTER 5 N MODELS
90
:::Lq^heodan*k^fa_po*cap$_kqjpnu9Q*O*=*%
Pn]_a^]_g$ikopna_ajp_]hhh]op%6
***
IqhpelhaK^fa_poNapqnja`6cap$%napqnja`iknapd]jkjaLq^heodan))
epnapqnja`.Hkkgqll]n]iapanosanaw#_kqjpnu#6#Q*O*=*#y
A query that returns no objects also causes an exception:
:::Lq^heodan*k^fa_po*cap$j]ia9Lajcqej%
Pn]_a^]_g$ikopna_ajp_]hhh]op%6
***
@kaoJkpAteop6Lq^heodani]p_dejcmqanu`kaojkpateop*
The @kaoJkpAteop exception is an attribute of the model’s class: Lq^heodan*@kaoJkpAteop.
In your applications, you’ll want to trap these exceptions, like this:
pnu6
l9Lq^heodan*k^fa_po*cap$j]ia9#=lnaoo#%
at_alpLq^heodan*@kaoJkpAteop6
lnejp=lnaooeoj#pejpda`]p]^]oauap*
ahoa6
lnejp=lnaooeoejpda`]p]^]oa*
Ordering Data
As you play around with the previous examples, you might discover that the objects are being
returned in a seemingly random order. You aren’t imagining things; so far we haven’t told the
database how to order its results, so we’re simply getting back data in some arbitrary order
chosen by the database.
In your Django applications, you’ll probably want to order your results according to a cer-
tain value—say, alphabetically. To do this, use the kn`an[^u$% method:
:::Lq^heodan*k^fa_po*kn`an[^u$j]ia%
W8Lq^heodan6=lnaoo:(8Lq^heodan6K#Naehhu:Y
This doesn’t look much different from the earlier ]hh$% example, but the SQL now
includes a specific ordering:
OAHA?Pe`(j]ia(]``naoo(_epu(op]pa[lnkrej_a(_kqjpnu(sa^oepa
BNKI^kkgo[lq^heodan
KN@AN>Uj]ia7
You can order by any field you like:
:::Lq^heodan*k^fa_po*kn`an[^u$]``naoo%
W8Lq^heodan6K#Naehhu:(8Lq^heodan6=lnaoo:Y
:::Lq^heodan*k^fa_po*kn`an[^u$op]pa[lnkrej_a%
W8Lq^heodan6=lnaoo:(8Lq^heodan6K#Naehhu:Y
To order by multiple fields (where the second field is used to disambiguate ordering in
cases where the first is the same), use multiple arguments:
CHAPTER 5 N MODELS 91
:::Lq^heodan*k^fa_po*kn`an[^u$op]pa[lnkrej_a(]``naoo%
W8Lq^heodan6=lnaoo:(8Lq^heodan6K#Naehhu:Y
You can also specify reverse ordering by prefixing the field name with a ) (that’s a minus
character):
:::Lq^heodan*k^fa_po*kn`an[^u$)j]ia%
W8Lq^heodan6K#Naehhu:(8Lq^heodan6=lnaoo:Y
While this flexibility is useful, using kn`an[^u$% all the time can be quite repetitive. Most of
the time you’ll have a particular field you usually want to order by. In these cases, Django lets
you specify a default ordering in the model:
_h]ooLq^heodan$ik`aho*Ik`ah%6
j]ia9ik`aho*?d]nBeah`$i]t[hajcpd9/,%
]``naoo9ik`aho*?d]nBeah`$i]t[hajcpd91,%
_epu9ik`aho*?d]nBeah`$i]t[hajcpd92,%
op]pa[lnkrej_a9ik`aho*?d]nBeah`$i]t[hajcpd9/,%
_kqjpnu9ik`aho*?d]nBeah`$i]t[hajcpd91,%
sa^oepa9ik`aho*QNHBeah`$%
`ab[[qje_k`a[[$oahb%6
napqnjoahb*j]ia
_h]ooIap]6
kn`anejc9W#j]ia#Y
Here, we’ve introduced a new concept: the _h]ooIap], which is a class that’s embedded
within the Lq^heodan class definition (it’s indented to be within _h]ooLq^heodan). You can use
this Iap] class on any model to specify various model-specific options. A full reference of Iap]
options is available in Appendix B, but for now, we’re concerned with the kn`anejc option.
If you specify this, it tells Django that unless an ordering is given explicitly with kn`an[^u$%,
all Lq^heodan objects should be ordered by the j]ia field whenever they’re retrieved with the
Django database API.
Chaining Lookups
You’ve seen how you can filter data, and you’ve seen how you can order it. You’ll often need to
do both, of course. In these cases, you simply “chain” the lookups together:
:::Lq^heodan*k^fa_po*behpan$_kqjpnu9Q*O*=*%*kn`an[^u$)j]ia%
W8Lq^heodan6K#Naehhu:(8Lq^heodan6=lnaoo:Y
As you might expect, this translates to an SQL query with both a SDANA and an KN@AN>U:
OAHA?Pe`(j]ia(]``naoo(_epu(op]pa[lnkrej_a(_kqjpnu(sa^oepa
BNKI^kkgo[lq^heodan
SDANA_kqjpnu9#Q*O*=#
KN@AN>Uj]ia@AO?7
CHAPTER 5 N MODELS
92
Slicing Data
Another common need is to look up only a fixed number of rows. Imagine that you have thou-
sands of publishers in your database, but you want to display only the first one. You can do
this using Python’s standard list-slicing syntax:
:::Lq^heodan*k^fa_po*kn`an[^u$#j]ia#%W,Y
8Lq^heodan6=lnaoo:
This translates roughly to:
OAHA?Pe`(j]ia(]``naoo(_epu(op]pa[lnkrej_a(_kqjpnu(sa^oepa
BNKI^kkgo[lq^heodan
KN@AN>Uj]ia
HEIEP-7
Similarly, you can retrieve a specific subset of data using Python’s range-slicing syntax:
:::Lq^heodan*k^fa_po*kn`an[^u$#j]ia#%W,6.Y
This returns two objects, translating roughly to the following:
OAHA?Pe`(j]ia(]``naoo(_epu(op]pa[lnkrej_a(_kqjpnu(sa^oepa
BNKI^kkgo[lq^heodan
KN@AN>Uj]ia
KBBOAP,HEIEP.7
Note that negative slicing is not supported:
:::Lq^heodan*k^fa_po*kn`an[^u$#j]ia#%W)-Y
Pn]_a^]_g$ikopna_ajp_]hhh]op%6
***
=ooanpekjAnnkn6Jac]peraej`atejceojkpoqllknpa`*
This is easy to get around, though. Just change the kn`an[^u$% statement like this:
:::Lq^heodan*k^fa_po*kn`an[^u$#)j]ia#%W,Y
Updating Multiple Objects in One Statement
We pointed out in the “Inserting and Updating Data” section that the model o]ra$% method
updates all columns in a row. Depending on your application, you might want to update only
a subset of columns.
For example, suppose that you want to update the Apress Lq^heodan to change the name
from #=lnaoo# to #=lnaooLq^heodejc#. Using o]ra$%, it would look something like this:
:::l9Lq^heodan*k^fa_po*cap$j]ia9#=lnaoo#%
:::l*j]ia9#=lnaooLq^heodejc#
:::l*o]ra$%
CHAPTER 5 N MODELS 93
This roughly translates to the following SQL:
OAHA?Pe`(j]ia(]``naoo(_epu(op]pa[lnkrej_a(_kqjpnu(sa^oepa
BNKI^kkgo[lq^heodan
SDANAj]ia9#=lnaoo#7
QL@=PA^kkgo[lq^heodanOAP
j]ia9#=lnaooLq^heodejc#(
]``naoo9#.411Pahacn]ld=ra*#(
_epu9#>angahau#(
op]pa[lnkrej_a9#?=#(
_kqjpnu9#Q*O*=*#(
sa^oepa9#dppl6++sss*]lnaoo*_ki#
SDANAe`91.7
NNote This example assumes that Apress has a publisher ID of 1..
You can see in this example that Django’s o]ra$% method sets all the column values, not
just the j]ia column. If you’re in an environment in which other columns of the database
might change because of some other process, it’s smarter to change only the column you need
to change. To do this, use the ql`]pa$% method on MqanuOap objects. Here’s an example:
:::Lq^heodan*k^fa_po*behpan$e`91.%*ql`]pa$j]ia9#=lnaooLq^heodejc#%
The SQL translation here is much more efficient and has no chance of race conditions:
QL@=PA^kkgo[lq^heodan
OAPj]ia9#=lnaooLq^heodejc#
SDANAe`91.7
The ql`]pa$% method works on any MqanuOap, which means that you can edit multiple
records in bulk. Here’s how you might change the _kqjpnu from #Q*O*=*# to QO= in each
Lq^heodan record:
:::Lq^heodan*k^fa_po*]hh$%*ql`]pa$_kqjpnu9#QO=#%
.
The ql`]pa$% method has a return value: an integer that represents how many records
changed. In the preceding example, it was ..
Deleting Objects
To delete an object from your database, simply call the object’s `ahapa$% method:
:::l9Lq^heodan*k^fa_po*cap$j]ia9K#Naehhu%
:::l*`ahapa$%
:::Lq^heodan*k^fa_po*]hh$%
W8Lq^heodan6=lnaooLq^heodejc:Y
CHAPTER 5 N MODELS
94
You can also delete objects in bulk by calling `ahapa$% on the result of any MqanuOap. This
is similar to the ql`]pa$% method shown in the last section:
:::Lq^heodan*k^fa_po*behpan$_kqjpnu9#QO=#%*`ahapa$%
:::Lq^heodan*k^fa_po*]hh$%*`ahapa$%
:::Lq^heodan*k^fa_po*]hh$%
WY
Be careful when deleting your data! As a precaution against deleting all the data in a par-
ticular table, Django requires you to explicitly use ]hh$% if you want to delete everything in
your table.
For example, this doesn’t work:
:::Lq^heodan*k^fa_po*`ahapa$%
Pn]_a^]_g$ikopna_ajp_]hhh]op%6
Beha8_kjokha:(heja-(ej8ik`qha:
=ppne^qpaAnnkn6#I]j]can#k^fa_pd]ojk]ppne^qpa#`ahapa#
But it does work if you add the ]hh$% method:
:::Lq^heodan*k^fa_po*]hh$%*`ahapa$%
If you’re just deleting a subset of your data, you don’t need to include ]hh$%. To repeat a
previous example:
:::Lq^heodan*k^fa_po*behpan$_kqjpnu9#QO=#%*`ahapa$%
What's Next?
After reading this chapter, you now have enough knowledge of Django models to be able
to write basic database applications. Chapter 10 will provide some information on more
advanced usage of Django’s database layer.
Once you’ve defined your models, the next step is to populate your database with data.
You might have legacy data, in which case Chapter 18 will give you advice about integrating
with legacy databases. You might rely on site users to supply your data, in which case Chapter 7
will teach you how to process user-submitted form data.
But in some cases, you or your team might need to enter data manually, in which case
it would be helpful to have a Web-based interface for entering and managing data. The next
chapter covers Django’s admin interface, which exists precisely for that reason.
CHAPTER 6
The Django Admin Site
For a certain class of Web sites, an admin interface is an essential part of the infrastructure.
This is a Web-based interface, limited to trusted site administrators, that enables the adding,
editing, and deletion of site content. Some common examples are: the interface you use to
post to your blog, the back-end site managers use to moderate user-generated comments,
the tool your clients use to update the press releases on the Web site you built for them.
There’s a problem with admin interfaces, though: it’s boring to build them. Web develop-
ment is fun when you’re developing public-facing functionality, but building admin interfaces
is always the same. You have to authenticate users, display and handle forms, validate input,
and so on. It’s boring and it’s repetitive.
So what’s Django’s approach to these boring, repetitive tasks? It does it all for you—in
just a couple of lines of code, no less. With Django, building an admin interface is a solved
problem.
This chapter is about Django’s automatic admin interface. The feature works by read-
ing metadata in your model to provide a powerful and production-ready interface that site
administrators can start using immediately. We discuss how to activate, use, and customize
this feature.
Note that we recommend reading this chapter even if you don’t intend to use the Django
admin site, because we introduce a few concepts that apply to all of Django, regardless of
admin-site usage.
The django.contrib Packages
Django’s automatic admin is part of a larger suite of Django functionality called `f]jck*
_kjpne^—the part of the Django codebase that contains various useful add-ons to the core
framework. You can think of `f]jck*_kjpne^ as Django’s equivalent of the Python standard
library—optional, de facto implementations of common patterns. They’re bundled with
Django so that you don’t have to reinvent the wheel in your own applications.
The admin site is the first part of `f]jck*_kjpne^ that we’re covering in this book; techni-
cally, it’s called `f]jck*_kjpne^*]`iej. Other available features in `f]jck*_kjpne^ include a
user-authentication system (`f]jck*_kjpne^*]qpd), support for anonymous sessions (`f]jck*
_kjpne^*oaooekjo), and even a system for user comments (`f]jck*_kjpne^*_kiiajpo). You’ll get
95
CHAPTER 6 N THE DJANGO ADMIN SITE
96
to know the various `f]jck*_kjpne^ features as you become a Django expert, and we’ll spend
some more time discussing them in Chapter 16. For now, just know that Django ships with
many nice add-ons, and `f]jck*_kjpne^ is generally where they live.
Activating the Admin Interface
The Django admin site is entirely optional, because only certain types of sites need this func-
tionality. That means you’ll need to take a few steps to activate it in your project.
First, make a few changes to your settings file:
1. Add #`f]jck*_kjpne^*]`iej# to the EJOP=HHA@[=LLO setting. (The order of EJOP=HHA@[
=LLO doesn’t matter, but we like to keep things alphabetical so it’s easy for a human
to read.)
2. Make sure EJOP=HHA@[=LLO contains #`f]jck*_kjpne^*]qpd#, #`f]jck*_kjpne^*
_kjpajppulao#, and #`f]jck*_kjpne^*oaooekjo#. The Django admin site requires
these three packages. (If you’re following along with our ongoing iuoepa project, note
that we commented out these three EJOP=HHA@[=LLO entries in Chapter 5. Uncomment
them now.)
3. Make sure IE@@HAS=NA[?H=OOAO contains #`f]jck*ie``has]na*_kiikj*?kiikjIe``has]na#,
#`f]jck*_kjpne^*oaooekjo*ie``has]na*OaooekjIe``has]na#, and #`f]jck*_kjpne^*
]qpd*ie``has]na*=qpdajpe_]pekjIe``has]na#. (Again, if you’re following along, note
that we commented them out in Chapter 5, so uncomment them.)
Second, run lupdkji]j]ca*luouj_`^. This step will install the extra database tables
that the admin interface uses. The first time you run ouj_`^ with #`f]jck*_kjpne^*]qpd# in
EJOP=HHA@[=LLO, you’ll be asked about creating a superuser. If you don’t do this, you’ll need
to run lupdkji]j]ca*lu_na]paoqlanqoan separately to create an admin user account; oth-
erwise you won’t be able to log in to the admin site. (Potential gotcha: the lupdkji]j]ca*lu
_na]paoqlanqoan command is available only if #`f]jck*_kjpne^*]qpd# is in your EJOP=HHA@[
=LLO.)
Third, add the admin site to your URLconf (in qnho*lu, remember). By default, the qnho*lu
generated by `f]jck)]`iej*luop]nplnkfa_p contains commented-out code for the Django
admin, and all you have to do is uncomment it. For the record, here are the bits you need to
make sure are in there:
Ej_hq`apdaoaeilknpop]paiajpo***
bnki`f]jck*_kjpne^eilknp]`iej
]`iej*]qpk`eo_kran$%
=j`ej_hq`apdeoQNHl]ppanj***
qnhl]ppanjo9l]ppanjo$##(
***
$n#Z]`iej+#(ej_hq`a$]`iej*oepa*qnho%%(
***
%
CHAPTER 6 N THE DJANGO ADMIN SITE 97
With that bit of configuration out of the way, now you can see the Django admin site in
action. Just run the development server (lupdkji]j]ca*lunqjoanran, as in previous chapters)
and visit dppl6++-.3*,*,*-64,,,+]`iej+ in your Web browser.
Using the Admin Site
The admin site is designed to be used by nontechnical users, and as such it should be pretty
self-explanatory. Nevertheless, we’ll give you a quick walkthrough of the basic features.
The first thing you’ll see is a login screen, as shown in Figure 6-1.
Figure 6-1. Django’s login screen
Log in with the username and password you set up when you added your superuser. If
you’re unable to log in, make sure you’ve actually created a superuser—try running lupdkj
i]j]ca*lu_na]paoqlanqoan.
Once you’re logged in, the first thing you’ll see will be the admin home page (Figure 6-2).
This page lists all the available types of data that can be edited on the admin site. At this point,
because we haven’t activated any of our own models yet, the list is sparse: it includes only
Groups and Users, which are the two default admin-editable models.
CHAPTER 6 N THE DJANGO ADMIN SITE
98
Figure 6-2. The Django admin home page
Each type of data in the Django admin site has a change list and an edit form. Change lists
show you all the available objects in the database, and edit forms let you add, change, or delete
particular records in your database.
OTHER LANGUAGES
If your primary language is not English and your Web browser is configured to prefer a language other
than English, you can make a quick change to see whether the Django admin site has been translated into
your language. Just add #`f]jck*ie``has]na*hk_]ha*Hk_]haIe``has]na# to your IE@@HAS=NA[
?H=OOAO setting, making sure it appears after #`f]jck*_kjpne^*oaooekjo*ie``has]na*
OaooekjIe``has]na#.
When you’ve done that, reload the admin index page. If a translation for your language is available, then
the various parts of the interface—from the Change Password and Log Out links at the top of the page to the
Groups and Users links in the middle—will appear in your language instead of English. Django ships with
translations for dozens of languages.
For much more on Django’s internationalization features, see Chapter 19.
CHAPTER 6 N THE DJANGO ADMIN SITE 99
Click the Change link in the Users row to load the change-list page for users (Figure 6-3).
Figure 6-3. The user change-list page
This page displays all users in the database; you can think of it as a prettied-up Web
version of a OAHA?P&BNKI]qpd[qoan7 SQL query. If you’re following along with our ongo-
ing example, you’ll see only one user here, assuming you’ve added only one, but once you
have more users, you’ll probably find the filtering, sorting, and searching options useful.
Filtering options are at the right, sorting is available by clicking a column header, and the
search box at the top lets you search by username.
Click the username of the user you created, and you’ll see the edit form for that user
(Figure 6-4).
CHAPTER 6 N THE DJANGO ADMIN SITE
100
Figure 6-4. The user edit form
This page lets you change the attributes of the user, like the first/last names and various
permissions. (Note that to change a user’s password, you should click Change Password Form
under the password field rather than editing the hashed code.) Another thing to note here is
that fields of different types get different widgets—for example, date/time fields have calendar
controls, Boolean fields have check boxes, and character fields have simple text input fields.
You can delete a record by clicking the Delete button at the bottom left of the record’s edit
form. That’ll take you to a confirmation page, which, in some cases, will display any depen-
dent objects that will be deleted, too. (For example, if you delete a publisher, any book with
that publisher will be deleted, as well!)
You can add a record by clicking Add in the appropriate column of the admin home page.
This will give you an empty version of the edit page, ready for you to fill out.
You’ll notice that the admin interface handles input validation for you. Try leaving a
required field blank or putting an invalid date into a date field, and you’ll see those errors
when you try to save, as shown in Figure 6-5.
When you edit an existing object, you’ll notice a History link in the upper-right corner of
the window. Every change made through the admin interface is logged, and you can examine
this log by clicking the History link (see Figure 6-6).
CHAPTER 6 N THE DJANGO ADMIN SITE 101
Figure 6-5. An edit form displaying errors
Figure 6-6. An object history page
CHAPTER 6 N THE DJANGO ADMIN SITE
102
Adding Your Models to the Admin Site
There’s one crucial part we haven’t done yet. Let’s add our own models to the admin site so
we can add, change, and delete objects in our custom database tables using this nice interface.
We’ll continue the ^kkgo example from Chapter 5, where we defined three models: Lq^heodan,
=qpdkn, and >kkg.
Within the ^kkgo directory (iuoepa+^kkgo), create a file called ]`iej*lu, and type in the fol-
lowing lines of code:
bnki`f]jck*_kjpne^eilknp]`iej
bnkiiuoepa*^kkgo*ik`ahoeilknpLq^heodan(=qpdkn(>kkg
]`iej*oepa*naceopan$Lq^heodan%
]`iej*oepa*naceopan$=qpdkn%
]`iej*oepa*naceopan$>kkg%
This code tells the Django admin site to offer an interface for each of these models.
Once you’ve done that, go to your admin home page in your Web browser (dppl6++-.3*,*
,*-64,,,+]`iej+). You should see a Books section with links for Authors, Books, and Publish-
ers. (You might have to stop and start the nqjoanran for the changes to take effect.)
You now have a fully functional admin interface for each of those three models. That
was easy!
Take some time to add and change records, to populate your database with some data.
If you followed Chapter 5’s examples of creating Lq^heodan objects (and you didn’t delete
them), you’ll already see those records on the publisher change-list page.
One feature worth mentioning here is the admin site’s handling of foreign keys and many-
to-many relationships, both of which appear in the >kkg model. As a reminder, here’s what the
>kkg model looks like:
_h]oo>kkg$ik`aho*Ik`ah%6
pepha9ik`aho*?d]nBeah`$i]t[hajcpd9-,,%
]qpdkno9ik`aho*I]juPkI]juBeah`$=qpdkn%
lq^heodan9ik`aho*BknaecjGau$Lq^heodan%
lq^he_]pekj[`]pa9ik`aho*@]paBeah`$%
`ab[[qje_k`a[[$oahb%6
napqnjoahb*pepha
On the Django admin site’s Add Book page (dppl6++-.3*,*,*-64,,,+]`iej+^kkgo+^kkg+
]``+), the publisher (a BknaecjGau) is represented by a select box, and the ]qpdkno field (a
I]juPkI]juBeah`) is represented by a multiple-select box. Both fields sit next to a green plus
sign that lets you add related records of that type. For example, if you click the green plus sign
next to the Publisher field, you’ll get a pop-up window that lets you add a publisher. After you
successfully create the publisher in the pop-up, the Add Book form will be updated with the
newly created publisher. Slick.
CHAPTER 6 N THE DJANGO ADMIN SITE 103
How the Admin Site Works
Behind the scenes, how does the admin site work? It’s pretty straightforward.
When Django loads your URLconf from qnho*lu at server startup, it executes the ]`iej*
]qpk`eo_kran$% statement that we added as part of activating the admin. This function iterates
over your EJOP=HHA@[=LLO setting and looks for a file called ]`iej*lu in each installed app. If an
]`iej*lu exists in a given app, it executes the code in that file.
In the ]`iej*lu in our ^kkgo app, each call to ]`iej*oepa*naceopan$% simply registers the
given model with the admin. The admin site will display an edit/change interface for only
models that have been explicitly registered.
The app `f]jck*_kjpne^*]qpd includes its own ]`iej*lu, which is why Users and Groups
showed up automatically in the admin. Other `f]jck*_kjpne^ apps, such as `f]jck*_kjpne^*
na`ena_po, also add themselves to the admin, as do many third-party Django applications you
might download from the Web.
Beyond that, the Django admin site is just a Django application, with its own models,
templates, views, and URLpatterns. You add it to your application by hooking it into your
URLconf, just as you hook in your own views. You can inspect its templates, views, and URL-
patterns by poking around in `f]jck+_kjpne^+]`iej in your copy of the Django codebase—but
don’t be tempted to change anything directly in there, as there are plenty of hooks for you to
customize the way the admin site works. (If you do decide to poke around the Django admin
application, keep in mind it does some rather complicated things in reading metadata about
models, so it would probably take a good amount of time to read and understand the code.)
Making Fields Optional
After you play around with the admin site for a while, you’ll probably notice a limitation—
the edit forms require every field to be filled out, whereas in many cases you’d want certain
fields to be optional. Let’s say, for example, that we want our =qpdkn model’s ai]eh field to be
optional—that is, a blank string should be allowed. In the real world, you might not have an
e-mail address on file for every author.
To specify that the ai]eh field is optional, edit the >kkg model (which, as you’ll recall from
Chapter 5, lives in iuoepa+^kkgo+ik`aho*lu). Simply add ^h]jg9Pnqa to the ai]eh field, like so:
_h]oo=qpdkn$ik`aho*Ik`ah%6
benop[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd9/,%
h]op[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd90,%
ai]eh9ik`aho*Ai]ehBeah`$^h]jg9Pnqa%
This tells Django that a blank value is indeed allowed for authors’ e-mail addresses.
By default, all fields have ^h]jg9B]hoa, which means blank values are not allowed.
There’s something interesting happening here. Until now, with the exception of the [[
qje_k`a[[$% method, our models have served as definitions of our database tables—Pythonic
expressions of SQL ?NA=PAP=>HA statements, essentially. In adding ^h]jg9Pnqa, we have begun
expanding our model beyond a simple definition of what the database table looks like. Now
our model class is starting to become a richer collection of knowledge about what =qpdkn
objects are and what they can do. Not only is the ai]eh field represented by a R=N?D=N column
in the database, it’s also an optional field in contexts such as the Django admin site.
CHAPTER 6 N THE DJANGO ADMIN SITE
104
Once you’ve added that ^h]jg9Pnqa, reload the author edit form (dppl6++-.3*,*,*-6
4,,,+]`iej+^kkgo+]qpdkn+]``+), and you’ll notice the field’s label—Email—is no longer
bolded. This signifies it’s not a required field. You can now add authors without needing to
provide e-mail addresses; you won’t get the loud red “This field is required” message anymore
if the field is submitted empty.
Making Date and Numeric Fields Optional
A common gotcha related to ^h]jg9Pnqa has to do with date and numeric fields, but it requires
a fair amount of background explanation.
SQL has its own way of specifying blank values—a special value called JQHH. JQHH could
mean “unknown,” or “invalid,” or some other application-specific meaning. In SQL, a value of
JQHH is different from an empty string, just as the special Python object Jkja is different from
an empty Python string (). This means it’s possible for a particular character field (e.g., a
R=N?D=N column) to contain both JQHH values and empty string values.
This can cause unwanted ambiguity and confusion: “Why does this record have a JQHH but
this other one has an empty string? Is there a difference, or was the data just entered inconsis-
tently?” And “How do I get all the records that have a blank value—should I look for both JQHH
records and empty strings, or do I select only the ones with empty strings?”
To help avoid such ambiguity, Django’s automatically generated ?NA=PAP=>HA statements
(which were covered in Chapter 5) add an explicit JKPJQHH to each column definition. For
example, here’s the generated statement for our =qpdkn model, from Chapter 5:
?NA=PAP=>HA^kkgo[]qpdkn$
e`oane]hJKPJQHHLNEI=NUGAU(
benop[j]iar]n_d]n$/,%JKPJQHH(
h]op[j]iar]n_d]n$0,%JKPJQHH(
ai]ehr]n_d]n$31%JKPJQHH
%
7
In most cases, this default behavior is optimal for your application and will save you
from data-inconsistency headaches. And it works nicely with the rest of Django, such as the
Django admin site, which inserts an empty string (not a JQHH value) when you leave a char-
acter field blank.
But there’s an exception with database column types that do not accept empty strings as
valid values—such as dates, times, and numbers. If you try to insert an empty string into a date
or an integer column, you’ll likely get a database error, depending on which database you’re
using. (PostgreSQL, which is strict, will raise an exception here; MySQL might accept it or
might not, depending on the version you’re using, the time of day, and the phase of the moon.)
In this case, JQHH is the only way to specify an empty value. In Django models, you can specify
that JQHH is allowed by adding jqhh9Pnqa to a field.
In short, if you want to allow blank values in a date field (e.g., @]paBeah`, PeiaBeah`,
@]paPeiaBeah`) or numeric field (e.g., EjpacanBeah`, @a_ei]hBeah`, Bhk]pBeah`), you’ll need to
use both jqhh9Pnqa and ^h]jg9Pnqa.
CHAPTER 6 N THE DJANGO ADMIN SITE 105
For the sake of example, let’s change our >kkg model to allow a blank lq^he_]pekj[`]pa.
Here’s the revised code:
_h]oo>kkg$ik`aho*Ik`ah%6
pepha9ik`aho*?d]nBeah`$i]t[hajcpd9-,,%
]qpdkno9ik`aho*I]juPkI]juBeah`$=qpdkn%
lq^heodan9ik`aho*BknaecjGau$Lq^heodan%
lq^he_]pekj[`]pa9ik`aho*@]paBeah`$^h]jg9Pnqa(jqhh9Pnqa%
Adding jqhh9Pnqa is more complicated than adding ^h]jg9Pnqa, because jqhh9Pnqa
changes the semantics of the database—that is, it changes the ?NA=PAP=>HA statement to
remove the JKPJQHH from the lq^he_]pekj[`]pa field. To complete this change, we’ll need to
update the database.
For a number of reasons, Django does not attempt to automate changes to database
schemas, so it’s your own responsibility to execute the appropriate =HPANP=>HA statement
whenever you make such a change to a model. Recall that you can use i]j]ca*lu`^odahh to
enter your database server’s shell. Here’s how to remove the JKPJQHH in this particular case:
=HPANP=>HA^kkgo[^kkg=HPAN?KHQIJlq^he_]pekj[`]pa@NKLJKPJQHH7
(Note that this SQL syntax is specific to PostgreSQL.) We’ll cover schema changes in more
depth in Chapter 10.
Bringing this back to the admin site, now the Add Book edit form should allow for empty
publication-date values.
Customizing Field Labels
On the admin site’s edit forms, each field’s label is generated from its model field name. The
algorithm is simple: Django just replaces underscores with spaces and capitalizes the first char-
acter, so, for example, the >kkg model’s lq^he_]pekj[`]pa field has the label Publication Date.
However, field names don’t always lend themselves to nice admin field labels, so in some
cases you might want to customize a label. You can do this by specifying ran^koa[j]ia in the
appropriate model field.
For example, here’s how we can change the label of the =qpdkn*ai]eh field to “e-mail,”
with a hyphen:
_h]oo=qpdkn$ik`aho*Ik`ah%6
benop[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd9/,%
h]op[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd90,%
ai]eh9ik`aho*Ai]ehBeah`$^h]jg9Pnqa(ran^koa[j]ia9#a)i]eh#%
Make that change and reload the server, and you should see the field’s new label on the
author edit form.
Note that you shouldn’t capitalize the first letter of a ran^koa[j]ia unless it should always
be capitalized (e.g., QO=op]pa). Django will automatically capitalize it when it needs to, and
it will use the exact ran^koa[j]ia value in places that don’t require capitalization.
CHAPTER 6 N THE DJANGO ADMIN SITE
106
Finally, note that you can pass the ran^koa[j]ia as a positional argument, for a slightly
more compact syntax. This example is equivalent to the previous one:
_h]oo=qpdkn$ik`aho*Ik`ah%6
benop[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd9/,%
h]op[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd90,%
ai]eh9ik`aho*Ai]ehBeah`$#a)i]eh#(^h]jg9Pnqa%
This won’t work with I]juPkI]juBeah` or BknaecjGau fields, though, because they require
the first argument to be a model class. In those cases, specifying ran^koa[j]ia explicitly is the
way to go.
Custom ModelAdmin Classes
The changes we’ve made so far—^h]jg9Pnqa, jqhh9Pnqa, and ran^koa[j]ia—are really
model-level changes, not admin-level changes. That is, these changes are fundamentally a
part of the model and just so happen to be used by the admin site; there’s nothing admin-
specific about them.
Beyond these, the Django admin site offers a wealth of options that let you customize how
the admin site works for a particular model. Such options live in Ik`ah=`iej classes, which are
classes that contain configuration for a specific model in a specific admin site instance.
Customizing Change Lists
Let’s dive into admin customization by specifying the fields that are displayed on the change
list for our =qpdkn model. By default, the change list displays the result of [[qje_k`a[[$% for
each object. In Chapter 5 we defined the [[qje_k`a[[$% method for =qpdkn objects to display
the first name and last name together:
_h]oo=qpdkn$ik`aho*Ik`ah%6
benop[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd9/,%
h]op[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd90,%
ai]eh9ik`aho*Ai]ehBeah`$^h]jg9Pnqa(ran^koa[j]ia9#a)i]eh#%
`ab[[qje_k`a[[$oahb%6
napqnjq#!o!o#!$oahb*benop[j]ia(oahb*h]op[j]ia%
As a result, the change list for =qpdkn objects displays each author’s first name and last
name together, as you can see in Figure 6-7.
CHAPTER 6 N THE DJANGO ADMIN SITE 107
Figure 6-7. The author change-list page
We can improve on this default behavior by adding a few other fields to the change-list
display. It’d be handy, for example, to see each author’s e-mail address in this list, and it’d be
nice to be able to sort by first and last name.
To make this happen, we’ll define a Ik`ah=`iej class for the =qpdkn model. This class is the
key to customizing the admin, and one of the most basic things it lets you do is specify the list
of fields to display on change-list pages. Edit ]`iej*lu to make these changes:
bnki`f]jck*_kjpne^eilknp]`iej
bnkiiuoepa*^kkgo*ik`ahoeilknpLq^heodan(=qpdkn(>kkg
_h]oo=qpdkn=`iej$]`iej*Ik`ah=`iej%6
heop[`eolh]u9$#benop[j]ia#(#h]op[j]ia#(#ai]eh#%
]`iej*oepa*naceopan$Lq^heodan%
]`iej*oepa*naceopan$=qpdkn(=qpdkn=`iej%
]`iej*oepa*naceopan$>kkg%
CHAPTER 6 N THE DJANGO ADMIN SITE
108
Here’s what we’ve done:
Ê UÊ 7iÊVÀi>Ìi`ÊÌiÊV>ÃÃÊ=qpdkn=`iej. This class, which subclasses `f]jck*_kjpne^*]`iej*
Ik`ah=`iej, holds custom configuration for a specific admin model. We’ve specified
only one customization—heop[`eolh]u, which is set to a tuple of field names to display
on the change-list page. These field names must exist in the model, of course.
Ê UÊ 7iÊ>ÌiÀi`ÊÌiÊ]`iej*oepa*naceopan$% call to add =qpdkn=`iej after =qpdkn. You can
read this as “Register the =qpdkn model with the =qpdkn=`iej options.”
The ]`iej*oepa*naceopan$% function takes a Ik`ah=`iej subclass as an optional second
argument. If you don’t specify a second argument (as is the case for Lq^heodan and
>kkg), Django will use the default admin options for that model.
With that tweak made, reload the author change-list page, and you’ll see it’s now display-
ing three columns—the first name, last name, and e-mail address. In addition, each of those
columns is sortable by clicking on the column header. (See Figure 6-8.)
Figure 6-8. The author change-list page after list_display
CHAPTER 6 N THE DJANGO ADMIN SITE 109
Next let’s add a simple search bar. Add oa]n_d[beah`o to =qpdkn=`iej, like so:
_h]oo=qpdkn=`iej$]`iej*Ik`ah=`iej%6
heop[`eolh]u9$#benop[j]ia#(#h]op[j]ia#(#ai]eh#%
oa]n_d[beah`o9$#benop[j]ia#(#h]op[j]ia#%
Reload the page in your browser, and you should see a search bar at the top. (See Figure 6-9.)
We’ve just told the admin change-list page to include a search bar that searches against the
benop[j]ia and h]op[j]ia fields. As a user might expect, this is case insensitive and searches
both fields, so searching for the string ^]n would find both an author with the first name
Barney and an author with the last name Hobarson.
Figure 6-9. The author change-list page after search_fields
Next let’s add some date filters to our >kkg model’s change-list page:
bnki`f]jck*_kjpne^eilknp]`iej
bnkiiuoepa*^kkgo*ik`ahoeilknpLq^heodan(=qpdkn(>kkg
_h]oo=qpdkn=`iej$]`iej*Ik`ah=`iej%6
heop[`eolh]u9$#benop[j]ia#(#h]op[j]ia#(#ai]eh#%
oa]n_d[beah`o9$#benop[j]ia#(#h]op[j]ia#%
CHAPTER 6 N THE DJANGO ADMIN SITE
110
_h]oo>kkg=`iej$]`iej*Ik`ah=`iej%6
heop[`eolh]u9$#pepha#(#lq^heodan#(#lq^he_]pekj[`]pa#%
heop[behpan9$#lq^he_]pekj[`]pa#(%
]`iej*oepa*naceopan$Lq^heodan%
]`iej*oepa*naceopan$=qpdkn(=qpdkn=`iej%
]`iej*oepa*naceopan$>kkg(>kkg=`iej%
Here, because we’re dealing with a different set of options, we created a separate
Ik`ah=`iej class—>kkg=`iej. First we defined a heop[`eolh]u just to make the change list
look a bit nicer. Then we used heop[behpan, which is set to a tuple of fields to use to create
filters along the right side of the change-list page. For date fields, Django provides short-
cuts to filter the list to “Today,” “Past 7 days,” “This month,” and “This year”—shortcuts
that Django’s developers have found hit the common cases for filtering by date. Figure 6-10
shows what that looks like.
Figure 6-10. The book change-list page after list_filter
heop[behpan also works on fields of other types, not just @]paBeah`. (Try it with
>kkha]jBeah` and BknaecjGau fields, for example.) The filters show up as long as there
are at least two values to choose from.
CHAPTER 6 N THE DJANGO ADMIN SITE 111
Another way to offer date filters is to use the `]pa[dean]n_du admin option, like this:
_h]oo>kkg=`iej$]`iej*Ik`ah=`iej%6
heop[`eolh]u9$#pepha#(#lq^heodan#(#lq^he_]pekj[`]pa#%
heop[behpan9$#lq^he_]pekj[`]pa#(%
`]pa[dean]n_du9#lq^he_]pekj[`]pa#
With this in place, the change-list page gets a date drill-down navigation bar at the top
of the list, as shown in Figure 6-11. It starts with a list of available years, then drills down into
months and individual days.
Figure 6-11. The book change-list page after date_hierarchy
Note that `]pa[dean]n_du takes a string, not a tuple, because only one date field can be
used to make the hierarchy.
Finally, let’s change the default ordering so that books on the change-list page are always
ordered descending by their publication date. By default, the change list orders objects
according to their model’s kn`anejc within _h]ooIap] (which we covered in Chapter 5)—but if
you haven’t specified this kn`anejc value, then the ordering is undefined.
_h]oo>kkg=`iej$]`iej*Ik`ah=`iej%6
heop[`eolh]u9$#pepha#(#lq^heodan#(#lq^he_]pekj[`]pa#%
heop[behpan9$#lq^he_]pekj[`]pa#(%
`]pa[dean]n_du9#lq^he_]pekj[`]pa#
kn`anejc9$#)lq^he_]pekj[`]pa#(%
CHAPTER 6 N THE DJANGO ADMIN SITE
112
This admin kn`anejc option works exactly as the kn`anejc in a model’s _h]ooIap], except
that it uses only the first field name in the list. Just pass a list or tuple of field names, and add a
minus sign to a field to use descending sort order.
Reload the book change list to see this in action. Note that the Publication Date header
now includes a small arrow that indicates which way the records are sorted. (See Figure 6-12.)
Figure 6-12. The book change-list page after ordering
We’ve covered the main change-list options here. Using these options, you can make a
very powerful, production-ready, data-editing interface with only a few lines of code.
Customizing Edit Forms
Just as the change list can be customized, edit forms can be customized in many ways.
First, let’s customize the way fields are ordered. By default, the order of fields in an edit
form corresponds to the order in which they’re defined in the model. We can change that
using the beah`o option in our Ik`ah=`iej subclass:
CHAPTER 6 N THE DJANGO ADMIN SITE 113
_h]oo>kkg=`iej$]`iej*Ik`ah=`iej%6
heop[`eolh]u9$#pepha#(#lq^heodan#(#lq^he_]pekj[`]pa#%
heop[behpan9$#lq^he_]pekj[`]pa#(%
`]pa[dean]n_du9#lq^he_]pekj[`]pa#
kn`anejc9$#)lq^he_]pekj[`]pa#(%
beah`o9$#pepha#(#]qpdkno#(#lq^heodan#(#lq^he_]pekj[`]pa#%
After this change, the edit form for books will use the given ordering for fields. It’s slightly
more natural to have the authors after the book title. Of course, the field order should depend
on your data-entry workflow. Every form is different.
Another useful thing the beah`o option lets you do is to exclude certain fields from being
edited. Just leave out the field(s) you want to exclude. You might use this if your admin users
are trusted to edit only a certain segment of your data, or if parts of your fields are changed by
some outside, automated process. For example, in our book database, we could prevent the
lq^he_]pekj[`]pa field from being editable:
_h]oo>kkg=`iej$]`iej*Ik`ah=`iej%6
heop[`eolh]u9$#pepha#(#lq^heodan#(#lq^he_]pekj[`]pa#%
heop[behpan9$#lq^he_]pekj[`]pa#(%
`]pa[dean]n_du9#lq^he_]pekj[`]pa#
kn`anejc9$#)lq^he_]pekj[`]pa#(%
beah`o9$#pepha#(#]qpdkno#(#lq^heodan#%
As a result, the edit form for books doesn’t offer a way to specify the publication date. This
could be useful if, say, you’re an editor who prefers that his authors not push back publication
dates. (This is purely a hypothetical example, of course.)
When a user employs this incomplete form to add a new book, Django will simply set the
lq^he_]pekj[`]pa to Jkja—so make sure that field has jqhh9Pnqa.
Another commonly used edit-form customization has to do with many-to-many fields.
As we’ve seen on the edit form for books, the admin site represents each I]juPkI]juBeah` as
a multiple-select box, which is the most logical HTML input widget to utilize—but multiple-
select boxes can be difficult to use. If you want to select multiple items, you have to hold down
the Control key, or Command on a Mac. The admin site helpfully inserts a bit of text that
explains this, but, still, it gets unwieldy when your field contains hundreds of options.
The admin site’s solution is behpan[dknevkjp]h. Let’s add that to >kkg=`iej and see what
it does.
_h]oo>kkg=`iej$]`iej*Ik`ah=`iej%6
heop[`eolh]u9$#pepha#(#lq^heodan#(#lq^he_]pekj[`]pa#%
heop[behpan9$#lq^he_]pekj[`]pa#(%
`]pa[dean]n_du9#lq^he_]pekj[`]pa#
kn`anejc9$#)lq^he_]pekj[`]pa#(%
behpan[dknevkjp]h9$#]qpdkno#(%
(If you’re following along, note that we’ve also removed the beah`o option to restore all the
fields in the edit form.)
CHAPTER 6 N THE DJANGO ADMIN SITE
114
Reload the edit form for books, and you’ll see that the Authors section now uses a fancy
JavaScript filter interface that lets you search through the options dynamically and move spe-
cific authors from Available Authors to the Chosen Authors box, and vice versa.
Figure 6-13. The book edit form after adding filter_horizontal
We’d highly recommend using behpan[dknevkjp]h for any I]juPkI]juBeah` that has more
than ten items. It’s far easier to use than a simple multiple-select widget. Also, note you can
use behpan[dknevkjp]h for multiple fields—just specify each name in the tuple.
Ik`ah=`iej classes also support a behpan[ranpe_]h option. This works exactly as behpan[
dknevkjp]h, but the resulting JavaScript interface stacks the two boxes vertically instead of
horizontally. It’s a matter of personal taste.
behpan[dknevkjp]h and behpan[ranpe_]h work on only I]juPkI]juBeah` fields, not
BknaecjGau fields. By default, the admin site uses simple 8oaha_p: boxes for BknaecjGau fields,
but, as for I]juPkI]juBeah`, sometimes you don’t want to incur the overhead of having to
select all the related objects to display in the drop-down. For example, if our book database
grows to include thousands of publishers, the Add Book form could take a while to load,
because it would have to load every publisher for display in the 8oaha_p: box.
CHAPTER 6 N THE DJANGO ADMIN SITE 115
You can fix this with an option called n]s[e`[beah`o. Set this to a tuple of BknaecjGau field
names, and those fields will be displayed in the admin with a simple text-input box (8ejlqp
pula9patp:) instead of a 8oaha_p:. See Figure 6-14.
_h]oo>kkg=`iej$]`iej*Ik`ah=`iej%6
heop[`eolh]u9$#pepha#(#lq^heodan#(#lq^he_]pekj[`]pa#%
heop[behpan9$#lq^he_]pekj[`]pa#(%
`]pa[dean]n_du9#lq^he_]pekj[`]pa#
kn`anejc9$#)lq^he_]pekj[`]pa#(%
behpan[dknevkjp]h9$#]qpdkno#(%
n]s[e`[beah`o9$#lq^heodan#(%
Figure 6-14. The book edit form after adding raw_id_fields
What do you enter in this input box? The database ID of the publisher. Given that humans
don’t normally memorize database IDs, there’s a magnifying-glass icon that you can click to
pull up a pop-up window from which you can select the publisher.
CHAPTER 6 N THE DJANGO ADMIN SITE
116
Users, Groups, and Permissions
Because you’re logged in as a superuser, you have access to create, edit, and delete any object.
Naturally, different environments require different permission systems—not everybody can or
should be a superuser. Django’s admin site uses a permissions system that you can use to give
specific users access to only the portions of the interface that they need.
These user accounts are meant to be generic enough to be used outside of the admin
interface, but we’ll just treat them as admin user accounts for now. In Chapter 14 we’ll cover
how to integrate user accounts with the rest of your site (i.e., not just the admin site).
You can edit users and permissions through the admin interface just like any other object.
We saw this earlier in this chapter, when we played around with the User and Group sections
of the admin. 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 Boolean flags:
Ê UÊ /iʺ>VÌÛi»Êv>} controls whether the user is active at all. If this flag is off and the user
tries to log in, he won’t be allowed in, even with a valid password.
Ê UÊ /iʺÃÌ>vv»Êv>} controls whether the user is allowed to log in to the admin interface
(i.e., whether that user is considered a “staff member” in your organization). Since this
same user system can be used to control access to public (i.e., nonadmin) sites—see
Chapter 14—this flag differentiates between public users and administrators.
Ê UÊ /iʺÃÕ«iÀÕÃiÀ»Êv>} gives the user full access to add, create, and delete any item in the
admin interface. If a user has this flag set, then all regular permissions (or lack thereof)
are ignored for that user.
“Normal” admin users—that is, active, nonsuperuser staff members—are granted admin
access through assigned permissions. Each object editable through the admin interface (e.g.,
books, authors, publishers) has three permissions: create, edit, and delete. Assigning permis-
sions to a user grants the user the associated level of access.
When you create a user, that user has no permissions; it’s up to you to assign specific
ones. For example, you can give a user permission to add and change publishers but not to
delete them. Note that these permissions are defined per model, not per object—so they let
you say, “John can make changes to any book,” but they don’t let you say, “John can make
changes to any book published by Apress.” Per-object permissions are a bit more complicated
and are outside the scope of this book (but are covered in the Django documentation).
NNote Access to edit users and permissions is also controlled by this permissions system. If you give
someone permission to edit users, she will be able to edit her own permissions, which might not be what you
want! Giving a user permission to edit other users is essentially turning a user into a superuser.
You can also assign users to groups. A group is simply a set of permissions to apply to
all members of that group. Groups are useful for granting identical permissions to a subset
of users.
CHAPTER 6 N THE DJANGO ADMIN SITE 117
When and Why to Use the Admin Interface—
And When Not To
After having worked through this chapter, you should have a good idea of how to use Django’s
admin site. But we want to make a point of covering when and why you might want to use it—
and when not to use it.
Django’s admin site especially shines when nontechnical users need to be able to enter
data; that’s the purpose behind the feature, after all. At the newspaper where Django was first
developed, creation of a typical online feature—say, a special report on water quality in the
municipal supply—would go something like this:
1. The reporter responsible for the project meets with one of the developers and describes
the available data.
2. The developer designs Django models to fit this data and then opens up the admin site
to the reporter.
3. The reporter inspects the admin site to point out any missing or extraneous fields—
better now than later. The developer changes the models iteratively.
4. When the models are agreed upon, the reporter begins entering data using the admin
site. At the same time, the programmer can focus on developing the publicly accessible
views/templates (the fun part!).
In other words, the raison d’être of Django’s admin interface is to facilitate the simultane-
ous work of content producers and programmers.
However, beyond these obvious data-entry tasks, the admin site is useful in a few
other cases:
ÊUÊInspecting data models: Once you’ve defined a few models, it can be quite useful to call
them up in the admin interface and enter some dummy data. In some cases, this might
reveal data-modeling mistakes or other problems with your models.
ÊUÊManaging acquired data: For applications that rely on data coming from external
sources (e.g., users or Web crawlers), the admin site gives you an easy way to inspect
or edit this data. You can think of it as a less powerful but more convenient version of
your database’s command-line utility.
ÊUÊQuick and dirty data-management apps: You can use the admin site to build a very
lightweight data-management app—say, to keep track of expenses. If you’re just build-
ing something for your own needs, not for public consumption, the admin site can take
you a long way. In this sense, you can think of it as a beefed-up, relational version of a
spreadsheet.
One final point we want to make clear is that the admin site is not an end-all-be-all.
Over the years, we’ve seen it hacked and chopped up to serve a variety of functions it wasn’t
intended to serve. It’s not intended to be a public interface to data, nor is it intended to
allow for sophisticated sorting and searching of your data. As we said early in this chapter,
it’s for trusted site administrators. Keeping this sweet spot in mind is the key to effective
admin-site usage.
CHAPTER 6 N THE DJANGO ADMIN SITE
118
What’s Next?
So far we’ve created a few models and configured a top-notch interface for editing data. In the
next chapter we’ll move on to the real “meat and potatoes” of Web development: form cre-
ation and processing.
CHAPTER 7
Forms
HTML forms are the backbone of interactive Web sites, from the simplicity of Google’s single
search box to ubiquitous blog comment-submission forms to complex custom data-entry
interfaces. This chapter covers how you can use Django to access user-submitted form data,
validate it, and do something with it. Along the way, we’ll cover DpplNamqaop and Bkni objects.
Getting Data from the Request Object
We introduced DpplNamqaop objects in Chapter 3 when we first covered view functions, but
we didn’t have much to say about them at the time. Recall that each view function takes an
DpplNamqaop object as its first parameter, as in our dahhk$% view:
bnki`f]jck*dppleilknpDpplNaolkjoa
`abdahhk$namqaop%6
napqnjDpplNaolkjoa$Dahhksknh`%
DpplNamqaop objects, such as the variable namqaop here, have a number of interesting attri-
butes and methods that you should familiarize yourself with so that you know what’s possible.
You can use these attributes to get information about the current request (i.e., the user/Web
browser that’s loading the current page on your Django-powered site) at the time the view
function is executed.
Information About the URL
DpplNamqaop objects contain several pieces of information about the currently requested URL,
as Table 7-1 shows.
119
CHAPTER 7 N FORMS
120
Table 7-1. HttpRequest Attributes and Methods
Attribute/Method Description Example
namqaop*l]pd The full path, not including the domain
but including the leading slash
+dahhk+
namqaop*cap[dkop$% The host (i.e., the “domain,” in common
parlance)
-.3*,*,*-64,,, or
sss*at]ilha*_ki
namqaop*cap[bqhh[l]pd$% The l]pd, plus a query string (if available) +dahhk+;lnejp9pnqa
namqaop*eo[oa_qna$% Pnqa if the request was made via HTTPS;
otherwise, B]hoa
Pnqa or B]hoa
Always use the attributes/methods outlined in Table 7-1 instead of hard-coding URLs in
your views. This makes for more flexible code that can be reused in other places. Here’s a sim-
plistic example:
>=@
`ab_qnnajp[qnh[reas[^]`$namqaop%6
napqnjDpplNaolkjoa$Sah_kiapkpdal]ca]p+_qnnajp+%
CKK@
`ab_qnnajp[qnh[reas[ckk`$namqaop%6
napqnjDpplNaolkjoa$Sah_kiapkpdal]ca]p!o!namqaop*l]pd%
Other Information About the Request
namqaop*IAP= is a Python dictionary containing all available HTTP headers for the given
request—including the user’s IP address and user agent (generally the name and version of the
Web browser). Note that the full list of available headers depends on which headers the user
sent and which headers your Web server sets. The following are some commonly available
keys in this dictionary:
ÊUÊDPPL[NABANAN: The referring URL, if any. (Note the misspelling of NABANAN.)
ÊUÊDPPL[QOAN[=CAJP: The user-agent string (if any) of the user’s browser. This looks some-
thing like the following:
Ikvehh]1*,$T--7Q7Hejqte242%Ca_gk+.,,4,4.5Benabkt+.*,*,*-3
ÊUÊNAIKPA[=@@N: The IP address of the client—for instance, -.*/01*23*45. (If the request
has passed through any proxies, then this might be a comma-separated list of IP
addresses, such as -.*/01*23*45(./*012*34*5,.)
CHAPTER 7 N FORMS 121
Note that because namqaop*IAP= is just a basic Python dictionary, you’ll get a GauAnnkn
exception if you try to access a key that doesn’t exist. (Because HTTP headers are external
data—that is, they’re submitted by your users’ browsers—they shouldn’t be trusted, and
you should always design your application to fail gracefully if a particular header is empty or
doesn’t exist.) You should either use a pnu/at_alp clause or the cap$% method to handle the
case of undefined keys, as in this example:
>=@
`abq][`eolh]u[^]`$namqaop%6
q]9namqaop*IAP=W#DPPL[QOAN[=CAJP#YIecdpn]eoaGauAnnkn
napqnjDpplNaolkjoa$Ukqn^nksoaneo!o!q]%
CKK@$RANOEKJ-%
`abq][`eolh]u[ckk`-$namqaop%6
pnu6
q]9namqaop*IAP=W#DPPL[QOAN[=CAJP#Y
at_alpGauAnnkn6
q]9#qjgjksj#
napqnjDpplNaolkjoa$Ukqn^nksoaneo!o!q]%
CKK@$RANOEKJ.%
`abq][`eolh]u[ckk`.$namqaop%6
q]9namqaop*IAP=*cap$#DPPL[QOAN[=CAJP#(#qjgjksj#%
napqnjDpplNaolkjoa$Ukqn^nksoaneo!o!q]%
We encourage you to write a small view that displays all of the namqaop*IAP= data so you
can get to know what’s available. Here’s what that view might look like:
`ab`eolh]u[iap]$namqaop%6
r]hqao9namqaop*IAP=*epaio$%
r]hqao*oknp$%
dpih9WY
bkng(rejr]hqao6
dpih*]llaj`$#8pn:8p`:!o8+p`:8p`:!o8+p`:8+pn:#!$g(r%%
napqnjDpplNaolkjoa$#8p]^ha:!o8+p]^ha:#!#Xj#*fkej$dpih%%
As an exercise, see whether you can convert this view to use Django’s template system
instead of hard-coding the HTML. Also try adding namqaop*l]pd and the other DpplNamqaop
methods from the previous section.
Information About Submitted Data
Beyond basic metadata about the request, DpplNamqaop objects have two attributes that
contain user-submitted information: namqaop*CAP and namqaop*LKOP. Both of these are diction-
ary-like objects that give you access to CAP and LKOP data.
LKOP data generally is submitted from an HTML 8bkni:, while CAP data can come from a
8bkni: or the query string in the page’s URL.
CHAPTER 7 N FORMS
122
DICTIONARY-LIKE OBJECTS
When we say namqaop*CAP and namqaop*LKOP are dictionary-like objects, we mean they behave like stan-
dard Python dictionaries but aren’t technically dictionaries under the hood. For example, namqaop*CAP and
namqaop*LKOP both have cap$%, gauo$%, and r]hqao$% methods, and you can iterate over the keys by
doing bkngauejnamqaop*CAP.
So why do we refer to these as “dictionary-like” objects as opposed to normal dictionaries? Because
both namqaop*CAP and namqaop*LKOP have additional methods that normal dictionaries don’t have.
You might have encountered the similar term “file-like objects”—Python objects that have a few basic
methods, such as na]`$%, that let them act as stand-ins for “real” file objects.
A Simple Form-Handling Example
Continuing this book’s ongoing example of books, authors, and publishers, let’s create a sim-
ple view that lets users search our book database by title.
Generally, there are two parts to developing a form: the HTML user interface and the
back-end view code that processes the submitted data. The first part is easy; let’s just set up a
view that displays a search form:
bnki`f]jck*odknp_qpoeilknpnaj`an[pk[naolkjoa
`aboa]n_d[bkni$namqaop%6
napqnjnaj`an[pk[naolkjoa$#oa]n_d[bkni*dpih#%
As you learned in Chapter 3, this view can live anywhere on your Python path. For this
example, put it in ^kkgo+reaso*lu.
The accompanying template, oa]n_d[bkni*dpih, could look like this:
8dpih:
8da]`:
8pepha:Oa]n_d8+pepha:
8+da]`:
8^k`u:
8bkni]_pekj9+oa]n_d+iapdk`9cap:
8ejlqppula9patpj]ia9m:
8ejlqppula9oq^iepr]hqa9Oa]n_d:
8+bkni:
8+^k`u:
8+dpih:
The URLpattern in qnho*lu could look like this:
bnkiiuoepa*^kkgoeilknpreaso
qnhl]ppanjo9l]ppanjo$##(
***
$n#Zoa]n_d)bkni+ #(reaso*oa]n_d[bkni%(
***
%
CHAPTER 7 N FORMS 123
Note that we’re importing the reaso module directly, instead of something like bnki
iuoepa*reasoeilknpoa]n_d[bkni, because the former is less verbose. We’ll cover this import-
ing approach in more detail in Chapter 8.
Now, if you run the nqjoanran and visit dppl6++-.3*,*,*-64,,,+oa]n_d)bkni+, you’ll see
the search interface. Simple enough.
Try submitting the form, though, and you’ll get a Django 404 error. The form points to the
URL +oa]n_d+, which hasn’t yet been implemented. Let’s fix that with a second view function:
qnho*lu
qnhl]ppanjo9l]ppanjo$##(
***
$n#Zoa]n_d)bkni+ #(reaso*oa]n_d[bkni%(
$n#Zoa]n_d+ #(reaso*oa]n_d%(
***
%
reaso*lu
`aboa]n_d$namqaop%6
eb#m#ejnamqaop*CAP6
iaoo]ca9#Ukqoa]n_da`bkn6!n#!namqaop*CAPW#m#Y
ahoa6
iaoo]ca9#Ukqoq^ieppa`]jailpubkni*#
napqnjDpplNaolkjoa$iaoo]ca%
For the moment, this merely displays the user’s search term so we can make sure the data
is being submitted to Django properly and so you can get a feel for how the search term flows
through the system. In short, here’s what happens:
1. The HTML 8bkni: defines a variable m. When it’s submitted, the value of m is sent via
CAP (iapdk`9cap) to the URL +oa]n_d+.
2. The Django view that handles the URL +oa]n_d+ (oa]n_d$%) has access to the m value in
namqaop*CAP.
Note that we explicitly check that #m# exists in namqaop*CAP. As we pointed out in the
namqaop*IAP= discussion earlier in this chapter, you shouldn’t trust anything submitted by
users or even assume that they’ve submitted anything in the first place. If we didn’t add this
check, any submission of an empty form would raise GauAnnkn in the view:
>=@
`ab^]`[oa]n_d$namqaop%6
Pdabkhhksejchejasehhn]eoaGauAnnkneb#m#d]oj#p
^aajoq^ieppa`
iaoo]ca9#Ukqoa]n_da`bkn6!n#!namqaop*CAPW#m#Y
napqnjDpplNaolkjoa$iaoo]ca%
CHAPTER 7 N FORMS
124
QUERY-STRING PARAMETERS
Because CAP data is passed in the query string (e.g., +oa]n_d+;m9`f]jck), you can use namqaop*CAP
to access query-string variables. In Chapter 3’s introduction of Django’s URLconf system, we compared
Django’s pretty URLs to more traditional PHP/Java URLs such as +peia+lhqo;dkqno9/ and said we’d show
you how to use the latter in Chapter 7. Now you know how to access query-string parameters in your views
(like dkqno9/ in this example)—use namqaop*CAP.
LKOP data works the same way as CAP data—just use namqaop*LKOP instead of namqaop*CAP.
What’s the difference between CAP and LKOP? Use CAP when the act of submitting the form is
just a request to “get” data. Use LKOP whenever the act of submitting the form will have some
side effect—changing data or sending an e-mail, or something else that’s beyond simple dis-
play of data. In our book-search example, we’re using CAP because the query doesn’t change
any data on our server. (See dppl6++sss*s/*knc+.,,-+p]c+`k_+sdajPkQoaCap*dpih if you want
to learn more about CAP and LKOP.)
Now that we’ve verified namqaop*CAP is being passed in properly, let’s hook the user’s
search query into our book database (again, in reaso*lu):
bnki`f]jck*dppleilknpDpplNaolkjoa
bnki`f]jck*odknp_qpoeilknpnaj`an[pk[naolkjoa
bnkiiuoepa*^kkgo*ik`ahoeilknp>kkg
`aboa]n_d$namqaop%6
eb#m#ejnamqaop*CAP]j`namqaop*CAPW#m#Y6
m9namqaop*CAPW#m#Y
^kkgo9>kkg*k^fa_po*behpan$pepha[[e_kjp]ejo9m%
napqnjnaj`an[pk[naolkjoa$#oa]n_d[naoqhpo*dpih#(
w#^kkgo#6^kkgo(#mqanu#6my%
ahoa6
napqnjDpplNaolkjoa$#Lha]oaoq^iep]oa]n_dpani*#%
Some notes on what we did here:
Ê UÊ Ê>``ÌÊÌÊViV}ÊÌ>ÌÊ#m# exists in namqaop*CAP, we made sure that namqaop*
CAPW#m#Y is a nonempty value before passing it to the database query.
Ê UÊ 7iÊÕÃi`Ê>kkg*k^fa_po*behpan$pepha[[e_kjp]ejo9m% to query our book table for all
books whose title includes the given submission. The e_kjp]ejo is a lookup type (as
explained in Chapter 5 and Appendix B), and the statement can be roughly translated
as “Get the books whose title contains m, without being case-sensitive.”
This is a very simple way to do a book search. We wouldn’t recommend using a simple
e_kjp]ejo query on a large production database, as it can be slow. (In the real world,
you’d want to use a custom search system of some sort. Search the Web for open-source
full-text search to get an idea of the possibilities.)
Ê UÊ 7iÊ«>ÃÃi`Ê^kkgo, a list of >kkg objects, to the template. The template code for oa]n_d[
naoqhpo*dpih might include something like this:
CHAPTER 7 N FORMS 125
8l:Ukqoa]n_da`bkn68opnkjc:wwmqanuyy8+opnkjc:8+l:
w!eb^kkgo!y
8l:Bkqj`ww^kkgoxhajcpdyy^kkgww^kkgoxlhqn]hevayy*8+l:
8qh:
w!bkn^kkgej^kkgo!y
8he:ww^kkg*pephayy8+he:
w!aj`bkn!y
8+qh:
w!ahoa!y
8l:Jk^kkgoi]p_da`ukqnoa]n_d_nepane]*8+l:
w!aj`eb!y
Note the usage of the lhqn]heva template filter, which outputs an “s” if appropriate, based
on the number of books found.
Improving Our Simple Form-Handling Example
As in previous chapters, we’ve shown you the simplest thing that could possibly work. Now
we’ll point out some problems and show you how to improve it.
First, our oa]n_d$% view’s handling of an empty query is poor—we’re just displaying a
Lha]oaoq^iep]oa]n_dpani* message, requiring the user to hit the browser’s Back button.
This is horrid and unprofessional, and if you ever actually implement something like this in
the wild, your Django privileges will be revoked.
It would be much better to redisplay the form, with an error above it, so that the user
can try again immediately. The easiest way to do that would be to render the template again,
like this:
bnki`f]jck*dppleilknpDpplNaolkjoa
bnki`f]jck*odknp_qpoeilknpnaj`an[pk[naolkjoa
bnkiiuoepa*^kkgo*ik`ahoeilknp>kkg
`aboa]n_d[bkni$namqaop%6
napqnjnaj`an[pk[naolkjoa$#oa]n_d[bkni*dpih#%
`aboa]n_d$namqaop%6
eb#m#ejnamqaop*CAP]j`namqaop*CAPW#m#Y6
m9namqaop*CAPW#m#Y
^kkgo9>kkg*k^fa_po*behpan$pepha[[e_kjp]ejo9m%
napqnjnaj`an[pk[naolkjoa$#oa]n_d[naoqhpo*dpih#(
w#^kkgo#6^kkgo(#mqanu#6my%
ahoa6
napqnjnaj`an[pk[naolkjoa$#oa]n_d[bkni*dpih#(w#annkn#6Pnqay%
(Note that we’ve included oa]n_d[bkni$% here so you can see both views in one place.)
Here we’ve improved oa]n_d$% to render the oa]n_d[bkni*dpih template again if the query
is empty. And because we need to display an error message in that template, we pass a tem-
plate variable. Now we can edit oa]n_d[bkni*dpih to check for the annkn variable:
CHAPTER 7 N FORMS
126
8dpih:
8da]`:
8pepha:Oa]n_d8+pepha:
8+da]`:
8^k`u:
w!ebannkn!y
8lopuha9_khkn6na`7:Lha]oaoq^iep]oa]n_dpani*8+l:
w!aj`eb!y
8bkni]_pekj9+oa]n_d+iapdk`9cap:
8ejlqppula9patpj]ia9m:
8ejlqppula9oq^iepr]hqa9Oa]n_d:
8+bkni:
8+^k`u:
8+dpih:
We can still use this template from our original view, oa]n_d[bkni$%, because oa]n_d[
bkni$% doesn’t pass annkn to the template—so the error message won’t show up in that case.
With this change in place, it’s a better application but it now begs the question: is a dedi-
cated oa]n_d[bkni$% view really necessary? As it stands, a request to the URL +oa]n_d+ (without
any CAP parameters) will display the empty form (but with an error). We can remove the
oa]n_d[bkni$% view, along with its associated URLpattern, as long as we change oa]n_d$% to
hide the error message when somebody visits +oa]n_d+ with no CAP parameters:
`aboa]n_d$namqaop%6
annkn9B]hoa
eb#m#ejnamqaop*CAP6
m9namqaop*CAPW#m#Y
ebjkpm6
annkn9Pnqa
ahoa6
^kkgo9>kkg*k^fa_po*behpan$pepha[[e_kjp]ejo9m%
napqnjnaj`an[pk[naolkjoa$#oa]n_d[naoqhpo*dpih#(
w#^kkgo#6^kkgo(#mqanu#6my%
napqnjnaj`an[pk[naolkjoa$#oa]n_d[bkni*dpih#(
w#annkn#6annkny%
In this updated view, if a user visits +oa]n_d+ with no CAP parameters, he’ll see the search
form with no error message. If a user submits the form with an empty value for #m#, he’ll see
the search form with an error message. And, finally, if a user submits the form with a non-
empty value for #m#, he’ll see the search results.
We can make one final improvement to this application, to remove a bit of redundancy.
Now that we’ve rolled the two views and URLs into one and +oa]n_d+ handles both search-
form display and result display, the HTML 8bkni: in oa]n_d[bkni*dpih doesn’t have to
hard-code a URL. Instead of this
8bkni]_pekj9+oa]n_d+iapdk`9cap:
it can be changed to this:
8bkni]_pekj9iapdk`9cap:
CHAPTER 7 N FORMS 127
The ]_pekj9 means “Submit the form to the same URL as the current page.” With
this change in place, you won’t have to remember to change the ]_pekj if you ever hook the
oa]n_d$% view to another URL.
Simple Validation
Our search example is still reasonably simple, particularly in terms of its data validation; we’re
merely checking to make sure the search query isn’t empty. Many HTML forms include a level
of validation that’s more complex than making sure the value is nonempty. We’ve all seen the
following error messages on Web sites:
Ê UÊ º*i>ÃiÊiÌiÀÊ>ÊÛ>`Êi>Ê>``ÀiÃðʼv½ÊÃÊÌÊ>Êi>Ê>``ÀiÃð»
Ê UÊ º*i>ÃiÊiÌiÀÊ>ÊÛ>`ÊvÛi`}ÌÊ1°-°Ê<*ÊV`i°Ê¼£ÓνÊÃÊÌÊ>Ê<*ÊV`i°»
Ê UÊ º*i>ÃiÊiÌiÀÊ>ÊÛ>`Ê`>ÌiÊÊÌiÊvÀ>ÌÊ9999°»
Ê UÊ º*i>ÃiÊiÌiÀÊ>Ê«>ÃÃÜÀ`ÊÌ>ÌÊÃÊ>ÌÊi>ÃÌÊnÊV>À>VÌiÀÃÊ}Ê>`ÊVÌ>ÃÊ>ÌÊi>ÃÌÊiÊ
number.”
A NOTE ON JAVASCRIPT VALIDATION
JavaScript validation is beyond the scope of this book, but you can use JavaScript to validate data on the
client side, directly in the browser. Be warned, however: even if you do this, you must validate data on the
server side. Some people have JavaScript turned off, and some malicious users might submit raw, unvali-
dated data directly to your form handler to see whether they can cause mischief.
There’s nothing you can do about this, other than to always validate user-submitted data server-side
(i.e., in your Django views). You should think of JavaScript validation as a bonus usability feature, not as your
only means of validating.
Let’s tweak our oa]n_d$% view so it validates that the search term is less than or equal to
ÓäÊV>À>VÌiÀÃÊ}°ÊÀÊÌÃÊiÝ>«i]Êi̽ÃÊÃ>ÞÊ>ÞÌ}Ê}iÀÊÌ>ÊÌ>ÌÊ}ÌÊ>iÊÌiʵÕiÀÞÊ
too slow.) How might we do that? The simplest thing would be to embed the logic directly in
the view, like this:
`aboa]n_d$namqaop%6
annkn9B]hoa
eb#m#ejnamqaop*CAP6
m9namqaop*CAPW#m#Y
ebjkpm6
annkn9Pnqa
ahebhaj$m%:.,6
annkn9Pnqa
ahoa6
^kkgo9>kkg*k^fa_po*behpan$pepha[[e_kjp]ejo9m%
napqnjnaj`an[pk[naolkjoa$#oa]n_d[naoqhpo*dpih#(
w#^kkgo#6^kkgo(#mqanu#6my%
CHAPTER 7 N FORMS
128
napqnjnaj`an[pk[naolkjoa$#oa]n_d[bkni*dpih#(
w#annkn#6annkny%
ÜÊvÊÞÕÊÌÀÞÊÃÕLÌÌ}Ê>ÊÃi>ÀVʵÕiÀÞÊ}Ài>ÌiÀÊÌ>ÊÓäÊV>À>VÌiÀÃÊ}]ÊÞÕ½Ê}iÌÊ>Ê
error message. But that error message in oa]n_d[bkni*dpih currently says, Lha]oaoq^iep]
oa]n_dpani*—so we’ll have to change it to be accurate for both cases (an empty search term
or a search term that’s too long).
8dpih:
8da]`:
8pepha:Oa]n_d8+pepha:
8+da]`:
8^k`u:
w!ebannkn!y
8lopuha9_khkn6na`7:
Lha]oaoq^iep]oa]n_dpani
.,_d]n]_panoknodknpan*
8+l:
w!aj`eb!y
8bkni]_pekj9+oa]n_d+iapdk`9cap:
8ejlqppula9patpj]ia9m:
8ejlqppula9oq^iepr]hqa9Oa]n_d:
8+bkni:
8+^k`u:
8+dpih:
There’s something ugly about this. Our one-size-fits-all error message is potentially con-
fusing. Why should the error message for an empty form submission mention anything about
>ÊÓäV>À>VÌiÀÊ̶ÊÀÀÀÊiÃÃ>}iÃÊÃÕ`ÊLiÊëiVvVÊ>`ÊVi>À°
The problem is that we’re using a simple Boolean value for annkn, whereas we should be
using a list of error-message strings. Here’s how we might fix that:
`aboa]n_d$namqaop%6
annkno9WY
eb#m#ejnamqaop*CAP6
m9namqaop*CAPW#m#Y
ebjkpm6
annkno*]llaj`$#Ajpan]oa]n_dpani*#%
ahebhaj$m%:.,6
annkno*]llaj`$#Lha]oaajpan]pikop.,_d]n]_pano*#%
ahoa6
^kkgo9>kkg*k^fa_po*behpan$pepha[[e_kjp]ejo9m%
napqnjnaj`an[pk[naolkjoa$#oa]n_d[naoqhpo*dpih#(
w#^kkgo#6^kkgo(#mqanu#6my%
napqnjnaj`an[pk[naolkjoa$#oa]n_d[bkni*dpih#(
w#annkno#6annknoy%
Then we need to make a small tweak to the oa]n_d[bkni*dpih template to reflect that it’s
now passed an annkno list instead of an annkn Boolean value:
CHAPTER 7 N FORMS 129
8dpih:
8da]`:
8pepha:Oa]n_d8+pepha:
8+da]`:
8^k`u:
w!ebannkno!y
8qh:
w!bknannknejannkno!y
8he:wwannknyy8+he:
w!aj`bkn!y
8+qh:
w!aj`eb!y
8bkni]_pekj9+oa]n_d+iapdk`9cap:
8ejlqppula9patpj]ia9m:
8ejlqppula9oq^iepr]hqa9Oa]n_d:
8+bkni:
8+^k`u:
8+dpih:
Making a Contact Form
Although we iterated over the book-search-form example several times and improved it
nicely, it’s still fundamentally simple: just a single field, #m#. Because it’s so simple, we didn’t
even use Django’s form library to deal with it. But more complex forms call for more complex
treatment—and now we’ll develop something more complex: a site contact form that lets site
users submit a bit of feedback, along with an optional e-mail return address. After the form
is submitted and the data is validated, we’ll automatically send the message via e-mail to the
site staff.
We’ll start with our template, _kjp]_p[bkni*dpih.
8dpih:
8da]`:
8pepha:?kjp]_pqo8+pepha:
8+da]`:
8^k`u:
8d-:?kjp]_pqo8+d-:
w!ebannkno!y
8qh:
w!bknannknejannkno!y
8he:wwannknyy8+he:
w!aj`bkn!y
8+qh:
w!aj`eb!y
CHAPTER 7 N FORMS
130
8bkni]_pekj9+_kjp]_p+iapdk`9lkop:
8l:Oq^fa_p68ejlqppula9patpj]ia9oq^fa_p:8+l:
8l:Ukqna)i]eh$klpekj]h%68ejlqppula9patpj]ia9a)i]eh:8+l:
8l:Iaoo]ca68patp]na]j]ia9iaoo]cankso9-,_kho91,:8+patp]na]:8+l:
8ejlqppula9oq^iepr]hqa9Oq^iep:
8+bkni:
8+^k`u:
8+dpih:
We’ve defined three fields: the subject, e-mail address, and message. The second is
optional, but the other two fields are required. Note we’re using iapdk`9lkop here instead of
iapdk`9cap because this form submission has a side effect—it sends an e-mail. Also, we cop-
ied the error-displaying code from our previous template oa]n_d[bkni*dpih.
If we continue down the road established by our oa]n_d$% view from the previous section,
a naive version of our _kjp]_p$% view might look like this:
bnki`f]jck*_kna*i]eheilknpoaj`[i]eh
bnki`f]jck*dppleilknpDpplNaolkjoaNa`ena_p
bnki`f]jck*odknp_qpoeilknpnaj`an[pk[naolkjoa
`ab_kjp]_p$namqaop%6
annkno9WY
ebnamqaop*iapdk`99#LKOP#6
ebjkpnamqaop*LKOP*cap$#oq^fa_p#(##%6
annkno*]llaj`$#Ajpan]oq^fa_p*#%
ebjkpnamqaop*LKOP*cap$#iaoo]ca#(##%6
annkno*]llaj`$#Ajpan]iaoo]ca*#%
ebnamqaop*LKOP*cap$#a)i]eh#%]j`#<#jkpejnamqaop*LKOPW#a)i]eh#Y6
annkno*]llaj`$#Ajpan]r]he`a)i]eh]``naoo*#%
ebjkpannkno6
oaj`[i]eh$
namqaop*LKOPW#oq^fa_p#Y(
namqaop*LKOPW#iaoo]ca#Y(
namqaop*LKOP*cap$#a)i]eh#(#jknalhu<at]ilha*_ki#%(
W#oepaksjan<at]ilha*_ki#Y(
%
napqnjDpplNaolkjoaNa`ena_p$#+_kjp]_p+pd]jgo+#%
napqnjnaj`an[pk[naolkjoa$#_kjp]_p[bkni*dpih#(
w#annkno#6annknoy%
NNote You may be wondering whether to put this view in the ^kkgo+reaso*lu file. It doesn’t have any-
thing to do with the books application, so should it live elsewhere? It’s up to you; Django doesn’t care, as
long as you’re able to point to the view from your URLconf. Our personal preference would be to create a
separate directory, _kjp]_p, at the same level in the directory tree as ^kkgo. This would contain an empty
[[ejep[[*lu and reaso*lu.
CHAPTER 7 N FORMS 131
Several new things are happening here:
Ê UÊ 7i½ÀiÊViV}ÊÌ>ÌÊnamqaop*iapdk` is #LKOP#. This will be true only in the case of a
form submission; it won’t be true if somebody is merely viewing the contact form. (In
the latter case, namqaop*iapdk` will be set to #CAP# because in normal Web browsing,
browsers use CAP, not LKOP.) This makes it a nice way to isolate the “form display” case
from the “form processing” case.
Ê UÊ ÃÌi>`ÊvÊnamqaop*CAP, we’re using namqaop*LKOP to access the submitted form data.
This is necessary because the HTML 8bkni: in _kjp]_p[bkni*dpih uses iapdk`9lkop.
If this view is accessed via LKOP, then namqaop*CAP will be empty.
Ê UÊ 7iÊ>ÛiÊtwo required fields, oq^fa_p and iaoo]ca, so we have to validate both. Note
that we’re using namqaop*LKOP*cap$% and providing a blank string as the default value;
this is a nice, short way of handling both the cases of missing keys and missing data.
Ê UÊ ÌÕ}ÊÌiÊa)i]eh field is not required, we still validate it if it is indeed submitted.
Our validation algorithm here is fragile—we’re just checking that the string contains an
< character. In the real world, you’d want more robust validation (and Django provides
it, which we’ll show you in the “Your First Form Class” section later in this chapter).
Ê UÊ 7i½ÀiÊÕÃ}ÊÌiÊvÕVÌÊ`f]jck*_kna*i]eh*oaj`[i]eh to send an e-mail. This function
has four required arguments: the e-mail subject, the e-mail body, the “from” address,
and a list of recipient addresses. oaj`[i]eh is a convenient wrapper around Django’s
A)i]ehIaoo]ca class, which provides advanced features such as attachments, multipart
e-mails, and full control over e-mail headers.
Note that in order to send e-mail using oaj`[i]eh$%, your server must be configured to
send mail, and Django must be told about your outbound e-mail server. See dppl6++
`k_o*`f]jcklnkfa_p*_ki+aj+`ar+pkle_o+a)i]eh+ for the specifics.
Ê UÊ vÌiÀÊÌiÊi>ÊÃÊÃiÌ]ÊÜiÊÀi`ÀiVÌÊÌÊ>ʺÃÕVViÃûʫ>}iÊLÞÊÀiÌÕÀ}Ê>Ê
DpplNaolkjoaNa`ena_p object. We’ll leave the implementation of that “success”
page up to you (it’s a simple view/URLconf/template), but we’ll explain why we
initiate a redirect instead of, for example, simply calling naj`an[pk[naolkjoa$% with
a template right there.
The reason: if a user hits Refresh on a page that was loaded via LKOP, that request will be
repeated. This can often lead to undesired behavior, such as a duplicate record being
added to the database—or, in our example, the e-mail being sent twice. If the user
is redirected to another page after the LKOP, then there’s no chance of repeating the
request.
You should always issue a redirect for successful LKOP requests. It’s a Web-development
best practice.
This view works, but those validation functions are kind of crufty. Imagine processing a
form with a dozen fields; would you really want to have to write all of those eb statements?
Another problem is form redisplay. In the case of validation errors, it’s best practice to
redisplay the form with the previously submitted data already filled in so the user can see what
he did wrong (and doesn’t have to re-enter data in fields that were submitted correctly). We
could manually pass the LKOP data back to the template, but we’d have to edit each HTML field
to insert the proper value in the proper place:
CHAPTER 7 N FORMS
132
reaso*lu
`ab_kjp]_p$namqaop%6
annkno9WY
ebnamqaop*iapdk`99#LKOP#6
ebjkpnamqaop*LKOP*cap$#oq^fa_p#(##%6
annkno*]llaj`$#Ajpan]oq^fa_p*#%
ebjkpnamqaop*LKOP*cap$#iaoo]ca#(##%6
annkno*]llaj`$#Ajpan]iaoo]ca*#%
ebnamqaop*LKOP*cap$#a)i]eh#%]j`#<#jkpejnamqaop*LKOPW#a)i]eh#Y6
annkno*]llaj`$#Ajpan]r]he`a)i]eh]``naoo*#%
ebjkpannkno6
oaj`[i]eh$
namqaop*LKOPW#oq^fa_p#Y(
namqaop*LKOPW#iaoo]ca#Y(
namqaop*LKOP*cap$#a)i]eh#(#jknalhu<at]ilha*_ki#%(
W#oepaksjan<at]ilha*_ki#Y(
%
napqnjDpplNaolkjoaNa`ena_p$#+_kjp]_p+pd]jgo+#%
napqnjnaj`an[pk[naolkjoa$#_kjp]_p[bkni*dpih#(w
#annkno#6annkno(
#oq^fa_p#6namqaop*LKOP*cap$#oq^fa_p#(##%(
#iaoo]ca#6namqaop*LKOP*cap$#iaoo]ca#(##%(
#a)i]eh#6namqaop*LKOP*cap$#a)i]eh#(##%(
y%
_kjp]_p[bkni*dpih
8dpih:
8da]`:
8pepha:?kjp]_pqo8+pepha:
8+da]`:
8^k`u:
8d-:?kjp]_pqo8+d-:
w!ebannkno!y
8qh:
w!bknannknejannkno!y
8he:wwannknyy8+he:
w!aj`bkn!y
8+qh:
w!aj`eb!y
8bkni]_pekj9+_kjp]_p+iapdk`9lkop:
8l:Oq^fa_p68ejlqppula9patpj]ia9oq^fa_pr]hqa9wwoq^fa_pyy:8+l:
8l:Ukqna)i]eh$klpekj]h%6
8ejlqppula9patpj]ia9a)i]ehr]hqa9wwa)i]ehyy:
CHAPTER 7 N FORMS 133
8+l:
8l:Iaoo]ca6
8patp]na]j]ia9iaoo]cankso9-,_kho91,:
&&wwiaoo]cayy&&
8+patp]na]:
8+l:
8ejlqppula9oq^iepr]hqa9Oq^iep:
8+bkni:
8+^k`u:
8+dpih:
This is a lot of cruft, and it introduces a lot of opportunities for human error. We hope
you’re starting to see the opportunity for some higher-level library that handles form- and
validation-related tasks.
Your First Form Class
Django comes with a form library, called `f]jck*bknio, that handles many of the issues we’ve
been exploring in this chapter—from HTML form display to validation. Let’s dive in and
rework our contact-form application using the Django forms framework.
DJANGO’S “NEWFORMS” LIBRARY
Throughout the Django community, you might see chatter about something called `f]jck*jasbknio. When
people speak of `f]jck*jasbknio, they’re talking about what is now `f]jck*bknio—the library covered
in this chapter.
When Django was first released to the public, it had a complicated, confusing forms system, `f]jck*
bknio. It was completely rewritten, and the new version was called `f]jck*jasbknio so that people could
still use the old system. When Django 1.0 was released, the old `f]jck*bknio went away, and `f]jck*
jasbknio became `f]jck*bknio.
The primary way to use the forms framework is to define a Bkni class for each HTML
8bkni: you’re dealing with. In our case, we only have one 8bkni:, so we’ll have one Bkni class.
This class can live anywhere you want—including directly in your reaso*lu file—but commu-
nity convention is to keep Bkni classes in a separate file called bknio*lu. Create this file in the
same directory as your reaso*lu, and enter the following:
bnki`f]jckeilknpbknio
_h]oo?kjp]_pBkni$bknio*Bkni%6
oq^fa_p9bknio*?d]nBeah`$%
a)i]eh9bknio*Ai]ehBeah`$namqena`9B]hoa%
iaoo]ca9bknio*?d]nBeah`$%
CHAPTER 7 N FORMS
134
/ÃÊÃÊ«ÀiÌÌÞÊÌÕÌÛi]Ê>`Ê̽ÃÊÃ>ÀÊÌÊ>}½ÃÊ`iÊÃÞÌ>Ý°Ê>VÊvi`ÊÊÌiÊvÀÊ
is represented by a type of Beah` class—?d]nBeah` and Ai]ehBeah` are the only types of fields
used here—as attributes of a BkniÊV>ÃðÊ>VÊvi`ÊÃÊÀiµÕÀi`ÊLÞÊ`iv>ÕÌ]ÊÃÊÌÊ>iÊa)i]eh
optional, we specify namqena`9B]hoa.
Let’s hop into the Python interactive interpreter and see what this class can do. The first
thing it can do is display itself as HTML:
:::bnki_kjp]_p*bknioeilknp?kjp]_pBkni
:::b9?kjp]_pBkni$%
:::lnejpb
8pn:8pd:8h]^ahbkn9e`[oq^fa_p:Oq^fa_p68+h]^ah:8+pd:8p`:
8ejlqppula9patpj]ia9oq^fa_pe`9e`[oq^fa_p+:8+p`:8+pn:
8pn:8pd:8h]^ahbkn9e`[a)i]eh:A)i]eh68+h]^ah:8+pd:8p`:
8ejlqppula9patpj]ia9a)i]ehe`9e`[a)i]eh+:8+p`:8+pn:
8pn:8pd:8h]^ahbkn9e`[iaoo]ca:Iaoo]ca68+h]^ah:8+pd:8p`:
8ejlqppula9patpj]ia9iaoo]cae`9e`[iaoo]ca+:8+p`:8+pn:
Django adds a label to each field, along with 8h]^ah: tags for accessibility. The idea is to
make the default behavior as optimal as possible.
This default output is in the format of an HTML 8p]^ha:, but there are a few other built-in
outputs:
:::lnejpb*]o[qh$%
8he:8h]^ahbkn9e`[oq^fa_p:Oq^fa_p68+h]^ah:
8ejlqppula9patpj]ia9oq^fa_pe`9e`[oq^fa_p+:8+he:
8he:8h]^ahbkn9e`[a)i]eh:A)i]eh68+h]^ah:
8ejlqppula9patpj]ia9a)i]ehe`9e`[a)i]eh+:8+he:
8he:8h]^ahbkn9e`[iaoo]ca:Iaoo]ca68+h]^ah:
8ejlqppula9patpj]ia9iaoo]cae`9e`[iaoo]ca+:8+he:
:::lnejpb*]o[l$%
8l:8h]^ahbkn9e`[oq^fa_p:Oq^fa_p68+h]^ah:
8ejlqppula9patpj]ia9oq^fa_pe`9e`[oq^fa_p+:8+l:
8l:8h]^ahbkn9e`[a)i]eh:A)i]eh68+h]^ah:
8ejlqppula9patpj]ia9a)i]ehe`9e`[a)i]eh+:8+l:
8l:8h]^ahbkn9e`[iaoo]ca:Iaoo]ca68+h]^ah:
8ejlqppula9patpj]ia9iaoo]cae`9e`[iaoo]ca+:8+l:
Note that the opening and closing 8p]^ha:, 8qh:, and 8bkni: tags aren’t included in the
output, so you can add any additional rows and customization if necessary.
These methods are just shortcuts for the common case of “display the entire form.” You
can also display the HTML for a particular field:
:::lnejpbW#oq^fa_p#Y
8ejlqppula9patpj]ia9oq^fa_pe`9e`[oq^fa_p+:
:::lnejpbW#iaoo]ca#Y
8ejlqppula9patpj]ia9iaoo]cae`9e`[iaoo]ca+:
The second thing Bkni objects can do is validate data. To do this, create a new Bkni object
and pass it a dictionary of data that maps field names to data:
CHAPTER 7 N FORMS 135
:::b9?kjp]_pBkni$w#oq^fa_p#6#Dahhk#(#a)i]eh#6#]`ne]j<at]ilha*_ki#(
Å#iaoo]ca#6#Je_aoepa#y%
Once you’ve associated data with a Bkni instance, you’ve created a bound Bkni:
:::b*eo[^kqj`
Pnqa
Call the eo[r]he`$% method on any bound Bkni to find out whether its data is valid. We’ve
passed a valid value for each field, so the Bkni in its entirety is valid:
:::b*eo[r]he`$%
Pnqa
If we don’t pass the a)i]eh field, it’s still valid, because we’ve specified namqena`9B]hoa for
that field:
:::b9?kjp]_pBkni$w#oq^fa_p#6#Dahhk#(#iaoo]ca#6#Je_aoepa#y%
:::b*eo[r]he`$%
Pnqa
But if we leave off either oq^fa_p or iaoo]ca, the Bkni is no longer valid:
:::b9?kjp]_pBkni$w#oq^fa_p#6#Dahhk#y%
:::b*eo[r]he`$%
B]hoa
:::b9?kjp]_pBkni$w#oq^fa_p#6#Dahhk#(#iaoo]ca#6##y%
:::b*eo[r]he`$%
B]hoa
You can drill down to get field-specific error messages:
:::b9?kjp]_pBkni$w#oq^fa_p#6#Dahhk#(#iaoo]ca#6##y%
:::bW#iaoo]ca#Y*annkno
Wq#Pdeobeah`eonamqena`*#Y
:::bW#oq^fa_p#Y*annkno
WY
:::bW#a)i]eh#Y*annkno
WY
>VÊLÕ`ÊBkni instance has an annkno attribute that gives you a dictionary mapping
field names to error-message lists:
:::b9?kjp]_pBkni$w#oq^fa_p#6#Dahhk#(#iaoo]ca#6##y%
:::b*annkno
w#iaoo]ca#6Wq#Pdeobeah`eonamqena`*#Yy
Finally, for Bkni instances whose data has been found to be valid, a _ha]ja`[`]p] attribute
is available. This is a dictionary of the submitted data, “cleaned up.” Django’s forms frame-
work not only validates data, but cleans it up by converting values to the appropriate Python
types, as shown here:
CHAPTER 7 N FORMS
136
:::b9?kjp]_pBkni$w#oq^fa_p#6#Dahhk#(#a)i]eh#6#]`ne]j<at]ilha*_ki#(
Å#iaoo]ca#6#Je_aoepa#y%
:::b*eo[r]he`$%
Pnqa
:::b*_ha]ja`[`]p]
w#iaoo]ca#6q#Je_aoepa#(#a)i]eh#6q#]`ne]j<at]ilha*_ki#(#oq^fa_p#6q#Dahhk#y
Our contact form deals only with strings, which are “cleaned” into Unicode objects—
but if we were to use an EjpacanBeah` or a @]paBeah`, the forms framework would ensure that
_ha]ja`[`]p] used proper Python integers or `]papeia*`]pa objects for the given fields.
Tying Form Objects into Views
Now that you have some basic knowledge about Bkni classes, you might see how we can use
this infrastructure to replace some of the cruft in our _kjp]_p$% view. Here’s how we can
rewrite _kjp]_p$% to use the forms framework:
reaso*lu
bnki`f]jck*odknp_qpoeilknpnaj`an[pk[naolkjoa
bnkiiuoepa*_kjp]_p*bknioeilknp?kjp]_pBkni
`ab_kjp]_p$namqaop%6
ebnamqaop*iapdk`99#LKOP#6
bkni9?kjp]_pBkni$namqaop*LKOP%
ebbkni*eo[r]he`$%6
_`9bkni*_ha]ja`[`]p]
oaj`[i]eh$
_`W#oq^fa_p#Y(
_`W#iaoo]ca#Y(
_`*cap$#a)i]eh#(#jknalhu<at]ilha*_ki#%(
W#oepaksjan<at]ilha*_ki#Y(
%
napqnjDpplNaolkjoaNa`ena_p$#+_kjp]_p+pd]jgo+#%
ahoa6
bkni9?kjp]_pBkni$%
napqnjnaj`an[pk[naolkjoa$#_kjp]_p[bkni*dpih#(w#bkni#6bkniy%
_kjp]_p[bkni*dpih
8dpih:
8da]`:
8pepha:?kjp]_pqo8+pepha:
8+da]`:
8^k`u:
8d-:?kjp]_pqo8+d-:
CHAPTER 7 N FORMS 137
w!ebbkni*annkno!y
8lopuha9_khkn6na`7:
Lha]oa_knna_ppdaannknwwbkni*annknoxlhqn]hevayy^ahks*
8+l:
w!aj`eb!y
8bkni]_pekj9iapdk`9lkop:
8p]^ha:
wwbkni*]o[p]^hayy
8+p]^ha:
8ejlqppula9oq^iepr]hqa9Oq^iep:
8+bkni:
8+^k`u:
8+dpih:
Look at how much cruft we’ve been able to remove! Django’s forms framework handles
the HTML display, the validation, data cleanup, and form redisplay-with-errors.
Try running this locally. Load the form, submit it with none of the fields filled out, submit
it with an invalid e-mail address, then finally submit it with valid data. (Of course, depend-
ing on your mail-server configuration, you might get an error when oaj`[i]eh$% is called, but
that’s another issue.)
Changing How Fields Are Rendered
Probably the first thing you’ll notice when you render this form locally is that the iaoo]ca field
is displayed as an 8ejlqppula9patp:, and it ought to be a 8patp]na]:. We can fix that by set-
ting the field’s widget:
bnki`f]jckeilknpbknio
_h]oo?kjp]_pBkni$bknio*Bkni%6
oq^fa_p9bknio*?d]nBeah`$%
a)i]eh9bknio*Ai]ehBeah`$namqena`9B]hoa%
iaoo]ca9bknio*?d]nBeah`$se`cap9bknio*Patp]na]%
The forms framework separates out the presentation logic for each field into a set of wid-
}iÌðÊ>VÊvi`ÊÌÞ«iÊ>ÃÊ>Ê`iv>ÕÌÊÜ`}iÌ]ÊLÕÌÊÞÕÊV>Êi>ÃÞÊÛiÀÀ`iÊÌiÊ`iv>ÕÌÊÀÊ«ÀÛ`iÊ>Ê
custom widget of your own.
Think of the Beah` classes as representing validation logic, while widgets represent presen-
tation logic.
Setting a Maximum Length
One of the most common validation needs is to check that a field is of a certain size. For good
measure, we should improve our ?kjp]_pBkni to limit the oq^fa_p to 100 characters. To do
that, just supply a i]t[hajcpd to the ?d]nBeah`, like this:
CHAPTER 7 N FORMS
138
bnki`f]jckeilknpbknio
_h]oo?kjp]_pBkni$bknio*Bkni%6
oq^fa_p9bknio*?d]nBeah`$i]t[hajcpd9-,,%
a)i]eh9bknio*Ai]ehBeah`$namqena`9B]hoa%
iaoo]ca9bknio*?d]nBeah`$se`cap9bknio*Patp]na]%
An optional iej[hajcpd argument is also available.
Setting Initial Values
As an improvement to this form, let’s add an initial value for the oq^fa_p field: Ehkraukqn
oepa (A little power of suggestion can’t hurt.) To do this, we can use the ejepe]h argument
when we create a Bkni instance:
`ab_kjp]_p$namqaop%6
ebnamqaop*iapdk`99#LKOP#6
bkni9?kjp]_pBkni$namqaop*LKOP%
ebbkni*eo[r]he`$%6
_`9bkni*_ha]ja`[`]p]
oaj`[i]eh$
_`W#oq^fa_p#Y(
_`W#iaoo]ca#Y(
_`*cap$#a)i]eh#(#jknalhu<at]ilha*_ki#%(
W#oepaksjan<at]ilha*_ki#Y(
%
napqnjDpplNaolkjoaNa`ena_p$#+_kjp]_p+pd]jgo+#%
ahoa6
bkni9?kjp]_pBkni$
ejepe]h9w#oq^fa_p#6#Ehkraukqnoepa#y
%
napqnjnaj`an[pk[naolkjoa$#_kjp]_p[bkni*dpih#(w#bkni#6bkniy%
Now the oq^fa_p field will be displayed prepopulated with that kind statement.
Note that there is a difference between passing initial data and passing data that binds the
form. If you’re just passing initial data, then the form will be unbound, which means it won’t
have any error messages.
Adding Custom Validation Rules
Imagine we’ve launched our feedback form, and the e-mails have started tumbling in. There’s
just one problem: some of the submitted messages are just one or two words, which isn’t long
enough for us to make sense of. We decide to adopt a new validation policy: four words or
more, please.
There are various ways to hook custom validation into a Django form. If our rule is
something we will reuse again and again, we can create a custom field type. Most custom vali-
dations are one-off affairs, though, and can be tied directly to the Bkni class.
We want additional validation on the iaoo]ca field, so we add a _ha]j[iaoo]ca$% method
to our Bkni class:
CHAPTER 7 N FORMS 139
bnki`f]jckeilknpbknio
_h]oo?kjp]_pBkni$bknio*Bkni%6
oq^fa_p9bknio*?d]nBeah`$i]t[hajcpd9-,,%
a)i]eh9bknio*Ai]ehBeah`$namqena`9B]hoa%
iaoo]ca9bknio*?d]nBeah`$se`cap9bknio*Patp]na]%
`ab_ha]j[iaoo]ca$oahb%6
iaoo]ca9oahb*_ha]ja`[`]p]W#iaoo]ca#Y
jqi[skn`o9haj$iaoo]ca*olhep$%%
ebjqi[skn`o806
n]eoabknio*R]he`]pekjAnnkn$Jkpajkqcdskn`o%
napqnjiaoo]ca
Django’s form system automatically looks for any method whose name starts with _ha]j[
and ends with the name of a field. If any such method exists, it’s called during validation.
Specifically, the _ha]j[iaoo]ca$% method will be called after the default validation logic
for a given field (in this case, the validation logic for a required ?d]nBeah`). Because the field
data has already been partially processed, we pull it out of oahb*_ha]ja`[`]p]. Also, we don’t
have to worry about checking that the value exists and is nonempty; the default validator
does that.
We naively use a combination of haj$% and olhep$% to count the number of words. If the
user has entered too few words, we raise a bknio*R]he`]pekjAnnkn. The string attached to this
exception will be displayed to the user as an item in the error list.
It’s important that we explicitly return the cleaned value for the field at the end of the
method. This allows us to modify the value (or convert it to a different Python type) within our
custom validation method. If we forget the return statement, then Jkja will be returned and
the original value will be lost.
Specifying Labels
By default, the labels on Django’s autogenerated form HTML are created by replacing under-
scores with spaces and capitalizing the first letter—so the label for the a)i]eh field is A)i]eh.
(Sound familiar? It’s the same simple algorithm that Django’s models use to calculate default
ran^koa[j]ia values for fields, which we covered in Chapter 5.)
But, as with Django’s models, we can customize the label for a given field. Just use h]^ah,
like so:
_h]oo?kjp]_pBkni$bknio*Bkni%6
oq^fa_p9bknio*?d]nBeah`$i]t[hajcpd9-,,%
a)i]eh9bknio*Ai]ehBeah`$namqena`9B]hoa(h]^ah9#Ukqna)i]eh]``naoo#%
iaoo]ca9bknio*?d]nBeah`$se`cap9bknio*Patp]na]%
Customizing Form Design
Our _kjp]_p[bkni*dpih template uses wwbkni*]o[p]^hayy to display the form, but we can
display the form in other ways to get more granular control over the display.
CHAPTER 7 N FORMS
140
/iʵÕViÃÌÊÜ>ÞÊÌÊVÕÃÌâiÊvÀýʫÀiÃiÌ>ÌÊÃÊÜÌÊ--°ÊÀÀÀÊÃÌÃ]ÊÊ«>ÀÌVÕ>À]Ê
could do with some visual enhancement, and the autogenerated error lists use 8qh_h]oo9
annknheop: precisely so that you can target them with CSS. The following CSS really makes
our errors stand out:
8opuhapula9patp+_oo:
qh*annknheopw
i]ncej6,7
l]``ejc6,7
y
*annknheophew
^]_gcnkqj`)_khkn6na`7
_khkn6sdepa7
`eolh]u6^hk_g7
bkjp)oeva6-,lt7
i]ncej6,,/lt7
l]``ejc60lt1lt7
y
8+opuha:
Although it’s convenient to have our form’s HTML generated for us, in many cases you’ll
want to override the default rendering. wwbkni*]o[p]^hayy and friends are useful shortcuts
while you develop your application, but everything about the way a form is displayed can be
overridden, mostly within the template itself, and you’ll likely override the defaults often.
>VÊvi`½ÃÊÜ`}iÌÊ8ejlqppula9patp:, 8oaha_p:, 8patp]na]:, etc.) can be rendered
individually by accessing wwbkni*beah`j]iayy in the template, and any errors associated
with a field are available as wwbkni*beah`j]ia*annknoyy. With this in mind, we can construct
a custom template for our contact form with the following template code:
8dpih:
8da]`:
8pepha:?kjp]_pqo8+pepha:
8+da]`:
8^k`u:
8d-:?kjp]_pqo8+d-:
w!ebbkni*annkno!y
8lopuha9_khkn6na`7:
Lha]oa_knna_ppdaannknwwbkni*annknoxlhqn]hevayy^ahks*
8+l:
w!aj`eb!y
8bkni]_pekj9iapdk`9lkop:
8`er_h]oo9beah`:
wwbkni*oq^fa_p*annknoyy
8h]^ahbkn9e`[oq^fa_p:Oq^fa_p68+h]^ah:
wwbkni*oq^fa_pyy
8+`er:
CHAPTER 7 N FORMS 141
8`er_h]oo9beah`:
wwbkni*a)i]eh*annknoyy
8h]^ahbkn9e`[a)i]eh:Ukqna)i]eh]``naoo68+h]^ah:
wwbkni*a)i]ehyy
8+`er:
8`er_h]oo9beah`:
wwbkni*iaoo]ca*annknoyy
8h]^ahbkn9e`[iaoo]ca:Iaoo]ca68+h]^ah:
wwbkni*iaoo]cayy
8+`er:
8ejlqppula9oq^iepr]hqa9Oq^iep:
8+bkni:
8+^k`u:
8+dpih:
wwbkni*iaoo]ca*annknoyy displays a 8qh_h]oo9annknheop: if errors are present and
a blank string if the field is valid (or the form is unbound). We can also treat bkni*iaoo]ca*
annkno as a Boolean or even iterate over it as a list. Consider this example:
8`er_h]oo9beah`w!ebbkni*iaoo]ca*annkno!yannknow!aj`eb!y:
w!ebbkni*iaoo]ca*annkno!y
8qh:
w!bknannknejbkni*iaoo]ca*annkno!y
8he:8opnkjc:wwannknyy8+opnkjc:8+he:
w!aj`bkn!y
8+qh:
w!aj`eb!y
8h]^ahbkn9e`[iaoo]ca:Iaoo]ca68+h]^ah:
wwbkni*iaoo]cayy
8+`er:
In the case of validation errors, this will add an annkno class to the containing 8`er: and
display the list of errors in an unordered list.
What’s Next?
This chapter concludes the introductory material in this book—the so-called “core curricu-
Õ°»Ê/iÊiÝÌÊÃiVÌÊvÊÌiÊL]Ê>«ÌiÀÃÊnÊÌÊ£Ó]Ê}iÃÊÌÊÀiÊ`iÌ>Ê>LÕÌÊ>`Û>Vi`Ê
>}ÊÕÃ>}i]ÊVÕ`}ÊÜÊÌÊ`i«ÞÊ>Ê>}Ê>««V>ÌÊ>«ÌiÀÊ£Ó®°
After these first seven chapters, you should know enough to start writing your own Django
projects. The rest of the material in this book will help fill in the missing pieces. We’ll start in
Chapter 8 by doubling back and taking a closer look at views and URLconfs (introduced first in
Chapter 3).
PART 2
Advanced Usage
145
CHAPTER 8
Advanced Views and URLconfs
In Chapter 3, we explained the basics of Django view functions and URLconfs. This chapter
goes into more detail about advanced functionality in those two pieces of the framework.
URLconf Tricks
There’s nothing “special” about URLconfs—like anything else in Django, they’re just Python
code. You can take advantage of this in several ways, as described in the sections that follow.
Streamlining Function Imports
Consider this URLconf, which builds on the example in Chapter 3:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnkiiuoepa*reasoeilknpdahhk(_qnnajp[`]papeia(dkqno[]da]`
qnhl]ppanjo9l]ppanjo$##(
$n#Zdahhk+ #(dahhk%(
$n#Zpeia+ #(_qnnajp[`]papeia%(
$n#Zpeia+lhqo+$X`w-(.y%+ #(dkqno[]da]`%(
%
As explained in Chapter 3, each entry in the URLconf includes its associated view func-
tion, passed directly as a function object. This means it’s necessary to import the view
functions at the top of the module.
But as a Django application grows in complexity, its URLconf grows, too, and keeping
those imports can be tedious to manage. (For each new view function, you have to remember
to import it, and the eilknp statement tends to get overly long if you use this approach.) It’s
possible to avoid that tedium by importing the reaso module itself. This example URLconf is
equivalent to the previous one:
CHAPTER 8 N ADVANCED VIEWS AND URLCONFS
146
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnkiiuoepaeilknpreaso
qnhl]ppanjo9l]ppanjo$##(
$n#Zdahhk+ #(reaso*dahhk%(
$n#Zpeia+ #(reaso*_qnnajp[`]papeia%(
$n#Zpeia+lhqo+$`w-(.y%+ #(reaso*dkqno[]da]`%(
%
Django offers another way of specifying the view function for a particular pattern in the
URLconf: you can pass a string containing the module name and function name rather than
the function object itself. Continuing the ongoing example:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
qnhl]ppanjo9l]ppanjo$##(
$n#Zdahhk+ #(#iuoepa*reaso*dahhk#%(
$n#Zpeia+ #(#iuoepa*reaso*_qnnajp[`]papeia#%(
$n#Zpeia+lhqo+$`w-(.y%+ #(#iuoepa*reaso*dkqno[]da]`#%(
%
(Note the quotes around the view names. We’re using #iuoepa*reaso*_qnnajp[`]papeia#
with quotes—instead of iuoepa*reaso*_qnnajp[`]papeia.)
Using this technique, it’s no longer necessary to import the view functions; Django auto-
matically imports the appropriate view function the first time it’s needed, according to the
string describing the name and path of the view function.
A further shortcut you can take when using the string technique is to factor out a common
“view prefix.” In our URLconf example, each of the view strings starts with #iuoepa*reaso#,
which is redundant to type. We can factor out that common prefix and pass it as the first argu-
ment to l]ppanjo$%, like this:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
qnhl]ppanjo9l]ppanjo$#iuoepa*reaso#(
$n#Zdahhk+ #(#dahhk#%(
$n#Zpeia+ #(#_qnnajp[`]papeia#%(
$n#Zpeia+lhqo+$`w-(.y%+ #(#dkqno[]da]`#%(
%
Note that 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.
With these two approaches in mind, which is better? It really depends on your personal
coding style and needs.
Advantages of the string approach are as follows:
Ê UÊ ̽ÃÊÀiÊV«>VÌ]ÊLiV>ÕÃiÊÌÊ`iÃ½ÌÊÀiµÕÀiÊÞÕÊÌÊ«ÀÌÊÌiÊÛiÜÊvÕVÌð
Ê UÊ ÌÊÀiÃÕÌÃÊÊÀiÊÀi>`>LiÊ>`Ê>>}i>LiÊ1,VvÃÊvÊÞÕÀÊÛiÜÊvÕVÌÃÊ>ÀiÊëÀi>`Ê
across several different Python modules.
CHAPTER 8 N ADVANCED VIEWS AND URLCONFS 147
Advantages of the function object approach are as follows:
Ê UÊ ÌÊ>ÜÃÊvÀÊi>ÃÞʺÜÀ>««}” of view functions. See the section “Wrapping View Func-
tions” later in this chapter.
Ê UÊ ̽ÃÊÀiʺ*ÞÌV»pÌ>ÌÊÃ]Ê̽ÃÊÀiÊÊiÊÜÌÊ*ÞÌÊÌÀ>`ÌÃ]ÊÃÕVÊ>ÃÊ«>ÃÃ}Ê
functions as objects.
Both approaches are valid, and you can even mix them within the same URLconf. The
choice is yours.
Using Multiple View Prefixes
In practice, 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. However, you can still take
advantage of the view prefix shortcut to remove duplication. Just add multiple l]ppanjo$%
objects together, like this:
Old:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
qnhl]ppanjo9l]ppanjo$##(
$n#Zdahhk+ #(#iuoepa*reaso*dahhk#%(
$n#Zpeia+ #(#iuoepa*reaso*_qnnajp[`]papeia#%(
$n#Zpeia+lhqo+$X`w-(.y%+ #(#iuoepa*reaso*dkqno[]da]`#%(
$n#Zp]c+$Xs'%+ #(#sa^hkc*reaso*p]c#%(
%
New:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
qnhl]ppanjo9l]ppanjo$#iuoepa*reaso#(
$n#Zdahhk+ #(#dahhk#%(
$n#Zpeia+ #(#_qnnajp[`]papeia#%(
$n#Zpeia+lhqo+$X`w-(.y%+ #(#dkqno[]da]`#%(
%
qnhl]ppanjo'9l]ppanjo$#sa^hkc*reaso#(
$n#Zp]c+$Xs'%+ #(#p]c#%(
%
All the framework cares about is that there’s a module-level variable called qnhl]ppanjo.
This variable can be constructed dynamically, as we do in this example. We should specifically
point out that the objects returned by l]ppanjo$% can be added together, which is something
you might not have expected.
CHAPTER 8 N ADVANCED VIEWS AND URLCONFS
148
Special-Casing URLs in Debug Mode
Speaking of constructing qnhl]ppanjo dynamically, you might want to take advantage of this
technique to alter your URLconf’s behavior while in Django’s debug mode. To do this, just
check the value of the @A>QC setting at runtime, like so:
bnki`f]jck*_kjbeilknpoappejco
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnkiiuoepaeilknpreaso
qnhl]ppanjo9l]ppanjo$##(
$n#Z #(reaso*dkial]ca%(
$n#Z$X`w0y%+$W])vYw/y%+ #(reaso*]n_dera[ikjpd%(
%
eboappejco*@A>QC6
qnhl]ppanjo'9l]ppanjo$##(
$n#Z`a^qcejbk+ #(reaso*`a^qc%(
%
In this example, the URL +`a^qcejbk+ will be available only if your @A>QC setting is set to Pnqa.
Using Named Groups
In all of our URLconf examples so far, we’ve used simple, non-named regular expression
groups—that is, we put parentheses around parts of the URL we wanted to capture, and
Django passes that captured text to the view function as a positional argument. In more
advanced usage, it’s possible to use named regular expression groups to capture URL bits and
pass them as keyword arguments to a view.
KEYWORD ARGUMENTS VS. POSITIONAL ARGUMENTS
A Python function can be called using keyword arguments or positional arguments—and, in some cases, both
at the same time. In a keyword argument call, you specify the names of the arguments along with the values
you’re passing. In a positional argument call, you simply pass the arguments without explicitly specifying
which argument matches which value; the association is implicit in the arguments’ order.
For example, consider this simple function:
`aboahh$epai(lne_a(mq]jpepu%6
lnejpOahhejc!oqjep$o%kb!o]p!o!$mq]jpepu(epai(lne_a%
To call it with positional arguments, you specify the arguments in the order in which they’re listed in the
function definition:
oahh$#Ok_go#(# .*1,#(2%
CHAPTER 8 N ADVANCED VIEWS AND URLCONFS 149
To call it with keyword arguments, you specify the names of the arguments along with the values. The
following statements are equivalent:
oahh$epai9#Ok_go#(lne_a9# .*1,#(mq]jpepu92%
oahh$epai9#Ok_go#(mq]jpepu92(lne_a9# .*1,#%
oahh$lne_a9# .*1,#(epai9#Ok_go#(mq]jpepu92%
oahh$lne_a9# .*1,#(mq]jpepu92(epai9#Ok_go#%
oahh$mq]jpepu92(epai9#Ok_go#(lne_a9# .*1,#%
oahh$mq]jpepu92(lne_a9# .*1,#(epai9#Ok_go#%
Finally, you can mix keyword and positional arguments, as long as all positional arguments are listed
before keyword arguments. The following statements are equivalent to the previous examples:
oahh$#Ok_go#(# .*1,#(mq]jpepu92%
oahh$#Ok_go#(lne_a9# .*1,#(mq]jpepu92%
oahh$#Ok_go#(mq]jpepu92(lne_a9# .*1,#%
In Python regular expressions, the syntax for named regular expression groups is
$;L8j]ia:l]ppanj%, where j]ia is the name of the group and l]ppanj is some pattern to match.
Here’s an example URLconf that uses non-named groups:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnkiiuoepaeilknpreaso
qnhl]ppanjo9l]ppanjo$##(
$n#Z]npe_hao+$X`w0y%+ #(reaso*ua]n[]n_dera%(
$n#Z]npe_hao+$X`w0y%+$X`w.y%+ #(reaso*ikjpd[]n_dera%(
%
Here’s the same URLconf, rewritten to use named groups:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnkiiuoepaeilknpreaso
qnhl]ppanjo9l]ppanjo$##(
$n#Z]npe_hao+$;L8ua]n:X`w0y%+ #(reaso*ua]n[]n_dera%(
$n#Z]npe_hao+$;L8ua]n:X`w0y%+$;L8ikjpd:X`w.y%+ #(reaso*ikjpd[]n_dera%(
%
This accomplishes exactly the same thing as the previous example, with one subtle dif-
ference: the captured values are passed to view functions as keyword arguments rather than
positional arguments.
For example, with non-named groups, a request to +]npe_hao+.,,2+,/+ would result in a
function call equivalent to this:
ikjpd[]n_dera$namqaop(#.,,2#(#,/#%
CHAPTER 8 N ADVANCED VIEWS AND URLCONFS
150
With named groups, though, the same request would result in this function call:
ikjpd[]n_dera$namqaop(ua]n9#.,,2#(ikjpd9#,/#%
In practice, using named groups makes your URLconfs slightly more explicit and less
prone to argument-order bugs—and you can reorder the arguments in your views’ function
definitions. Following the preceding example, if we wanted to change the URLs to include
the month before the year, and we were using non-named groups, we’d have to remember to
change the order of arguments in the ikjpd[]n_dera view. If we were using named groups,
changing the order of the captured parameters in the URL would have no effect on the view.
Of course, the benefits of named groups come at the cost of brevity; some developers find
the named-group syntax ugly and too verbose. Still, another advantage of named groups is
readability, especially by those who aren’t intimately familiar with regular expressions or your
particular Django application. It’s easier to see what’s happening, at a glance, in a URLconf
that uses named groups.
Understanding the Matching/Grouping Algorithm
A caveat with using named groups in a URLconf is that a single URLconf pattern cannot con-
tain both named and non-named groups. If you do this, Django won’t throw any errors, but
you’ll probably find that your URLs aren’t matching as you expect. Specifically, here’s the
algorithm the URLconf parser follows, with respect to named groups vs. non-named groups in
a regular expression:
Ê UÊ vÊÌiÀiÊ>ÀiÊ>ÞÊ>i`Ê>À}ÕiÌÃ]ÊÌÊÜÊÕÃiÊÌÃi]Ê}À}Ê>i`Ê>À}ÕiÌð
Ê UÊ "ÌiÀÜÃi]ÊÌÊÜÊ«>ÃÃÊ>Ê>i`Ê>À}ÕiÌÃÊ>ÃÊ«ÃÌ>Ê>À}ÕiÌð
Ê UÊ ÊLÌÊV>ÃiÃ]ÊÌÊÜÊ«>ÃÃÊ>ÞÊiÝÌÀ> options as keyword arguments. See the next section
for more information.
Passing Extra Options to View Functions
Sometimes you’ll find yourself writing view functions that are quite similar, with only a few
small differences. For example, say you have two views whose contents are identical except for
the templates they use:
qnho*lu
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnkiiuoepaeilknpreaso
qnhl]ppanjo9l]ppanjo$##(
$n#Zbkk+ #(reaso*bkk[reas%(
$n#Z^]n+ #(reaso*^]n[reas%(
%
reaso*lu
bnki`f]jck*odknp_qpoeilknpnaj`an[pk[naolkjoa
bnkiiuoepa*ik`ahoeilknpIuIk`ah
CHAPTER 8 N ADVANCED VIEWS AND URLCONFS 151
`abbkk[reas$namqaop%6
i[heop9IuIk`ah*k^fa_po*behpan$eo[jas9Pnqa%
napqnjnaj`an[pk[naolkjoa$#pailh]pa-*dpih#(w#i[heop#6i[heopy%
`ab^]n[reas$namqaop%6
i[heop9IuIk`ah*k^fa_po*behpan$eo[jas9Pnqa%
napqnjnaj`an[pk[naolkjoa$#pailh]pa.*dpih#(w#i[heop#6i[heopy%
We’re repeating ourselves in this code, and that’s inelegant. At first, you may think to
remove the redundancy by using the same view for both URLs, putting parentheses around
the URL to capture it, and checking the URL within the view to determine the template, like so:
qnho*lu
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnkiiuoepaeilknpreaso
qnhl]ppanjo9l]ppanjo$##(
$n#Z$bkk%+ #(reaso*bkk^]n[reas%(
$n#Z$^]n%+ #(reaso*bkk^]n[reas%(
%
reaso*lu
bnki`f]jck*odknp_qpoeilknpnaj`an[pk[naolkjoa
bnkiiuoepa*ik`ahoeilknpIuIk`ah
`abbkk^]n[reas$namqaop(qnh%6
i[heop9IuIk`ah*k^fa_po*behpan$eo[jas9Pnqa%
ebqnh99#bkk#6
pailh]pa[j]ia9#pailh]pa-*dpih#
ahebqnh99#^]n#6
pailh]pa[j]ia9#pailh]pa.*dpih#
napqnjnaj`an[pk[naolkjoa$pailh]pa[j]ia(w#i[heop#6i[heopy%
The problem with that solution, though, is that it couples your URLs to your code. If you
decide to rename +bkk+ to +bkkau+, you’ll have to remember to change the view code.
The elegant solution involves an optional URLconf parameter. Each pattern in a URLconf
may include a third item: a dictionary of keyword arguments to pass to the view function.
With this in mind, we can rewrite our ongoing example like this:
qnho*lu
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnkiiuoepaeilknpreaso
qnhl]ppanjo9l]ppanjo$##(
$n#Zbkk+ #(reaso*bkk^]n[reas(w#pailh]pa[j]ia#6#pailh]pa-*dpih#y%(
$n#Z^]n+ #(reaso*bkk^]n[reas(w#pailh]pa[j]ia#6#pailh]pa.*dpih#y%(
%
CHAPTER 8 N ADVANCED VIEWS AND URLCONFS
152
reaso*lu
bnki`f]jck*odknp_qpoeilknpnaj`an[pk[naolkjoa
bnkiiuoepa*ik`ahoeilknpIuIk`ah
`abbkk^]n[reas$namqaop(pailh]pa[j]ia%6
i[heop9IuIk`ah*k^fa_po*behpan$eo[jas9Pnqa%
napqnjnaj`an[pk[naolkjoa$pailh]pa[j]ia(w#i[heop#6i[heopy%
As you can see, the URLconf in this example specifies pailh]pa[j]ia 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. As such, it’s used by a couple of Django’s bundled
applications, most notably its generic views system, which we cover in Chapter 11.
The following sections contain a couple of ideas on how you can use the extra URLconf
options technique in your own projects.
Faking Captured URLconf Values
Say you have a set of views that match a pattern, along with another URL that doesn’t fit the
pattern but whose view logic is the same. In this case, you can “fake” the capturing of URL val-
ues by using extra URLconf options to handle that extra URL with the same view.
For example, you might have an application that displays some data for a particular day,
with URLs such as these:
+iu`]p]+f]j+,-+
+iu`]p]+f]j+,.+
+iu`]p]+f]j+,/+
***
+iu`]p]+`a_+/,+
+iu`]p]+`a_+/-+
This is simple enough to deal with—you can capture those in a URLconf like this (using
named group syntax):
qnhl]ppanjo9l]ppanjo$##(
$n#Ziu`]p]+$;L8ikjpd:Xsw/y%+$;L8`]u:X`X`%+ #(reaso*iu[reas%(
%
And the view function signature would look like this:
`abiu[reas$namqaop(ikjpd(`]u%6
****
This approach is straightforward—it’s nothing you haven’t seen before. The trick comes in
when you want to add another URL that uses iu[reas but whose URL doesn’t include a ikjpd
and/or `]u.
For example, you might want to add another URL, +iu`]p]+^enpd`]u+, which would be
equivalent to +iu`]p]+f]j+,2+. You can take advantage of extra URLconf options like so:
CHAPTER 8 N ADVANCED VIEWS AND URLCONFS 153
qnhl]ppanjo9l]ppanjo$##(
$n#Ziu`]p]+^enpd`]u+ #(reaso*iu[reas(w#ikjpd#6#f]j#(#`]u#6#,2#y%(
$n#Ziu`]p]+$;L8ikjpd:Xsw/y%+$;L8`]u:X`X`%+ #(reaso*iu[reas%(
%
The cool thing here is that you don’t have to change your view function at all. The view
function only cares that it gets ikjpd and `]u parameters—it doesn’t matter whether they come
from the URL capturing itself or extra parameters.
Making a View Generic
It’s good programming practice to “factor out” commonalities in code. For example, with
these two Python functions:
`abo]u[dahhk$lanokj[j]ia%6
lnejp#Dahhk(!o#!lanokj[j]ia
`abo]u[ckk`^ua$lanokj[j]ia%6
lnejp#Ckk`^ua(!o#!lanokj[j]ia
we can factor out the greeting to make it a parameter:
`abcnaap$lanokj[j]ia(cnaapejc%6
lnejp#!o(!o#!$cnaapejc(lanokj[j]ia%
You can apply this same philosophy to your Django views by using extra URLconf param-
eters.
With this in mind, you can start making higher-level abstractions of your views. Instead of
thinking to yourself, “This view displays a list of Arajp objects,” and “That view displays a list of
>hkcAjpnu objects,” realize they’re both specific cases of “A view that displays a list of objects,
where the type of object is variable.”
Take this code, for example:
qnho*lu
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnkiiuoepaeilknpreaso
qnhl]ppanjo9l]ppanjo$##(
$n#Zarajpo+ #(reaso*arajp[heop%(
$n#Z^hkc+ajpneao+ #(reaso*ajpnu[heop%(
%
reaso*lu
bnki`f]jck*odknp_qpoeilknpnaj`an[pk[naolkjoa
bnkiiuoepa*ik`ahoeilknpArajp(>hkcAjpnu
`abarajp[heop$namqaop%6
k^f[heop9Arajp*k^fa_po*]hh$%
napqnjnaj`an[pk[naolkjoa$#iuoepa+arajp[heop*dpih#(w#arajp[heop#6k^f[heopy%
CHAPTER 8 N ADVANCED VIEWS AND URLCONFS
154
`abajpnu[heop$namqaop%6
k^f[heop9>hkcAjpnu*k^fa_po*]hh$%
napqnjnaj`an[pk[naolkjoa$#iuoepa+^hkcajpnu[heop*dpih#(
w#ajpnu[heop#6k^f[heopy%
The two views do essentially the same thing: they display a list of objects. So let’s factor
out the type of object they’re displaying:
qnho*lu
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnkiiuoepaeilknpik`aho(reaso
qnhl]ppanjo9l]ppanjo$##(
$n#Zarajpo+ #(reaso*k^fa_p[heop(w#ik`ah#6ik`aho*Arajpy%(
$n#Z^hkc+ajpneao+ #(reaso*k^fa_p[heop(w#ik`ah#6ik`aho*>hkcAjpnuy%(
%
reaso*lu
bnki`f]jck*odknp_qpoeilknpnaj`an[pk[naolkjoa
`abk^fa_p[heop$namqaop(ik`ah%6
k^f[heop9ik`ah*k^fa_po*]hh$%
pailh]pa[j]ia9#iuoepa+!o[heop*dpih#!ik`ah*[[j]ia[[*hksan$%
napqnjnaj`an[pk[naolkjoa$pailh]pa[j]ia(w#k^fa_p[heop#6k^f[heopy%
With those small changes, we suddenly have a reusable, model-agnostic view! From now
on, anytime we need a view that lists a set of objects, we can simply reuse this k^fa_p[heop
view rather than writing view code. Here are a couple of notes about what we did:
Ê UÊ 7iÊ«>ÃÃi`ÊÌiÊ`iÊV>ÃÃiÃÊ`ÀiVÌÞ]Ê>ÃÊÌiÊik`ah parameter. The dictionary of extra
URLconf options can pass any type of Python object—not just strings.
Ê UÊ /iÊik`ah*k^fa_po*]hh$% line is an example of duck typing: “If it walks like a duck and
talks like a duck, we can treat it like a duck.” Note the code doesn’t know what type of
object ik`ah is; the only requirement is that ik`ah have an k^fa_po attribute, which in
turn has an ]hh$% method.
Ê UÊ 7iÊÕÃi`Êik`ah*[[j]ia[[*hksan$% in determining the template name. Every Python
class has a [[j]ia[[ 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
>hkcAjpnu class’s [[j]ia[[ is the string #>hkcAjpnu#.
Ê UÊ Ê>ÊÃ}ÌÊ`vviÀiViÊLiÌÜiiÊÌÃÊiÝ>«iÊ>`ÊÌiÊ«ÀiÛÕÃÊiÝ>«i]ÊÜiÊ«>ÃÃi`ÊÌiÊ
generic variable name k^fa_p[heop to the template. We could easily change this vari-
able name to be ^hkcajpnu[heop or arajp[heop, but we’ve left that as an exercise for the
reader.
CHAPTER 8 N ADVANCED VIEWS AND URLCONFS 155
Because database-driven Web sites have several common patterns, Django comes with a
set of “generic views” that use this exact technique to save you time. We cover Django’s built-
in generic views in Chapter 11.
Giving a View Configuration Options
If you’re distributing a Django application, chances are that your users will want some degree
of configuration. In this case, it’s a good idea to add hooks to your views for any configuration
options you think people may want to change. You can use extra URLconf parameters for this
purpose.
A common bit of an application to make configurable is the template name:
`abiu[reas$namqaop(pailh]pa[j]ia%6
r]n9`k[okiapdejc$%
napqnjnaj`an[pk[naolkjoa$pailh]pa[j]ia(w#r]n#6r]ny%
Understanding Precedence of Captured Values vs. Extra Options
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.
For example, consider this URLconf:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnkiiuoepaeilknpreaso
qnhl]ppanjo9l]ppanjo$##(
$n#Ziu`]p]+$;L8e`:X`'%+ #(reaso*iu[reas(w#e`#6/y%(
%
Here, both the regular expression and the extra dictionary include an e`. The hard-coded
e` gets precedence. That means any request (e.g., +iu`]p]+.+ or +iu`]p]+0/.0/.+) will be
treated as if e` is set to /, regardless of the value captured in the URL.
Astute readers will note that in this case, it’s a waste of time and typing to capture the e`
in the regular expression, because its value will always be overridden by the dictionary’s value.
That’s correct; we bring this up only to help you avoid making the mistake.
Using Default View Arguments
Another convenient trick is to specify default parameters for a view’s arguments. This tells the
view which value to use for a parameter by default if none is specified.
Here’s an example:
qnho*lu
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnkiiuoepaeilknpreaso
CHAPTER 8 N ADVANCED VIEWS AND URLCONFS
156
qnhl]ppanjo9l]ppanjo$##(
$n#Z^hkc+ #(reaso*l]ca%(
$n#Z^hkc+l]ca$;L8jqi:X`'%+ #(reaso*l]ca%(
%
reaso*lu
`abl]ca$namqaop(jqi9#-#%6
Kqplqppda]llnklne]pal]cakb^hkcajpneao(]__kn`ejcpkjqi*
***
Here, both URLpatterns point to the same view—reaso*l]ca—but the first pattern doesn’t
capture anything from the URL. If the first pattern matches, the l]ca$% function will use its
default argument for jqi, #-#. If the second pattern matches, l]ca$% will use whatever jqi
value was captured by the regular expression.
NNote We’ve been careful to set the default argument’s value to the string #-#, not the integer -. That’s
for consistency because any captured value for jqi will always be a string.
It’s common to use this technique in conjunction with configuration options, as explained
earlier. This example makes a slight improvement to the example in the “Giving a View Con-
figuration Options” section by providing a default value for pailh]pa[j]ia:
`abiu[reas$namqaop(pailh]pa[j]ia9#iuoepa+iu[reas*dpih#%6
r]n9`k[okiapdejc$%
napqnjnaj`an[pk[naolkjoa$pailh]pa[j]ia(w#r]n#6r]ny%
Special-Casing Views
Sometimes you’ll have a pattern in your URLconf that handles a large set of URLs, but you’ll
need to special-case one of them. In this case, take advantage of the linear way a URLconf is
processed and put the special case first.
For example, you can think of the “add an object” pages in Django’s admin site as repre-
sented by a URLpattern like this:
qnhl]ppanjo9l]ppanjo$##(
***
$#Z$WZ+Y'%+$WZ+Y'%+]``+ #(reaso*]``[op]ca%(
***
%
This matches URLs such as +iu^hkc+ajpneao+]``+ and +]qpd+cnkqlo+]``+. However, the
“add” page for a user object (+]qpd+qoan+]``+) is a special case—it doesn’t display all of the
form fields, it displays two password fields, and so forth. We could solve this problem by spe-
cial-casing in the view, like so:
CHAPTER 8 N ADVANCED VIEWS AND URLCONFS 157
`ab]``[op]ca$namqaop(]ll[h]^ah(ik`ah[j]ia%6
eb]ll[h]^ah99#]qpd#]j`ik`ah[j]ia99#qoan#6
`kola_e]h)_]oa_k`a
ahoa6
`kjkni]h_k`a
but that’s inelegant for a reason we’ve touched on multiple times in this chapter: it puts URL
logic in the view. As a more elegant solution, we can take advantage of the fact that URLconfs
are processed in order from top to bottom:
qnhl]ppanjo9l]ppanjo$##(
***
$#Z]qpd+qoan+]``+ #(reaso*qoan[]``[op]ca%(
$#Z$WZ+Y'%+$WZ+Y'%+]``+ #(reaso*]``[op]ca%(
***
%
With this in place, a request to +]qpd+qoan+]``+ will be handled by the qoan[]``[op]ca
view. Although that URL matches the second pattern, it matches the top one first. (This is
short-circuit logic.)
Capturing Text in URLs
Each captured argument is sent to the view as a plain Python Unicode string, regardless of
what sort of match the regular expression makes. For example, in this URLconf line, the ua]n
argument to reaso*ua]n[]n_dera$% will be a string, not an integer, even though X`w0y will only
match integer strings:
$n#Z]npe_hao+$;L8ua]n:X`w0y%+ #(reaso*ua]n[]n_dera%(
This is important to keep in mind when you’re writing view code. Many built-in Python
functions are fussy (and rightfully so) about accepting only objects of a certain type. A com-
mon error is to attempt to create a `]papeia*`]pa object with string values instead of integer
values:
:::eilknp`]papeia
:::`]papeia*`]pa$#-55/#(#3#(#5#%
Pn]_a^]_g$ikopna_ajp_]hhh]op%6
***
PulaAnnkn6]jejpacaneonamqena`
:::`]papeia*`]pa$-55/(3(5%
`]papeia*`]pa$-55/(3(5%
Translated to a URLconf and view, the error looks like this:
qnho*lu
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnkiiuoepaeilknpreaso
CHAPTER 8 N ADVANCED VIEWS AND URLCONFS
158
qnhl]ppanjo9l]ppanjo$##(
$n#Z]npe_hao+$X`w0y%+$X`w.y%+$X`w.y%+ #(reaso*`]u[]n_dera%(
%
reaso*lu
eilknp`]papeia
`ab`]u[]n_dera$namqaop(ua]n(ikjpd(`]u%6
Pdabkhhksejcop]paiajpn]eoao]PulaAnnkn
`]pa9`]papeia*`]pa$ua]n(ikjpd(`]u%
Instead, `]u[]n_dera$% can be written correctly like this:
`ab`]u[]n_dera$namqaop(ua]n(ikjpd(`]u%6
`]pa9`]papeia*`]pa$ejp$ua]n%(ejp$ikjpd%(ejp$`]u%%
Note that ejp$% itself raises a R]hqaAnnkn when you pass it a string that is not composed
solely of digits, but we’re avoiding that error in this case because the regular expression in our
URLconf has ensured that only strings containing digits are passed to the view function.
Determining What the URLconf Searches Against
When a request comes in, Django tries to match the URLconf patterns against the requested
URL, as a Python string. This does not include CAP or LKOP parameters, or the domain name. It
also does not include the leading slash, because every URL has a leading slash.
For example, in a request to dppl6++sss*at]ilha*_ki+iu]ll+, Django will try to match
iu]ll+. In a request to dppl6++sss*at]ilha*_ki+iu]ll+;l]ca9/, Django will try to match iu]ll+.
The request method (e.g., LKOP, CAP) is not taken into account when traversing the URL-
conf. In other words, all request methods will be routed to the same function for the same
URL. It’s the responsibility of a view function to perform branching based on the request
method.
Higher-Level Abstractions of View Functions
And speaking of branching based on the request method, let’s take a look at how we might
build a nice way of doing that. Consider this URLconf/view layout:
qnho*lu
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnkiiuoepaeilknpreaso
qnhl]ppanjo9l]ppanjo$##(
***
$n#Zokial]ca+ #(reaso*okia[l]ca%(
***
%
reaso*lu
CHAPTER 8 N ADVANCED VIEWS AND URLCONFS 159
bnki`f]jck*dppleilknpDppl0,0(DpplNaolkjoaNa`ena_p
bnki`f]jck*odknp_qpoeilknpnaj`an[pk[naolkjoa
`abokia[l]ca$namqaop%6
ebnamqaop*iapdk`99#LKOP#6
`k[okiapdejc[bkn[lkop$%
napqnjDpplNaolkjoaNa`ena_p$#+okiaqnh+#%
ahebnamqaop*iapdk`99#CAP#6
`k[okiapdejc[bkn[cap$%
napqnjnaj`an[pk[naolkjoa$#l]ca*dpih#%
ahoa6
n]eoaDppl0,0$%
In this example, the okia[l]ca$% view’s handling of LKOP vs. CAP requests is quite different.
The only thing they have in common is a shared URL: +okial]ca+. As such, it’s kind of inel-
egant to deal with both LKOP and CAP in the same view function. It would be nice if we could
have two separate view functions—one handling CAP requests and the other handling LKOP
and ensuring that each one was called only when appropriate.
We can do that by writing a view function that delegates to other views, either before or
after executing some custom logic. Here’s an example of how this technique could help sim-
plify our okia[l]ca$% view:
reaso*lu
bnki`f]jck*dppleilknpDppl0,0(DpplNaolkjoaNa`ena_p
bnki`f]jck*odknp_qpoeilknpnaj`an[pk[naolkjoa
`abiapdk`[olheppan$namqaop(CAP9Jkja(LKOP9Jkja%6
ebnamqaop*iapdk`99#CAP#]j`CAPeojkpJkja6
napqnjCAP$namqaop%
ahebnamqaop*iapdk`99#LKOP#]j`LKOPeojkpJkja6
napqnjLKOP$namqaop%
n]eoaDppl0,0
`abokia[l]ca[cap$namqaop%6
]ooanpnamqaop*iapdk`99#CAP#
`k[okiapdejc[bkn[cap$%
napqnjnaj`an[pk[naolkjoa$#l]ca*dpih#%
`abokia[l]ca[lkop$namqaop%6
]ooanpnamqaop*iapdk`99#LKOP#
`k[okiapdejc[bkn[lkop$%
napqnjDpplNaolkjoaNa`ena_p$#+okiaqnh+#%
qnho*lu
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnkiiuoepaeilknpreaso
CHAPTER 8 N ADVANCED VIEWS AND URLCONFS
160
qnhl]ppanjo9l]ppanjo$##(
***
$n#Zokial]ca+ #(reaso*iapdk`[olheppan(
w#CAP#6reaso*okia[l]ca[cap(#LKOP#6reaso*okia[l]ca[lkopy%(
***
%
Let’s go through what this does:
Ê UÊ 7iÊÜÀÌiÊ>ÊiÜÊÛiÜ]Êiapdk`[olheppan$%, that delegates to other views based on
namqaop*iapdk`. It looks for two keyword arguments, CAP and LKOP, which should be
view functions. If namqaop*iapdk` is #CAP#, it calls the CAP view. If namqaop*iapdk` is
#LKOP#, it calls the LKOP view. If namqaop*iapdk` is something else (DA=@, and so on), or if
CAP or LKOP were not supplied to the function, it raises an Dppl0,0.
Ê UÊ ÊÌiÊ1,Vv]ÊÜiÊ«ÌÊ+okial]ca+ at iapdk`[olheppan$% and pass it extra arguments—
the view functions to use for CAP and LKOP, respectively.
Ê UÊ >Þ]ÊÜiÊëÌÊÌiÊokia[l]ca$% view into two view functions: okia[l]ca[cap$% and
okia[l]ca[lkop$%. This is much nicer than shoving all that logic into a single view.
NNote These view functions technically no longer have to check namqaop*iapdk` because iapdk`[
olheppan$% does that. (By the time okia[l]ca[lkop$% is called, for example, we can be confident that
namqaop*iapdk` is #LKOP#.) Still, just to be safe, and also to serve as documentation, we stuck in an
]ooanp, ensuring that namqaop*iapdk` is what we expect it to be.
Now we have a nice generic view function that encapsulates the logic of delegating a view
by namqaop*iapdk`. Nothing about iapdk`[olheppan$% is tied to our specific application, of
course, so we can reuse it in other projects.
But there’s one way to improve on iapdk`[olheppan$%. As it’s written, it assumes that the
CAP and LKOP views take no arguments other than namqaop. What if we wanted to use iapdk`[
olheppan$% with views that, for example, capture text from URLs or take optional keyword
arguments?
To do that, we can use a nice Python feature: variable arguments with asterisks. We’ll
show the example first and then explain it:
`abiapdk`[olheppan$namqaop(&]nco(&&gs]nco%6
cap[reas9gs]nco*lkl$#CAP#(Jkja%
lkop[reas9gs]nco*lkl$#LKOP#(Jkja%
ebnamqaop*iapdk`99#CAP#]j`cap[reaseojkpJkja6
napqnjcap[reas$namqaop(&]nco(&&gs]nco%
ahebnamqaop*iapdk`99#LKOP#]j`lkop[reaseojkpJkja6
napqnjlkop[reas$namqaop(&]nco(&&gs]nco%
n]eoaDppl0,0
CHAPTER 8 N ADVANCED VIEWS AND URLCONFS 161
Here, we refactored iapdk`[olheppan$% to remove the CAP and LKOP keyword arguments in
favor of &]nco and &&gs]nco (note the asterisks). This is a Python feature that allows a function
to accept a dynamic arbitrary number of arguments whose names aren’t known until runtime.
If you put a single asterisk in front of a parameter in a function definition, any positional argu-
ments to that function will be rolled up into a single tuple. If you put two asterisks in front of
a parameter in a function definition, any keyword arguments to that function will be rolled up
into a single dictionary.
For example, note this function:
`abbkk$&]nco(&&gs]nco%6
lnejpLkoepekj]h]ncqiajpo]na6
lnejp]nco
lnejpGauskn`]ncqiajpo]na6
lnejpgs]nco
Here’s how it would work:
:::bkk$-(.(/%
Lkoepekj]h]ncqiajpo]na6
$-(.(/%
Gauskn`]ncqiajpo]na6
wy
:::bkk$-(.(j]ia9#=`ne]j#(bn]iaskng9#@f]jck#%
Lkoepekj]h]ncqiajpo]na6
$-(.%
Gauskn`]ncqiajpo]na6
w#bn]iaskng#6#@f]jck#(#j]ia#6#=`ne]j#y
Bringing this back to iapdk`[olheppan$%, you can see we’re using &]nco and &&gs]nco to
accept any arguments to the function and pass them along to the appropriate view. But before
we do that, we make two calls to gs]nco*lkl$% to get the CAP and LKOP arguments, if they’re
available. (We’re using lkl$% with a default value of Jkja to avoid GauAnnkn if one or the other
isn’t defined.)
Wrapping View Functions
Our final view trick takes advantage of an advanced Python technique. Suppose that you find
yourself repeating a bunch of code throughout various views, as in this example:
`abiu[reas-$namqaop%6
ebjkpnamqaop*qoan*eo[]qpdajpe_]pa`$%6
napqnjDpplNaolkjoaNa`ena_p$#+]__kqjpo+hkcej+#%
***
napqnjnaj`an[pk[naolkjoa$#pailh]pa-*dpih#%
`abiu[reas.$namqaop%6
ebjkpnamqaop*qoan*eo[]qpdajpe_]pa`$%6
napqnjDpplNaolkjoaNa`ena_p$#+]__kqjpo+hkcej+#%
***
napqnjnaj`an[pk[naolkjoa$#pailh]pa.*dpih#%
CHAPTER 8 N ADVANCED VIEWS AND URLCONFS
162
`abiu[reas/$namqaop%6
ebjkpnamqaop*qoan*eo[]qpdajpe_]pa`$%6
napqnjDpplNaolkjoaNa`ena_p$#+]__kqjpo+hkcej+#%
***
napqnjnaj`an[pk[naolkjoa$#pailh]pa/*dpih#%
Here, each view starts by checking that namqaop*qoan is authenticated—that is, the current
user has successfully logged into the site—and redirects to +]__kqjpo+hkcej+ if not.
NNote We haven’t yet covered namqaop*qoan—Chapter 14 does—but namqaop*qoan represents the
current user, either logged-in or anonymous.
It would be nice if we could remove that bit of repetitive code from each of these views
and just mark them as requiring authentication. We can do that by making a view wrapper.
Take a moment to study this:
`abnamqenao[hkcej$reas%6
`abjas[reas$namqaop(&]nco(&&gs]nco%6
ebjkpnamqaop*qoan*eo[]qpdajpe_]pa`$%6
napqnjDpplNaolkjoaNa`ena_p$#+]__kqjpo+hkcej+#%
napqnjreas$namqaop(&]nco(&&gs]nco%
napqnjjas[reas
This function, namqenao[hkcej, takes a view function (reas) and returns a new view func-
tion (jas[reas). The new function, jas[reas, is defined within namqenao[hkcej and handles the
logic of checking namqaop*qoan*eo[]qpdajpe_]pa`$% and delegating to the original view (reas).
Now, we can remove the ebjkpnamqaop*qoan*eo[]qpdajpe_]pa`$% checks from our views
and simply wrap them with namqenao[hkcej in our URLconf:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnkiiuoepa*reasoeilknpnamqenao[hkcej(iu[reas-(iu[reas.(iu[reas/
qnhl]ppanjo9l]ppanjo$##(
$n#Zreas-+ #(namqenao[hkcej$iu[reas-%%(
$n#Zreas.+ #(namqenao[hkcej$iu[reas.%%(
$n#Zreas/+ #(namqenao[hkcej$iu[reas/%%(
%
This has the same effect as before, but with less code redundancy. Now we’ve created a
nice generic function—namqenao[hkcej$% that we can wrap around any view in order to make
it require a login.
Including Other URLconfs
If you intend your code to be used on multiple Django-based sites, you should consider
arranging your URLconfs in such a way that allows for “including.”
CHAPTER 8 N ADVANCED VIEWS AND URLCONFS 163
At any point, your URLconf can “include” other URLconf modules. This essentially “roots”
a set of URLs below other ones. For example, this URLconf includes other URLconfs:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
qnhl]ppanjo9l]ppanjo$##(
$n#Zsa^hkc+#(ej_hq`a$#iuoepa*^hkc*qnho#%%(
$n#Zldkpko+#(ej_hq`a$#iuoepa*ldkpko*qnho#%%(
$n#Z]^kqp+ #(#iuoepa*reaso*]^kqp#%(
%
You saw this before in Chapter 6, when we introduced the Django admin site. The admin
site has its own URLconf that you merely ej_hq`a$% within yours.
There’s an important gotcha here: the regular expressions in this example that point to
an ej_hq`a$% do not have a (end-of-string match character) but do include a trailing slash.
Whenever Django encounters ej_hq`a$%, 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.
Continuing this example, here’s the URLconf iuoepa*^hkc*qnho:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
qnhl]ppanjo9l]ppanjo$##(
$n#Z$X`X`X`X`%+ #(#iuoepa*^hkc*reaso*ua]n[`ap]eh#%(
$n#Z$X`X`X`X`%+$X`X`%+ #(#iuoepa*^hkc*reaso*ikjpd[`ap]eh#%(
%
With these two URLconfs, here’s how a few sample requests would be handled:
ÊUÊ+sa^hkc+.,,3+: In the first URLconf, the pattern n#Zsa^hkc+# matches. Because it is
an ej_hq`a$%, Django strips all the matching text, which is #sa^hkc+# in this case. The
remaining part of the URL is .,,3+, which matches the first line in the iuoepa*^hkc*
qnho URLconf.
ÊUÊ+sa^hkc++.,,3+ (with two slashes): In the first URLconf, the pattern n#Zsa^hkc+#
matches. Because it is an ej_hq`a$%, Django strips all the matching text, which is
#sa^hkc+# in this case. The remaining part of the URL is +.,,3+ (with a leading slash),
which does not match any of the lines in the iuoepa*^hkc*qnho URLconf.
ÊUÊ+]^kqp+: This matches the view iuoepa*reaso*]^kqp in the first URLconf, demonstrat-
ing that you can mix ej_hq`a$% patterns with non-ej_hq`a$% patterns.
How Captured Parameters Work with include()
An included URLconf receives any captured parameters from parent URLconfs, for example:
nkkpqnho*lu
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
qnhl]ppanjo9l]ppanjo$##(
$n#Z$;L8qoanj]ia:Xs'%+^hkc+#(ej_hq`a$#bkk*qnho*^hkc#%%(
%
CHAPTER 8 N ADVANCED VIEWS AND URLCONFS
164
bkk+qnho+^hkc*lu
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
qnhl]ppanjo9l]ppanjo$##(
$n#Z #(#bkk*reaso*^hkc[ej`at#%(
$n#Z]n_dera+ #(#bkk*reaso*^hkc[]n_dera#%(
%
In this example, the captured qoanj]ia variable is passed to the included URLconf and,
hence, to every view function within that URLconf.
Note that the captured parameters will always be passed to every line in the included
URLconf, regardless of whether the line’s view actually accepts those parameters as valid. For
this reason, this technique is useful only if you’re certain that every view in the included URL-
conf accepts the parameters you’re passing.
How Extra URLconf Options Work with include()
Similarly, you can pass extra URLconf options to ej_hq`a$%, just as you can pass extra URLconf
options to a normal view—as a dictionary. When you do this, each line in the included URL-
conf will be passed the extra options.
For example, the following two URLconf sets are functionally identical.
Set one:
qnho*lu
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
qnhl]ppanjo9l]ppanjo$##(
$n#Z^hkc+#(ej_hq`a$#ejjan#%(w#^hkce`#6/y%(
%
ejjan*lu
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
qnhl]ppanjo9l]ppanjo$##(
$n#Z]n_dera+ #(#iuoepa*reaso*]n_dera#%(
$n#Z]^kqp+ #(#iuoepa*reaso*]^kqp#%(
$n#Znoo+ #(#iuoepa*reaso*noo#%(
%
Set two:
qnho*lu
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
CHAPTER 8 N ADVANCED VIEWS AND URLCONFS 165
qnhl]ppanjo9l]ppanjo$##(
$n#Z^hkc+#(ej_hq`a$#ejjan#%%(
%
ejjan*lu
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
qnhl]ppanjo9l]ppanjo$##(
$n#Z]n_dera+ #(#iuoepa*reaso*]n_dera#(w#^hkce`#6/y%(
$n#Z]^kqp+ #(#iuoepa*reaso*]^kqp#(w#^hkce`#6/y%(
$n#Znoo+ #(#iuoepa*reaso*noo#(w#^hkce`#6/y%(
%
As is the case with captured parameters (explained in the previous section), extra options
will always be passed to every line in the included URLconf, regardless of whether the line’s view
actually accepts those options as valid. For this reason, this technique is useful only if you’re
certain that every view in the included URLconf accepts the extra options you’re passing.
What’s Next?
This chapter provided many advanced tips and tricks for views and URLconfs. In Chapter 9,
we’ll give this advanced treatment to Django’s template system.
CHAPTER 9
Advanced Templates
Although most of your interactions with Django’s template language will be in the role of
template author, you may want to customize and extend the template engine—either to make
it do something it doesn’t already do, or to make your job easier in some other way.
This chapter delves deep into the guts of Django’s template system. It covers what you
need to know if you plan to extend the system or if you’re just curious about how it works. It
also covers the autoescaping feature, a security measure you’ll no doubt notice over time as
you continue to use Django.
If you’re looking to use the Django template system as part of another application (i.e.,
without the rest of the framework), make sure to read the “Configuring the Template System
in Standalone Mode” section later in the chapter.
Template Language Review
First, let’s quickly review a number of terms introduced in Chapter 4:
ÊUÊÊtemplate is a text document, or a normal Python string, that is marked up using the
>}ÊÌi«>ÌiÊ>}Õ>}i°ÊÊÌi«>ÌiÊV>ÊVÌ>ÊÌi«>ÌiÊÌ>}ÃÊ>`ÊÛ>À>Lið
ÊUÊÊtemplate tag is a symbol within a template that does something. This definition is
deliberately vague. For example, a template tag can produce content, serve as a con-
trol structure (an eb statement or a bkn loop), grab content from a database, or enable
access to other template tags.
Template tags are surrounded by w! and !y:
w!ebeo[hkcca`[ej!y
Pd]jgobknhkccejcej
w!ahoa!y
Lha]oahkcej*
w!aj`eb!y
167
CHAPTER 9 N ADVANCED TEMPLATES
168
ÊUÊÊvariable is a symbol within a template that outputs a value.
Variable tags are surrounded by ww and yy:
Iubenopj]iaeowwbenop[j]iayy*Iuh]opj]iaeowwh]op[j]iayy*
ÊUÊÊcontext is a name-value mapping (similar to a Python dictionary) that is passed to a
template.
Ê UÊ ÊÌi«>ÌiÊrenders a context by replacing the variable “holes” with values from the
context and executing all template tags.
For more details about the basics of these terms, refer back to Chapter 4.
The rest of this chapter discusses ways of extending the template engine. First, though,
let’s take a quick look at a few internals left out of Chapter 4 for simplicity.
RequestContext and Context Processors
When rendering a template, you need a context. Usually this is an instance of `f]jck*pailh]pa*
?kjpatp, but Django also comes with a special subclass, `f]jck*pailh]pa*Namqaop?kjpatp, that
acts slightly differently. Namqaop?kjpatp adds a bunch of variables to your template context by
default—things like the DpplNamqaop object or information about the currently logged-in user.
Use Namqaop?kjpatp when you don’t want to have to specify the same set of variables in a
series of templates. For example, consider these two views:
bnki`f]jck*pailh]paeilknphk]`an(?kjpatp
`abreas[-$namqaop%6
***
p9hk]`an*cap[pailh]pa$#pailh]pa-*dpih#%
_9?kjpatp$w
#]ll#6#Iu]ll#(
#qoan#6namqaop*qoan(
#el[]``naoo#6namqaop*IAP=W#NAIKPA[=@@N#Y(
#iaoo]ca#6#E]ireas-*#
y%
napqnjp*naj`an$_%
`abreas[.$namqaop%6
***
p9hk]`an*cap[pailh]pa$#pailh]pa.*dpih#%
_9?kjpatp$w
#]ll#6#Iu]ll#(
#qoan#6namqaop*qoan(
#el[]``naoo#6namqaop*IAP=W#NAIKPA[=@@N#Y(
#iaoo]ca#6#E]ipdaoa_kj`reas*#
y%
napqnjp*naj`an$_%
CHAPTER 9 N ADVANCED TEMPLATES 169
(Note that we’re deliberately not using the naj`an[pk[naolkjoa$% shortcut in these exam-
ples—we’re manually loading the templates, constructing the context objects, and rendering
the templates. We’re “spelling out” all of the steps for the purpose of clarity.)
Each view passes the same three variables—]ll, qoan, and el[]``naoo—to its template.
Wouldn’t it be nice if we could remove that redundancy?
Namqaop?kjpatp and context processors were created to solve this problem. Context proces-
sors let you specify a number of variables that get set in each context automatically—without
you having to specify the variables in each naj`an[pk[naolkjoa$% call. The catch is that you
have to use Namqaop?kjpatp instead of ?kjpatp when you render a template.
The most low-level way of using context processors is to create some processors and pass
them to Namqaop?kjpatp. Here’s how the preceding example could be written with context
processors:
bnki`f]jck*pailh]paeilknphk]`an(Namqaop?kjpatp
`ab_qopki[lnk_$namqaop%6
=_kjpatplnk_aooknpd]plnkre`ao#]ll#(#qoan#]j`#el[]``naoo#*
napqnjw
#]ll#6#Iu]ll#(
#qoan#6namqaop*qoan(
#el[]``naoo#6namqaop*IAP=W#NAIKPA[=@@N#Y
y
`abreas[-$namqaop%6
***
p9hk]`an*cap[pailh]pa$#pailh]pa-*dpih#%
_9Namqaop?kjpatp$namqaop(w#iaoo]ca#6#E]ireas-*#y(
lnk_aookno9W_qopki[lnk_Y%
napqnjp*naj`an$_%
`abreas[.$namqaop%6
***
p9hk]`an*cap[pailh]pa$#pailh]pa.*dpih#%
_9Namqaop?kjpatp$namqaop(w#iaoo]ca#6#E]ipdaoa_kj`reas*#y(
lnk_aookno9W_qopki[lnk_Y%
napqnjp*naj`an$_%
Let’s step through this code:
Ê UÊ ÀÃÌ]ÊÜiÊ`iviÊ>ÊvÕVÌÊ_qopki[lnk_. This is a context processor—it takes an
DpplNamqaop object and returns a dictionary of variables to use in the template context.
That’s all it does.
Ê UÊ 7i½ÛiÊV>}i`ÊÌiÊÌÜÊÛiÜÊvÕVÌÃÊÌÊÕÃiÊNamqaop?kjpatp instead of ?kjpatp.
There are two differences in how the context is constructed. First, Namqaop?kjpatp
requires the first argument to be an DpplNamqaop object—the one that was passed into
the view function in the first place (namqaop). Second, Namqaop?kjpatp takes an optional
lnk_aookno argument, which is a list or tuple of context processor functions to use.
Here, we pass in _qopki[lnk_, the custom processor we defined earlier.
CHAPTER 9 N ADVANCED TEMPLATES
170
Ê UÊ >VÊÛiÜÊÊ}iÀÊ>ÃÊÌÊVÕ`iÊ]ll, qoan, or el[]``naoo in its context construction,
because those are provided by _qopki[lnk_.
Ê UÊ >VÊÛiÜÊstill has the flexibility to introduce any custom template variables it might
need. In this example, the iaoo]ca template variable is set differently in each view.
In Chapter 4, we introduced the naj`an[pk[naolkjoa$% shortcut, which saves you from
having to call hk]`an*cap[pailh]pa$%, then create a ?kjpatp, then call the naj`an$% method
on the template. In order to demonstrate the lower-level workings of context processors, the
previous examples didn’t use naj`an[pk[naolkjoa$%. But it’s possible—and preferable—to use
context processors with naj`an[pk[naolkjoa$%. Do this with the _kjpatp[ejop]j_a argument,
like so:
bnki`f]jck*odknp_qpoeilknpnaj`an[pk[naolkjoa
bnki`f]jck*pailh]paeilknpNamqaop?kjpatp
`ab_qopki[lnk_$namqaop%6
=_kjpatplnk_aooknpd]plnkre`ao#]ll#(#qoan#]j`#el[]``naoo#*
napqnjw
#]ll#6#Iu]ll#(
#qoan#6namqaop*qoan(
#el[]``naoo#6namqaop*IAP=W#NAIKPA[=@@N#Y
y
`abreas[-$namqaop%6
***
napqnjnaj`an[pk[naolkjoa$#pailh]pa-*dpih#(
w#iaoo]ca#6#E]ireas-*#y(
_kjpatp[ejop]j_a9Namqaop?kjpatp$namqaop(lnk_aookno9W_qopki[lnk_Y%%
`abreas[.$namqaop%6
***
napqnjnaj`an[pk[naolkjoa$#pailh]pa.*dpih#(
w#iaoo]ca#6#E]ipdaoa_kj`reas*#y(
_kjpatp[ejop]j_a9Namqaop?kjpatp$namqaop(lnk_aookno9W_qopki[lnk_Y%%
Here, we’ve trimmed down each view’s template-rendering code to a single (wrapped) line.
This is an improvement, but, evaluating the conciseness of this code, we have to admit
we’re now almost overdosing on the other end of the spectrum. We’ve removed redundancy
in data (our template variables) at the cost of adding redundancy in code (in the lnk_aookno
call). Using context processors doesn’t save you much typing if you have to type lnk_aookno
all the time.
For that reason, Django provides support for global context processors. The PAILH=PA[
?KJPATP[LNK?AOOKNO setting (in your oappejco*lu) designates which context processors should
always be applied to Namqaop?kjpatp. This removes the need to specify lnk_aookno each time
you use Namqaop?kjpatp.
CHAPTER 9 N ADVANCED TEMPLATES 171
By default, PAILH=PA[?KJPATP[LNK?AOOKNO is set to the following:
PAILH=PA[?KJPATP[LNK?AOOKNO9$
#`f]jck*_kna*_kjpatp[lnk_aookno*]qpd#(
#`f]jck*_kna*_kjpatp[lnk_aookno*`a^qc#(
#`f]jck*_kna*_kjpatp[lnk_aookno*e-4j#(
#`f]jck*_kna*_kjpatp[lnk_aookno*ia`e]#(
%
This setting is a tuple of callables that use the same interface as the preceding _qopki[lnk_
function—functions that take a request object as their argument and return a dictionary of
items to be merged into the context. Note that the values in PAILH=PA[?KJPATP[LNK?AOOKNO are
specified as strings, which means the processors are required to be somewhere on your Python
path (so you can refer to them from the setting).
Each processor is applied in order. That is, if one processor adds a variable to the context
and a second processor adds a variable with the same name, the second will override the first.
Django provides a number of simple context processors, including the ones that are
enabled by default.
django.core.context_processors.auth
If PAILH=PA[?KJPATP[LNK?AOOKNO contains this processor, every Namqaop?kjpatp will contain
these variables:
ÊUÊqoan\ÊÊ`f]jck*_kjpne^*]qpd*ik`aho*Qoan instance representing the current logged-in
user (or an =jkjuikqoQoan instance, if the client isn’t logged in).
ÊUÊiaoo]cao\ÊÊÃÌÊvÊiÃÃ>}iÃÊ>ÃÊÃÌÀ}îÊvÀÊÌiÊVÕÀÀiÌÊ}}i`ÊÕÃiÀ°Êi`ÊÌiÊ
scenes, this variable calls namqaop*qoan*cap[]j`[`ahapa[iaoo]cao$% for every request.
That method collects the user’s messages and deletes them from the database.
ÊUÊlanio\ÊÊÃÌ>ViÊvÊ`f]jck*_kna*_kjpatp[lnk_aookno*LaniSn]llan, which represents
the permissions the current logged-in user has.
See Chapter 14 for more information on users, permissions, and messages.
django.core.context_processors.debug
This processor pushes debugging information down to the template layer. If PAILH=PA[?KJPATP[
LNK?AOOKNO contains this processor, every Namqaop?kjpatp will contain these variables:
ÊUÊ`a^qc: The value of your @A>QC setting (either Pnqa or B]hoa). You can use this variable in
templates to test whether you’re in debug mode.
ÊUÊomh[mqaneao\ÊÊÃÌÊvÊw#omh#6***(#peia#6***y dictionaries representing every SQL
query that has happened so far during the request and how long it took. The list is in
the order in which the queries were issued.
CHAPTER 9 N ADVANCED TEMPLATES
172
Because debugging information is sensitive, this context processor will add variables to
the context only if both of the following conditions are true:
Ê UÊ /iÊ@A>QC setting is Pnqa.
Ê UÊ /iÊÀiµÕiÃÌÊV>iÊvÀÊ>Ê*Ê>``ÀiÃÃÊÊÌiÊEJPANJ=H[ELO setting.
ÃÌÕÌiÊÀi>`iÀÃÊÜÊÌViÊÌ>ÌÊÌiÊ`a^qc template variable will never have the value B]hoa
because if @A>QC is B]hoa, the `a^qc template variable won’t be populated in the first place.
django.core.context_processors.i18n
If this processor is enabled, every Namqaop?kjpatp will contain these variables:
ÊUÊH=JCQ=CAO: The value of the H=JCQ=CAO setting.
ÊUÊH=JCQ=CA[?K@A: namqaop*H=JCQ=CA[?K@A if it exists; otherwise, the value of the H=JCQ=CA[
?K@A setting.
««i`ÝÊÊ«ÀÛ`iÃÊÀiÊvÀ>ÌÊ>LÕÌ these two settings.
django.core.context_processors.request
If this processor is enabled, every Namqaop?kjpatp will contain a variable namqaop, which is the
current DpplNamqaop object. Note that this processor is not enabled by default; you have to
activate it.
You might want to use this if you find your templates needing to access attributes of the
current DpplNamqaop such as the IP address:
wwnamqaop*NAIKPA[=@@Nyy
Guidelines for Writing Your Own Context Processors
Here are a few tips for rolling your own:
Ê UÊ >iÊi>VÊVÌiÝÌÊ«ÀViÃÃÀÊÀiëÃLiÊvÀÊÌiÊÃ>iÃÌÊÃÕLÃiÌÊvÊvÕVÌ>ÌÞÊ
possible. It’s easy to use multiple processors, so you might as well split functionality
into logical pieces for future reuse.
Ê UÊ ii«ÊÊ`ÊÌ>ÌÊ>ÞÊVÌiÝÌÊ«ÀViÃÃÀÊÊPAILH=PA[?KJPATP[LNK?AOOKNO will be
available in every template powered by that settings file, so try to pick variable names
that are unlikely to conflict with variable names your templates might be using inde-
pendently. Because variable names are case-sensitive, it’s not a bad idea to use all
uppercase letters for variables that a processor provides.
Ê UÊ ÌÊ`iÃ½ÌÊ>ÌÌiÀÊÜiÀiÊÊÌiÊviÃÞÃÌiÊÌiÊ«ÀViÃÃÀÃÊÛi]Ê>ÃÊ}Ê>ÃÊÌiÞ½ÀiÊÊÞÕÀÊ
Python path so you can point to them from the PAILH=PA[?KJPATP[LNK?AOOKNO setting.
With that said, the convention is to save them in a file called _kjpatp[lnk_aookno*lu
within your app or project.
CHAPTER 9 N ADVANCED TEMPLATES 173
Automatic HTML Escaping
When generating HTML from templates, there’s always a risk that a variable will include char-
acters that affect the resulting HTML. For example, consider this template fragment:
Dahhk(wwj]iayy*
ÌÊvÀÃÌ]ÊÌÊÃiiÃÊiÊ>Ê>ÀiÃÃÊÜ>ÞÊÌÊ`ë>ÞÊ>ÊÕÃiÀ½ÃÊ>i]ÊLÕÌÊVÃ`iÀÊÜ>ÌÊÜÕ`Ê
happen if the user entered his name this way:
8o_nelp:]hanp$#dahhk#%8+o_nelp:
With this name value, the template would be rendered as follows:
Dahhk(8o_nelp:]hanp$#dahhk#%8+o_nelp:
This means the browser would display a JavaScript alert box! Similarly, what if the name
contained a #8# symbol, like this?
8^:qoanj]ia
It would result in a rendered template like this:
Dahhk(8^:qoanj]ia
This, in turn, would result in the remainder of the Web page being bold!
Clearly, user-submitted data shouldn’t be trusted blindly and inserted directly into your
Web pages because a malicious user could use this kind of hole to do potentially bad things.
This type of security exploit is called a cross-site scripting (XSS) attack.
NTip For more on security, see Chapter 20.
To avoid this problem, you have two options:
Ê UÊ 9ÕÊV>Ê>iÊÃÕÀiÊÌÊÀÕÊi>VÊÕÌÀÕÃÌi`ÊÛ>À>LiÊÌÀÕ}ÊÌiÊao_]la filter, which
converts potentially harmful HTML characters to unharmful ones. This was the default
solution in Django for its first few years, but the problem is that it puts the onus on you,
the developer/template author, to ensure that you’re escaping everything. It’s easy to
forget to escape data.
Ê UÊ 9ÕÊV>ÊÌ>iÊ>`Û>Ì>}iÊvÊ>}½ÃÊ>ÕÌ>ÌVÊ/ÊiÃV>«}°Ê/iÊÀi>`iÀÊvÊÌÃÊ
section describes how autoescaping works.
CHAPTER 9 N ADVANCED TEMPLATES
174
By default, in Django every template automatically escapes the output of every variable
tag. Specifically, these five characters are escaped:
8 is converted to "hp7
: is converted to "cp7
# (single quote) is converted to "/57
(double quote) is converted to "mqkp7
" is converted to "]il7
}>]ÊÜiÊÃÌÀiÃÃÊÌ>ÌÊÌÃÊLi>ÛÀÊÃÊÊLÞÊ`iv>ÕÌ°ÊvÊÞÕ½ÀiÊÕÃ}Ê>}½ÃÊÌi«>ÌiÊÃÞÃ-
tem, you’re protected.
How to Turn It Off
If you don’t want data to be autoescaped on a per-site, per-template, or per-variable level, you
can turn it off in several ways.
Why would you want to turn it off? Because sometimes template variables contain data
that you intend to be rendered as raw HTML, in which case you don’t want their contents to be
escaped. For example, you might store a blob of trusted HTML in your database and want to
embed it directly into your template. Or you might be using Django’s template system to pro-
duce text that is not HTML—like an e-mail message, for instance.
For Individual Variables
To disable autoescaping for an individual variable, use the o]ba filter:
Pdeosehh^aao_]la`6ww`]p]yy
Pdeosehhjkp^aao_]la`6ww`]p]xo]bayy
Think of safe as shorthand for safe from further escaping or can be safely interpreted as
HTML. In this example, if `]p] contains #8^:#, the output will be the following:
Pdeosehh^aao_]la`6"hp7^"cp7
Pdeosehhjkp^aao_]la`68^:
For Template Blocks
To control autoescaping for a template, wrap the template (or just a particular section of the
template) in the ]qpkao_]la tag, like so:
w!]qpkao_]lakbb!y
Dahhkwwj]iayy
w!aj`]qpkao_]la!y
CHAPTER 9 N ADVANCED TEMPLATES 175
The ]qpkao_]la tag takes either kj or kbbÊ>ÃÊÌÃÊ>À}ÕiÌ°ÊÌÊÌiÃ]ÊÞÕÊ}ÌÊÜ>ÌÊÌÊ
force autoescaping when it would otherwise be disabled. Here is an example template:
=qpkao_]lejceokj^u`ab]qhp*Dahhkwwj]iayy
w!]qpkao_]lakbb!y
Pdeosehhjkp^a]qpkao_]la`6ww`]p]yy*
Jknpdeo6wwkpdan[`]p]yy
w!]qpkao_]lakj!y
=qpkao_]lejc]llheao]c]ej6wwj]iayy
w!aj`]qpkao_]la!y
w!aj`]qpkao_]la!y
The autoescaping tag passes its effect on to templates that extend the current one as well
as templates included via the ej_hq`a tag, just like all block tags. For example:
^]oa*dpih
w!]qpkao_]lakbb!y
8d-:w!^hk_gpepha!yw!aj`^hk_g!y8+d-:
w!^hk_g_kjpajp!y
w!aj`^hk_g!y
w!aj`]qpkao_]la!y
_deh`*dpih
w!atpaj`o^]oa*dpih!y
w!^hk_gpepha!yPdeo"pd]pw!aj`^hk_g!y
w!^hk_g_kjpajp!ywwcnaapejcyyw!aj`^hk_g!y
Because autoescaping is turned off in the base template, it will also be turned off in the
child template, resulting in the following rendered HTML when the cnaapejc variable contains
the string 8^:Dahhk8+^::
8d-:Pdeo"pd]p8+d-:
8^:Dahhk8+^:
Notes
Template authors usually don’t need to worry about autoescaping very much. Developers
on the Python side (people writing views and custom filters) need to think about the cases in
which data shouldn’t be escaped, and mark data appropriately, so things work in the template.
If you’re creating a template that might be used in situations in which you’re not sure
whether autoescaping is enabled, add an ao_]la filter to any variable that needs escaping.
When autoescaping is on, there’s no danger of the ao_]la filter double-escaping data—the
ao_]la filter does not affect autoescaped variables.
CHAPTER 9 N ADVANCED TEMPLATES
176
Automatic Escaping of String Literals in Filter Arguments
ÃÊiÌi` earlier, filter arguments can be strings:
ww`]p]x`ab]qhp6Pdeoeo]opnejchepan]h*yy
ÊÃÌÀ}ÊÌiÀ>ÃÊ>ÀiÊÃiÀÌi`Êwithout any automatic escaping into the template—they act
as if they were all passed through the o]ba filter. The reasoning behind this is that the template
author is in control of what goes into the string literal, so they can make sure the text is cor-
rectly escaped when the template is written.
This means you would write the following:
ww`]p]x`ab]qhp6/"hp7.yy
instead of the following:
ww`]p]x`ab]qhp6/8.yy8))>]`@kj#p`kpdeo*
This doesn’t affect what happens to data coming from the variable itself. The variable’s
contents are still automatically escaped, if necessary, because they’re beyond the control of
the template author.
Inside Template Loading
Generally, you’ll store templates in files on your filesystem, but you can use custom template
loaders to load templates from other sources.
Django has two ways to load templates:
ÊUÊ`f]jck*pailh]pa*hk]`an*cap[pailh]pa$pailh]pa[j]ia%: cap[pailh]pa returns the com-
piled template (a Pailh]pa object) for the template with the given name. If the template
doesn’t exist, a Pailh]pa@kaoJkpAteop exception will be raised.
ÊUÊ`f]jck*pailh]pa*hk]`an*oaha_p[pailh]pa$pailh]pa[j]ia[heop%: oaha_p[pailh]pa is
just like cap[pailh]pa, except it takes a list of template names. Of the list, it returns the
first template that exists. If none of the templates exist, a Pailh]pa@kaoJkpAteop excep-
tion will be raised.
ÃÊVÛiÀi`ÊÊ>«ÌiÀÊ{]Êi>VÊvÊÌiÃiÊvÕVÌÃÊLÞÊ`iv>ÕÌÊÕÃiÃÊÞÕÀÊPAILH=PA[@ENO set-
ting to load templates. Internally, however, these functions actually delegate to a template
loader for the heavy lifting.
Some of loaders are disabled by default, but you can activate them by editing the PAILH=PA[
HK=@ANO setting. PAILH=PA[HK=@ANO should be a tuple of strings, where each string represents a
template loader. These template loaders ship with Django:
ÊUÊ`f]jck*pailh]pa*hk]`ano*behaouopai*hk]`[pailh]pa[okqn_a: This loader loads tem-
plates from the filesystem, according to PAILH=PA[@ENO. It is enabled by default.
ÊUÊ`f]jck*pailh]pa*hk]`ano*]ll[`ena_pkneao*hk]`[pailh]pa[okqn_a: This loader
loads templates from Django applications on the filesystem. For each application in
EJOP=HHA@[=LLO, the loader looks for a pailh]pao subdirectory. If the directory exists,
Django looks for templates there.
CHAPTER 9 N ADVANCED TEMPLATES 177
This means you can store templates with your individual applications, making it easy
to distribute Django applications with default templates. For example, if EJOP=HHA@[
=LLO contains $#iulnkfa_p*lkhho#(#iulnkfa_p*iqoe_#%, then cap[pailh]pa$#bkk*
dpih#% will look for templates in this order:
ÊUÊ+l]pd+pk+iulnkfa_p+lkhho+pailh]pao+bkk*dpih
ÊUÊ+l]pd+pk+iulnkfa_p+iqoe_+pailh]pao+bkk*dpih
Note that the loader performs an optimization when it is first imported: it caches a list
of which EJOP=HHA@[=LLO packages have a pailh]pao subdirectory.
This loader is enabled by default.
ÊUÊ`f]jck*pailh]pa*hk]`ano*acco*hk]`[pailh]pa[okqn_a: This loader is just like ]ll[
`ena_pkneao, except it loads templates from Python eggs rather than from the filesystem.
This loader is disabled by default; you’ll need to enable it if you’re using eggs to distribute
your application. (Python eggs are a way of compressing Python code into a single file.)
Django uses the template loaders in order according to the PAILH=PA[HK=@ANO setting. It
uses each loader until a loader finds a match.
Extending the Template System
Now that you understand a bit more about the internals of the template system, let’s look at
how to extend the system with custom code.
Most template customization comes in the form of custom template tags and/or filters.
ÌÕ}ÊÌiÊ>}ÊÌi«>ÌiÊ>}Õ>}iÊViÃÊÜÌÊ>ÞÊLÕÌÊÌ>}ÃÊ>`ÊvÌiÀÃ]ÊÞÕ½Ê«ÀL-
ably assemble your own libraries of tags and filters that fit your own needs. Fortunately, it’s
quite easy to define your own functionality.
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 is a two-step process:
1. First, decide which Django application should house the template library. If you’ve cre-
ated an app via i]j]ca*luop]np]ll, you can put it in there, or you can create another
app solely for the template library. We recommend the latter because your filters might
be useful to you in future projects.
Whichever route you take, make sure to add the app to your EJOP=HHA@[=LLO setting.
We’ll explain this shortly.
2. Second, create a pailh]pap]co directory in the appropriate Django application’s pack-
age. It should be on the same level as ik`aho*lu, reaso*lu, and so forth. For example:
^kkgo+
[[ejep[[*lu
ik`aho*lu
pailh]pap]co+
reaso*lu
CHAPTER 9 N ADVANCED TEMPLATES
178
Create two empty files in the pailh]pap]co directory: an [[ejep[[*lu file (to indicate to
Python that this is a package containing Python code) and a file that will contain your
custom tag/filter definitions. The name of the latter file is what you’ll use to load the
tags later. For example, if your custom tags/filters are in a file called lkhh[atpn]o*lu,
you’d write the following in a template:
w!hk]`lkhh[atpn]o!y
The w!hk]`!y tag looks at your EJOP=HHA@[=LLO setting and only allows the loading
of template libraries within installed Django applications. This is a security feature; it
allows you to host Python code for many template libraries on a single computer with-
out enabling access to all of them for every Django installation.
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 pailh]pap]co pack-
age. There’s no limit on how many modules you put in the pailh]pap]co package. Just keep in
mind that a w!hk]`!y statement will load tags/filters for the given Python module name, not
the name of the application.
Once you’ve created that Python module, you’ll just have to write a bit of Python code,
depending on whether you’re writing filters or tags.
To be a valid tag library, the module must contain a module-level variable named naceopan
that is an instance of pailh]pa*He^n]nu. This is the data structure in which all the tags and fil-
ters are registered. So, near the top of your module, insert the following:
bnki`f]jckeilknppailh]pa
naceopan9pailh]pa*He^n]nu$%
NNote For a fine selection of examples, read the source code for Django’s default filters and tags. They’re
in `f]jck+pailh]pa+`ab]qhpbehpano*lu and `f]jck+pailh]pa+`ab]qhpp]co*lu, respectively. Some
applications in `f]jck*_kjpne^ also contain template libraries.
Once you’ve created this naceopan variable, you’ll use it to create template filters and tags.
Writing Custom Template Filters
Custom filters are just Python functions that take one or two arguments:
Ê UÊ /iÊÛ>ÕiÊvÊÌiÊÛ>À>LiÊ«ÕÌ®
Ê UÊ /iÊÛ>ÕiÊvÊÌiÊ>À}ÕiÌ]ÊÜVÊV>Ê>ÛiÊ>Ê`iv>ÕÌÊÛ>ÕiÊÀÊLiÊivÌÊÕÌÊ>Ì}iÌiÀ
For example, in the filter wwr]nxbkk6^]nyy, the filter bkk would be passed the contents
of the variable r]n and the argument ^]n.
Filter functions should always return something. They shouldn’t raise exceptions, and
they should fail silently. If there’s an error, they should return either the original input or an
empty string, whichever makes more sense.
CHAPTER 9 N ADVANCED TEMPLATES 179
Here’s an example filter definition:
`ab_qp$r]hqa(]nc%6
Naikrao]hhr]hqaokb]ncbnkipdacerajopnejc
napqnjr]hqa*nalh]_a$]nc(##%
`ÊiÀi½ÃÊ>ÊiÝ>«iÊvÊÜÊÌ>ÌÊvÌiÀÊÜÕ`ÊLiÊÕÃi`ÊÌÊVÕÌÊë>ViÃÊvÀÊ>ÊÛ>À>Li½ÃÊ
value:
wwokiar]ne]^hax_qp6yy
Most filters don’t take arguments. In this case, just leave the argument out of your function:
`abhksan$r]hqa%6Kjhukja]ncqiajp*
?kjranpo]opnejcejpk]hhhksan_]oa
napqnjr]hqa*hksan$%
When you’ve written your filter definition, you need to register it with your He^n]nu
instance, to make it available to Django’s template language:
naceopan*behpan$#_qp#(_qp%
naceopan*behpan$#hksan#(hksan%
The He^n]nu*behpan$% method takes two arguments:
Ê UÊ /iÊ>iÊvÊÌiÊvÌiÀÊ>ÊÃÌÀ}®
Ê UÊ /iÊvÌiÀÊvÕVÌÊÌÃiv
If you’re using Python 2.4 or above, you can use naceopan*behpan$% as a decorator instead:
<naceopan*behpan$j]ia9#_qp#%
`ab_qp$r]hqa(]nc%6
napqnjr]hqa*nalh]_a$]nc(##%
<naceopan*behpan
`abhksan$r]hqa%6
napqnjr]hqa*hksan$%
If you leave off the j]ia argument, as in the second example, Django will use the func-
tion’s name as the filter name.
Here, then, is a complete template library example, supplying the _qp filter:
bnki`f]jckeilknppailh]pa
naceopan9pailh]pa*He^n]nu$%
<naceopan*behpan$j]ia9#_qp#%
`ab_qp$r]hqa(]nc%6
napqnjr]hqa*nalh]_a$]nc(##%
CHAPTER 9 N ADVANCED TEMPLATES
180
Writing Custom Template Tags
Tags are more complex than filters, because tags can do nearly anything.
Chapter 4 describes how the template system works in a two-step process: compiling and
rendering. To define a custom template tag, you need to tell Django how to manage both of
these steps when it gets to your tag.
When Django compiles a template, it splits the raw template text into nodes. Each node is
an instance of `f]jck*pailh]pa*Jk`a and has a naj`an$% method. Thus, a compiled template is
simply a list of Jk`a objects. For example, consider this template:
Dahhk(wwlanokj*j]iayy*
w!ebamq]hj]ia*^enpd`]upk`]u!y
D]llu^enpd`]u
w!ahoa!y
>aoqnapk_kia^]_gkjukqn^enpd`]u
bkn]olhaj`e`oqnlneoaiaoo]ca*
w!aj`ebamq]h!y
In compiled template form, this template is represented as this list of nodes:
Ê UÊ /iÝÌÊ`i\ÊDahhk(
Ê UÊ 6>À>LiÊ`i\Êlanokj*j]ia
Ê UÊ /iÝÌÊ`i\Ê*XjXj
Ê UÊ vµÕ>Ê`i\Êj]ia*^enpd`]u and pk`]u
When you call naj`an$% on a compiled template, the template calls naj`an$% on each
Jk`a in its node list, with the given context. The results are all concatenated together to form
the output of the template. Thus, to define a custom template tag, you specify how the raw
template tag is converted into a Jk`a (the compilation function) and what the node’s naj`an$%
method does.
In the sections that follow, we cover all the steps in writing a custom tag.
Writing the Compilation Function
For each template tag the parser encounters, it calls a Python function with the tag contents
and the parser object itself. This function is responsible for returning a Jk`a instance based on
the contents of the tag.
For example, let’s write a template tag, w!_qnnajp[peia!y, that displays the current
date/time, formatted according to a parameter given in the tag, in opnbpeia syntax (see dppl6++
sss*`f]jcklnkfa_p*_ki+n+lupdkj+opnbpeia+). It’s a good idea to decide the tag syntax before
anything else. In our case, let’s say the tag should be used like this:
8l:Pdapeiaeow!_qnnajp[peia!U)!i)!`!E6!I!l!y*8+l:
CHAPTER 9 N ADVANCED TEMPLATES 181
NNote Yes, this template tag is redundant—Django’s default w!jks!y tag does the same task with sim-
pler syntax. This template tag is presented here just for example purposes.
The parser for this function should grab the parameter and create a Jk`a object:
bnki`f]jckeilknppailh]pa
naceopan9pailh]pa*He^n]nu$%
`ab`k[_qnnajp[peia$l]noan(pkgaj%6
pnu6
olhep[_kjpajpo$%gjksojkppkolhepmqkpa`opnejco*
p]c[j]ia(bkni]p[opnejc9pkgaj*olhep[_kjpajpo$%
at_alpR]hqaAnnkn6
ioc9#!np]cnamqenao]oejcha]ncqiajp#!pkgaj*olhep[_kjpajpo$%W,Y
n]eoapailh]pa*Pailh]paOujp]tAnnkn$ioc%
napqnj?qnnajpPeiaJk`a$bkni]p[opnejcW-6)-Y%
There’s a lot going here:
Ê UÊ >VÊÌi«>ÌiÊÌ>}ÊV«>ÌÊvÕVÌÊÌ>iÃÊÌÜÊ>À}ÕiÌÃ\Êl]noan and pkgaj. l]noan
is the template parser object. We don’t use it in this example. pkgaj is the token cur-
rently being parsed by the parser.
ÊUÊpkgaj*_kjpajpo is a string of the raw contents of the tag. In our example, it’s #_qnnajp[
peia!U)!i)!`!E6!I!l#.
Ê UÊ /iÊpkgaj*olhep[_kjpajpo$% method separates the arguments on spaces while keeping
µÕÌi`ÊÃÌÀ}ÃÊÌ}iÌiÀ°ÊÛ`ÊÕÃ}Êpkgaj*_kjpajpo*olhep$% (which just uses Python’s
standard string-splitting semantics). It’s not as robust, as it naively splits on all spaces,
including those within quoted strings.
Ê UÊ /ÃÊvÕVÌÊÃÊÀiëÃLiÊvÀÊÀ>Ã}Ê`f]jck*pailh]pa*Pailh]paOujp]tAnnkn, with
helpful messages, for any syntax error.
Ê UÊ ½ÌÊ>À`V`iÊÌiÊÌ>}½ÃÊ>iÊÊÞÕÀÊiÀÀÀÊiÃÃ>}iÃ]ÊLiV>ÕÃiÊÌ>ÌÊVÕ«iÃÊÌiÊÌ>}½ÃÊ
name to your function. pkgaj*olhep[_kjpajpo$%W,Y will always be the name of your
tag—even when the tag has no arguments.
Ê UÊ /iÊvÕVÌÊÀiÌÕÀÃÊ>Ê?qnnajpPeiaJk`a (which we’ll create shortly) containing every-
thing the node needs to know about this tag. In this case, it just passes the argument
!U)!i)!`!E6!I!l. The leading and trailing quotes from the template tag are
removed with bkni]p[opnejcW-6)-Y.
Ê UÊ /i«>ÌiÊÌ>}ÊV«>Ì functions must return a Jk`a subclass; any other return value
is an error.
CHAPTER 9 N ADVANCED TEMPLATES
182
Writing the Template Node
The second step in writing custom tags is to define a Jk`a subclass that has a naj`an$% method.
Continuing the preceding example, we need to define ?qnnajpPeiaJk`a:
eilknp`]papeia
_h]oo?qnnajpPeiaJk`a$pailh]pa*Jk`a%6
`ab[[ejep[[$oahb(bkni]p[opnejc%6
oahb*bkni]p[opnejc9opn$bkni]p[opnejc%
`abnaj`an$oahb(_kjpatp%6
jks9`]papeia*`]papeia*jks$%
napqnjjks*opnbpeia$oahb*bkni]p[opnejc%
These two functions ([[ejep[[$% and naj`an$%) map directly to the two steps in template
processing (compilation and rendering). Thus, the initialization function only needs to store
the format string for later use, and the naj`an$% function does the real work.
Like template filters, these rendering functions should fail silently instead of raising errors.
The only time that template tags are allowed to raise errors is at compilation time.
Registering the Tag
Finally, you need to register the tag with your module’s He^n]nu instance. Registering custom
tags is very similar to registering custom filters (as explained previously). Just instantiate a
pailh]pa*He^n]nu instance and call its p]c$% method. For example:
naceopan*p]c$#_qnnajp[peia#(`k[_qnnajp[peia%
The p]c$% method takes two arguments:
Ê UÊ /iÊ>iÊvÊÌiÊÌi«>ÌiÊÌ>}ÊÃÌÀ}®°
Ê UÊ /iÊV«>ÌÊvÕVÌ°
ÃÊÜÌÊvÌiÀÊÀi}ÃÌÀ>Ì]ÊÌÊÃÊ>ÃÊ«ÃÃLiÊÌÊÕÃiÊnaceopan*p]c as a decorator in Python
2.4 and above:
<naceopan*p]c$j]ia9_qnnajp[peia%
`ab`k[_qnnajp[peia$l]noan(pkgaj%6
***
<naceopan*p]c
`abodkqp$l]noan(pkgaj%6
***
If you leave off the j]ia argument, as in the second example, Django will use the func-
tion’s name as the tag name.
CHAPTER 9 N ADVANCED TEMPLATES 183
Setting a Variable in the Context
The previous section’s example simply returned a value. Often it’s useful to set template vari-
ables instead of returning values. That way, template authors can just use the variables that
your template tags set.
To set a variable in the context, use dictionary assignment on the context object in the
naj`an$% method. Here’s an updated version of ?qnnajpPeiaJk`a that sets a template variable,
_qnnajp[peia, instead of returning it:
_h]oo?qnnajpPeiaJk`a.$pailh]pa*Jk`a%6
`ab[[ejep[[$oahb(bkni]p[opnejc%6
oahb*bkni]p[opnejc9opn$bkni]p[opnejc%
`abnaj`an$oahb(_kjpatp%6
jks9`]papeia*`]papeia*jks$%
_kjpatpW#_qnnajp[peia#Y9jks*opnbpeia$oahb*bkni]p[opnejc%
napqnj##
NNote We’ll leave the creation of a `k[_qnnajp[peia. function, plus the registration of that function to a
_qnnajp[peia. template tag, as exercises for you.
Note that naj`an$% returns an empty string. naj`an$% should always return a string, so if
all the template tag does is set a variable, naj`an$% should return an empty string.
Here’s how you’d use this new version of the tag:
w!_qnnajp[peia.!U)!I)!`!E6!I!l!y
8l:Pdapeiaeoww_qnnajp[peiayy*8+l:
But there’s a problem with ?qnnajpPeiaJk`a.: the variable name _qnnajp[peia is hard-
coded. This means you’ll need to make sure your template doesn’t use ww_qnnajp[peiayy
anywhere else, because w!_qnnajp[peia.!y will blindly overwrite that variable’s value.
ÊVi>iÀÊÃÕÌÊÃÊÌÊ>iÊÌiÊÌi«>ÌiÊÌ>}ÊëiVvÞÊÌiÊ>iÊvÊÌiÊÛ>À>LiÊÌÊLiÊÃiÌ]Ê
like so:
w!cap[_qnnajp[peia!U)!I)!`!E6!I!l]oiu[_qnnajp[peia!y
8l:Pda_qnnajppeiaeowwiu[_qnnajp[peiayy*8+l:
To do so, you’ll need to refactor both the compilation function and the Jk`a class, as
follows:
eilknpna
_h]oo?qnnajpPeiaJk`a/$pailh]pa*Jk`a%6
`ab[[ejep[[$oahb(bkni]p[opnejc(r]n[j]ia%6
oahb*bkni]p[opnejc9opn$bkni]p[opnejc%
oahb*r]n[j]ia9r]n[j]ia
CHAPTER 9 N ADVANCED TEMPLATES
184
`abnaj`an$oahb(_kjpatp%6
jks9`]papeia*`]papeia*jks$%
_kjpatpWoahb*r]n[j]iaY9jks*opnbpeia$oahb*bkni]p[opnejc%
napqnj##
`ab`k[_qnnajp[peia$l]noan(pkgaj%6
Pdeoranoekjqoao]nacqh]natlnaooekjpkl]noap]c_kjpajpo*
pnu6
Olheppejc^uJkja99olheppejc^uol]_ao*
p]c[j]ia(]nc9pkgaj*_kjpajpo*olhep$Jkja(-%
at_alpR]hqaAnnkn6
ioc9#!np]cnamqenao]ncqiajpo#!pkgaj*_kjpajpoW,Y
n]eoapailh]pa*Pailh]paOujp]tAnnkn$ioc%
i9na*oa]n_d$n#$*&;%]o$Xs'%#(]nc%
ebi6
bip(r]n[j]ia9i*cnkqlo$%
ahoa6
ioc9#!np]cd]`ejr]he`]ncqiajpo#!p]c[j]ia
n]eoapailh]pa*Pailh]paOujp]tAnnkn$ioc%
ebjkp$bipW,Y99bipW)-Y]j`bipW,Yej$##(#%%6
ioc9!np]c#o]ncqiajpodkqh`^aejmqkpao!p]c[j]ia
n]eoapailh]pa*Pailh]paOujp]tAnnkn$ioc%
napqnj?qnnajpPeiaJk`a/$bipW-6)-Y(r]n[j]ia%
Now `k[_qnnajp[peia$% passes the format string and the variable name to ?qnnajpPeiaJk`a/.
Parsing Until Another Template Tag
Template tags can work as blocks containing other tags (such as w!eb!y, w!bkn!y, etc.).
To create a template tag like this, use l]noan*l]noa$% in your compilation function.
Here’s how the standard w!_kiiajp!y tag is implemented:
`ab`k[_kiiajp$l]noan(pkgaj%6
jk`aheop9l]noan*l]noa$$#aj`_kiiajp#(%%
l]noan*`ahapa[benop[pkgaj$%
napqnj?kiiajpJk`a$%
_h]oo?kiiajpJk`a$pailh]pa*Jk`a%6
`abnaj`an$oahb(_kjpatp%6
napqnj##
l]noan*l]noa$% takes a tuple of names of template tags to parse until. It returns an
instance of `f]jck*pailh]pa*Jk`aHeop, which is a list of all Jk`a objects that the parser
encountered before it encountered any of the tags named in the tuple.
So in the preceding example, jk`aheop is a list of all nodes between w!_kiiajp!y and
w!aj`_kiiajp!y, not counting w!_kiiajp!y and w!aj`_kiiajp!y themselves.
CHAPTER 9 N ADVANCED TEMPLATES 185
vÌiÀÊl]noan*l]noa$% is called, the parser hasn’t yet “consumed” the w!aj`_kiiajp!y
tag, so the code needs to explicitly call l]noan*`ahapa[benop[pkgaj$% to prevent that tag from
being processed twice.
Then ?kiiajpJk`a*naj`an$% simply returns an emptyÊÃÌÀ}°ÊÞÌ}ÊLiÌÜiiÊ
w!_kiiajp!y and w!aj`_kiiajp!y is ignored.
Parsing Until Another Template Tag and Saving Contents
In the previous example, `k[_kiiajp$% discarded everything between w!_kiiajp!y and
w!aj`_kiiajp!y. It’s also possible to do something with the code between template tags
instead.
For example, here’s a custom template tag, w!qllan!y, that capitalizes everything
between itself and w!aj`qllan!y:
w!qllan!y
Pdeosehh]lla]nejqllan_]oa(wwqoan[j]iayy*
w!aj`qllan!y
ÃÊÊÌiÊ«ÀiÛÕÃÊiÝ>«i]ÊÜi½ÊÕÃiÊl]noan*l]noa$%. This time, we pass the resulting
jk`aheop to Jk`a:
`ab`k[qllan$l]noan(pkgaj%6
jk`aheop9l]noan*l]noa$$#aj`qllan#(%%
l]noan*`ahapa[benop[pkgaj$%
napqnjQllanJk`a$jk`aheop%
_h]ooQllanJk`a$pailh]pa*Jk`a%6
`ab[[ejep[[$oahb(jk`aheop%6
oahb*jk`aheop9jk`aheop
`abnaj`an$oahb(_kjpatp%6
kqplqp9oahb*jk`aheop*naj`an$_kjpatp%
napqnjkqplqp*qllan$%
The only new concept here is oahb*jk`aheop*naj`an$_kjpatp% in QllanJk`a*naj`an$%.
This simply calls naj`an$% on each Jk`a in the node list.
For more examples of complex rendering, see the source code for w!eb!y, w!bkn!y,
w!ebamq]h!y, and w!eb_d]jca`!y. They live in `f]jck+pailh]pa+`ab]qhpp]co*lu.
Shortcut for Simple Tags
Many template tags take a single argument—a string or a template variable reference—and
return a string after doing some processing based solely on the input argument and some
external information. For example, the _qnnajp[peia tag we wrote earlier is of this variety.
We give it a format string, and it returns the time as a string.
To ease the creation of these types of tags, Django provides a helper function, oeilha[p]c.
This function, which is a method of `f]jck*pailh]pa*He^n]nu, takes a function that accepts
one argument, wraps it in a naj`an function and the other necessary bits mentioned previ-
ously, and registers it with the template system.
CHAPTER 9 N ADVANCED TEMPLATES
186
Our earlier _qnnajp[peia function could thus be written like this:
`ab_qnnajp[peia$bkni]p[opnejc%6
pnu6
napqnj`]papeia*`]papeia*jks$%*opnbpeia$opn$bkni]p[opnejc%%
at_alpQje_k`aAj_k`aAnnkn6
napqnj##
naceopan*oeilha[p]c$_qnnajp[peia%
In Python 2.4, the decorator syntax also works:
<naceopan*oeilha[p]c
`ab_qnnajp[peia$pkgaj%6
***
Notice a couple of things about the oeilha[p]c helper function:
Ê UÊ "ÞÊÌiÊÃ}i®Ê>À}ÕiÌÊÃÊ«>ÃÃi`ÊÌÊÕÀÊvÕVÌ°
Ê UÊ iV}ÊvÀÊÌiÊÀiµÕÀi`ÊÕLiÀÊvÊ>À}ÕiÌÃÊ>ÃÊ>Ài>`ÞÊLiiÊ`iÊLÞÊÌiÊÌiÊÕÀÊ
function is called, so we don’t need to do that.
Ê UÊ /iʵÕÌiÃÊ>ÀÕ`ÊÌiÊ>À}ÕiÌÊvÊ>Þ®Ê>Ûi already been stripped away, so we
receive a plain Unicode string.
Inclusion Tags
ÌiÀÊV template tag is the type that displays some data by rendering another tem-
plate. For example, Django’s admin interface uses custom template tags to display the buttons
along the bottom of the “add/change” form pages. Those buttons always look the same, but
the link targets change depending on the object being edited. They’re a perfect case for using a
small template that is filled with details from the current object.
These sorts of tags are called inclusion tags. Writing inclusion tags is probably best dem-
onstrated by example. Let’s write a tag that produces a list of books for a given =qpdkn object.
We’ll use the tag like this:
w!^kkgo[bkn[]qpdkn]qpdkn!y
The result will be something like this:
8qh:
8he:Pda?]pEjPdaD]p8+he:
8he:DklKjLkl8+he:
8he:CnaajAcco=j`D]i8+he:
8+qh:
First, we define the function that takes the argument and produces a dictionary of data for
the result. Notice that we need to return only a dictionary, not anything more complex. This
will be used as the context for the template fragment:
CHAPTER 9 N ADVANCED TEMPLATES 187
`ab^kkgo[bkn[]qpdkn$]qpdkn%6
^kkgo9>kkg*k^fa_po*behpan$]qpdkno[[e`9]qpdkn*e`%
napqnjw#^kkgo#6^kkgoy
Next, we create the template used to render the tag’s output. Following our example, the
template is very simple:
8qh:
w!bkn^kkgej^kkgo!y
8he:ww^kkg*pephayy8+he:
w!aj`bkn!y
8+qh:
Finally, we create and register the inclusion tag by calling the ej_hqoekj[p]c$% method on
a He^n]nu object.
Following our example, if the preceding template is in a file called ^kkg[ojellap*dpih, we
register the tag like this:
naceopan*ej_hqoekj[p]c$#^kkg[ojellap*dpih#%$^kkgo[bkn[]qpdkn%
Python 2.4 decorator syntax works as well, so we could have written this instead:
<naceopan*ej_hqoekj[p]c$#^kkg[ojellap*dpih#%
`ab^kkgo[bkn[]qpdkn$]qpdkn%6
***
Sometimes, your inclusion tags need access to values from the parent template’s con-
text. To solve this, Django provides a p]gao[_kjpatp option for inclusion tags. If you specify
p]gao[_kjpatp in creating an inclusion tag, the tag will have no required arguments, and the
underlying Python function will have one argument: the template context as of when the tag
was called.
For example, say you’re writing an inclusion tag that will always be used in a context that
contains dkia[hejg and dkia[pepha variables that point back to the main page. Here’s what the
Python function would look like:
<naceopan*ej_hqoekj[p]c$#hejg*dpih#(p]gao[_kjpatp9Pnqa%
`abfqil[hejg$_kjpatp%6
napqnjw
#hejg#6_kjpatpW#dkia[hejg#Y(
#pepha#6_kjpatpW#dkia[pepha#Y(
y
NNote The first parameter to the function must be called _kjpatp.
The template hejg*dpih might contain the following:
Fqil`ena_phupk8]dnab9wwhejgyy:wwpephayy8+]:*
CHAPTER 9 N ADVANCED TEMPLATES
188
Then, anytime you want to use that custom tag, load its library and call it without any
arguments, like so:
w!fqil[hejg!y
Writing Custom Template Loaders
Django’s built-in template loaders (described in the “Inside Template Loading” section) will
usually cover all your template-loading needs, but it’s pretty easy to write your own if you need
special loading logic. For example, you could load templates from a database, or directly from
a Subversion repository using Subversion’s Python bindings, or (as shown shortly) from a ZIP
archive.
ÊÌi«>ÌiÊ>`iÀpÌ>ÌÊÃ]Êi>VÊiÌÀÞÊÊÌiÊPAILH=PA[HK=@ANO setting—is expected to be a
callable object with this interface:
hk]`[pailh]pa[okqn_a$pailh]pa[j]ia(pailh]pa[`eno9Jkja%
The pailh]pa[j]ia argument is the name of the template to load (as passed to hk]`an*
cap[pailh]pa$% or hk]`an*oaha_p[pailh]pa$%), and pailh]pa[`eno is an optional list of directo-
ries to search instead of PAILH=PA[@ENO.
If a loader is able to successfully load a template, it should return a tuple: $pailh]pa[
okqn_a(pailh]pa[l]pd%. Here, pailh]pa[okqn_a is the template string that will be compiled by
the template engine, and pailh]pa[l]pd is the path the template was loaded from. That path
might be shown to the user for debugging purposes, so it should quickly identify where the
template was loaded from.
If the loader is unable to load a template, it should raise `f]jck*pailh]pa*
Pailh]pa@kaoJkpAteop.
Each loader function should also have an eo[qo]^ha function attribute. This is a Boolean
that informs the template engine whether this loader is available in the current Python instal-
lation. For example, the eggs loader (which is capable of loading templates from Python eggs)
sets eo[qo]^ha to B]hoa if the lgc[naokqn_ao module isn’t installed, because lgc[naokqn_ao is
necessary to read data from eggs.
ÊiÝ>«iÊÃÕ`Êi«ÊV>ÀvÞÊ>ÊvÊÌðÊiÀi½ÃÊ>ÊÌi«>ÌiÊ>`iÀÊvÕVÌÊÌ>ÌÊV>Ê
load templates from a ZIP file. It uses a custom setting, PAILH=PA[VEL[BEHAO, as a search path
instead of PAILH=PA[@ENO, and it expects each item on that path to be a ZIP file containing
templates:
bnki`f]jck*_kjbeilknpoappejco
bnki`f]jck*pailh]paeilknpPailh]pa@kaoJkpAteop
eilknpvelbeha
`abhk]`[pailh]pa[okqn_a$pailh]pa[j]ia(pailh]pa[`eno9Jkja%6
Pailh]pahk]`anpd]phk]`opailh]paobnki]VELbeha*
pailh]pa[velbehao9cap]ppn$oappejco(PAILH=PA[VEL[BEHAO(WY%
CHAPTER 9 N ADVANCED TEMPLATES 189
Pnua]_dVELbehaejPAILH=PA[VEL[BEHAO*
bknbj]iaejpailh]pa[velbehao6
pnu6
v9velbeha*VelBeha$bj]ia%
okqn_a9v*na]`$pailh]pa[j]ia%
at_alp$EKAnnkn(GauAnnkn%6
_kjpejqa
v*_hkoa$%
Sabkqj`]pailh]pa(oknapqnjpdaokqn_a*
pailh]pa[l]pd9!o6!o!$bj]ia(pailh]pa[j]ia%
napqnj$okqn_a(pailh]pa[l]pd%
Ebsana]_ddana(pdapailh]pa_kqh`j#p^ahk]`a`
n]eoaPailh]pa@kaoJkpAteop$pailh]pa[j]ia%
Pdeohk]`aneo]hs]uoqo]^ha$oej_avelbehaeoej_hq`a`sepdLupdkj%
hk]`[pailh]pa[okqn_a*eo[qo]^ha9Pnqa
The only step left if we want to use this loader is to add it to the PAILH=PA[HK=@ANO setting.
If we put this code in a package called iuoepa*vel[hk]`an, then we add iuoepa*vel[hk]`an*
hk]`[pailh]pa[okqn_a to PAILH=PA[HK=@ANO.
Configuring the Template System in
Standalone Mode
NNote This section is only of interest to people trying to use the template system as an output component
in another application. If you are using the template system as part of a Django application, the information
presented here doesn’t apply to you.
Normally, Django loads all the configuration information it needs from its own default
configuration file, combined with the settings in the module given in the @F=JCK[OAPPEJCO[
IK@QHA environment variable°Ê/ÃÊÜ>ÃÊiÝ«>i`ÊʺÊ-«iV>Ê*ÞÌÊ*À«Ì»ÊÊ>«ÌiÀÊ{°®Ê
But if you’re using the template system independent of the rest of Django, the environment
variable approach isn’t very convenient, because you probably want to configure the tem-
plate system in line with the rest of your application rather than dealing with settings files and
pointing to them via environment variables.
To solve this problem, you need to use the manual configuration option described fully in
««i`ÝÊ°ÊÊ>ÊÕÌÃi]ÊÞÕÊii`ÊÌÊ«ÀÌÊÌiÊ>««À«À>ÌiÊ«iViÃÊvÊÌiÊÌi«>ÌiÊÃÞÃÌiÊ
and then, before you call any of the template functions, call `f]jck*_kjb*oappejco*_kjbecqna$%
with any settings you wish to specify.
CHAPTER 9 N ADVANCED TEMPLATES
190
You might want to consider setting at least PAILH=PA[@ENO (if you are going to use template
loaders), @AB=QHP[?D=NOAP (although the default of qpb)4 is probably fine), and PAILH=PA[@A>QC.
Ê>Û>>LiÊÃiÌÌ}ÃÊ>ÀiÊ`iÃVÀLi`ÊÊ««i`ÝÊ]Ê>`Ê>ÞÊÃiÌÌ}ÊÃÌ>ÀÌ}ÊÜÌÊPAILH=PA[ is of
obvious interest.
What’s Next?
Continuing this section’s theme of advanced topics, the next chapter covers the advanced
usage of Django models.
CHAPTER 10
Advanced Models
In Chapter 5 we presented an introduction to Django’s database layer—how to define models
and how to use the database API to create, retrieve, update, and delete records. In this chapter,
we’ll introduce you to some more advanced features of this part of Django.
Related Objects
Recall our book models from Chapter 5:
bnki`f]jck*`^eilknpik`aho
_h]ooLq^heodan$ik`aho*Ik`ah%6
j]ia9ik`aho*?d]nBeah`$i]t[hajcpd9/,%
]``naoo9ik`aho*?d]nBeah`$i]t[hajcpd91,%
_epu9ik`aho*?d]nBeah`$i]t[hajcpd92,%
op]pa[lnkrej_a9ik`aho*?d]nBeah`$i]t[hajcpd9/,%
_kqjpnu9ik`aho*?d]nBeah`$i]t[hajcpd91,%
sa^oepa9ik`aho*QNHBeah`$%
`ab[[qje_k`a[[$oahb%6
napqnjoahb*j]ia
_h]oo=qpdkn$ik`aho*Ik`ah%6
benop[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd9/,%
h]op[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd90,%
a)i]eh9ik`aho*A)i]ehBeah`$%
`ab[[qje_k`a[[$oahb%6
napqnjq#!o!o#!$oahb*benop[j]ia(oahb*h]op[j]ia%
191
CHAPTER 10 N ADVANCED MODELS
192
_h]oo>kkg$ik`aho*Ik`ah%6
pepha9ik`aho*?d]nBeah`$i]t[hajcpd9-,,%
]qpdkno9ik`aho*I]juPkI]juBeah`$=qpdkn%
lq^heodan9ik`aho*BknaecjGau$Lq^heodan%
lq^he_]pekj[`]pa9ik`aho*@]paBeah`$%
`ab[[qje_k`a[[$oahb%6
napqnjoahb*pepha
As we explained in Chapter 5, accessing the value for a particular field on a database
object is as straightforward as using an attribute. For example, to determine the title of the
book with ID 50, we’d do the following:
:::bnkiiuoepa*^kkgo*ik`ahoeilknp>kkg
:::^9>kkg*k^fa_po*cap$e`91,%
:::^*pepha
q#Pda@f]jck>kkg#
But one thing we didn’t mention previously is that related objects—fields expressed as
either a BknaecjGau or I]juPkI]juBeah`—act slightly differently.
Accessing Foreign Key Values
When you access a field that’s a BknaecjGau, you’ll get the related model object. Consider this
example:
:::^9>kkg*k^fa_po*cap$e`91,%
:::^*lq^heodan
8Lq^heodan6=lnaooLq^heodejc:
:::^*lq^heodan*sa^oepa
q#dppl6++sss*]lnaoo*_ki+#
With BknaecjGau fields, API access works in reverse, too, but it’s slightly different due to
the nonsymmetrical nature of the relationship. To get a list of books for a given publisher, use
lq^heodan*^kkg[oap*]hh$%, like this:
:::l9Lq^heodan*k^fa_po*cap$j]ia9#=lnaooLq^heodejc#%
:::l*^kkg[oap*]hh$%
W8>kkg6Pda@f]jck>kkg:(8>kkg6@eraEjpkLupdkj:(***Y
Behind the scenes, ^kkg[oap is just a MqanuOap (as covered in Chapter 5), and it can be fil-
tered and sliced like any other MqanuOap. Consider this example:
:::l9Lq^heodan*k^fa_po*cap$j]ia9#=lnaooLq^heodejc#%
:::l*^kkg[oap*behpan$j]ia[[e_kjp]ejo9#`f]jck#%
W8>kkg6Pda@f]jck>kkg:(8>kkg6Lnk@f]jck:Y
The attribute name ^kkg[oap is generated by appending the lowercase model name to [oap.
CHAPTER 10 N ADVANCED MODELS 193
Accessing Many-to-Many Values
Many-to-many values work like foreign-key values, except we deal with MqanuOap values
instead of model instances. For example, here’s how to view the authors for a book:
:::^9>kkg*k^fa_po*cap$e`91,%
:::^*]qpdkno*]hh$%
W8=qpdkn6=`ne]jDkhkr]pu:(8=qpdkn6F]_k^G]lh]j)Ikoo:Y
:::^*]qpdkno*behpan$benop[j]ia9#=`ne]j#%
W8=qpdkn6=`ne]jDkhkr]pu:Y
:::^*]qpdkno*behpan$benop[j]ia9#=`]i#%
WY
It works in reverse, too. To view all of the books for an author, use ]qpdkn*^kkg[oap,
like this:
:::]9=qpdkn*k^fa_po*cap$benop[j]ia9#=`ne]j#(h]op[j]ia9#Dkhkr]pu#%
:::]*^kkg[oap*]hh$%
W8>kkg6Pda@f]jck>kkg:(8>kkg6=`ne]j#oKpdan>kkg:Y
Here, as with BknaecjGau fields, the attribute name ^kkg[oap is generated by appending
the lowercase model name to [oap.
Making Changes to a Database Schema
When we introduced the ouj_`^ command in Chapter 5, we noted that ouj_`^ merely creates
tables that don’t yet exist in your database—it does not sync changes in models or perform
deletions of models. If you add or change a model’s field or if you delete a model, you’ll need
to make the change in your database manually. This section explains how to do that.
When dealing with schema changes, it’s important to keep a few things in mind about
how Django’s database layer works:
Ê UÊ >}ÊÜÊV«>ÊÕ`ÞÊvÊ>Ê`iÊVÌ>ÃÊ>Êvi`ÊÌ>ÌÊ>ÃÊÌÊÞiÌÊLiiÊVÀi>Ìi`ÊÊ
the database table. This will cause an error the first time you use the Django database
API to query the given table (i.e., it will happen at code-execution time, not at compila-
tion time).
Ê UÊ >}Ê`iÃÊnot care if a database table contains columns that are not defined in the
model.
Ê UÊ >}Ê`iÃÊnot care if a database contains a table that is not represented by a model.
Making schema changes is a matter of changing the various pieces—the Python code and
the database itself—in the right order, as outlined in the following sections.
Adding Fields
When adding a field to a table/model in a production setting, the trick is to take advantage of
the fact that Django doesn’t care if a table contains columns that aren’t defined in the model.
The strategy is to add the column in the database, and then update the Django model to
include the new field.
CHAPTER 10 N ADVANCED MODELS
194
However, there’s a bit of a chicken-and-egg problem here, because in order to know how
the new database column should be expressed in SQL, you need to look at the output of Djan-
go’s i]j]ca*luomh]hh command, which requires that the field exist in the model. (Note that
you’re not required to create your column with exactly the same SQL that Django would, but
it’s a good idea to do so, just to be sure everything’s in sync.)
The solution to the chicken-and-egg problem is to use a development environment
instead of making the changes on a production server. (You are using a testing/development
environment, right?) The following are the detailed steps to take.
First, take these steps in the development environment (i.e., not on the production server):
1. Add the field to your model.
2. Run i]j]ca*luomh]hhWukqn]llY to see the new ?NA=PAP=>HA statement for the model.
Note the column definition for the new field.
3. Start your database’s interactive shell (e.g., lomh or iuomh, or you can use i]j]ca*lu
`^odahh). Execute an =HPANP=>HA statement that adds your new column.
4. Launch the Python interactive shell with i]j]ca*luodahh and verify that the new field
was added properly by importing the model and selecting from the table (e.g., IuIk`ah*
k^fa_po*]hh$%W61Y). If you updated the database correctly, the statement should work
without errors.
Then, on the production server perform these steps:
1. Start your database’s interactive shell.
2. Execute the =HPANP=>HA statement you used in step 3 of the development-environment
steps.
3. Add the field to your model. If you’re using source-code revision control and you
checked in your change in step 1 of the development-environment part of this process,
now is the time to update the code (e.g., orjql`]pa, with Subversion) on the produc-
tion server.
4. Restart the Web server for the code changes to take effect.
For example, let’s walk through what we’d do if we added a jqi[l]cao field to the >kkg
model from Chapter 5. First we’d alter the model in our development environment to look
like this:
_h]oo>kkg$ik`aho*Ik`ah%6
pepha9ik`aho*?d]nBeah`$i]t[hajcpd9-,,%
]qpdkno9ik`aho*I]juPkI]juBeah`$=qpdkn%
lq^heodan9ik`aho*BknaecjGau$Lq^heodan%
lq^he_]pekj[`]pa9ik`aho*@]paBeah`$%
jqi[l]cao9ik`aho*EjpacanBeah`$^h]jg9Pnqa(jqhh9Pnqa%
`ab[[qje_k`a[[$oahb%6
napqnjoahb*pepha
CHAPTER 10 N ADVANCED MODELS 195
NNote Read the section “Making Fields Optional” in Chapter 6, plus the sidebar “Adding NOT NULL
Columns” later in this chapter for important details on why we included ^h]jg9Pnqa and jqhh9Pnqa.
Then we’d run the command i]j]ca*luomh]hh^kkgo to see the ?NA=PAP=>HA statement.
Depending on your database back-end, it would look something like this:
?NA=PAP=>HA^kkgo[^kkg$
e`oane]hJKPJQHHLNEI=NUGAU(
pephar]n_d]n$-,,%JKPJQHH(
lq^heodan[e`ejpacanJKPJQHHNABANAJ?AO^kkgo[lq^heodan$e`%(
lq^he_]pekj[`]pa`]paJKPJQHH(
jqi[l]caoejpacanJQHH
%7
The new column is represented like this:
jqi[l]caoejpacanJQHH
Next we’d start the database’s interactive shell for our development database by typing
lomh (for PostgreSQL), and we’d execute the following statement:
=HPANP=>HA^kkgo[^kkg=@@?KHQIJjqi[l]caoejpacan7
ADDING NOT NULL COLUMNS
There’s a subtlety here that deserves mention. When we added the jqi[l]cao field to our model, we
included the ^h]jg9Pnqa and jqhh9Pnqa options because a database column will contain JQHH values
when you first create it.
However, it’s also possible to add columns that cannot contain JQHH values. To do this, you have to
create the column as JQHH, then populate the column’s values using some default(s), and then alter the
column to set the JKPJQHH modifier. Here’s an example:
>ACEJ7
=HPANP=>HA^kkgo[^kkg=@@?KHQIJjqi[l]caoejpacan7
QL@=PA^kkgo[^kkgOAPjqi[l]cao9,7
=HPANP=>HA^kkgo[^kkg=HPAN?KHQIJjqi[l]caoOAPJKPJQHH7
?KIIEP7
If you go down this path, remember that you should leave off ^h]jg9Pnqa and jqhh9Pnqa in your
model.
CHAPTER 10 N ADVANCED MODELS
196
After the =HPANP=>HA statement, we’d verify that the change worked properly by starting
the Python shell and running this code:
:::bnkiiuoepa*^kkgo*ik`ahoeilknp>kkg
:::>kkg*k^fa_po*]hh$%W61Y
If that code didn’t cause errors, we’d switch to our production server and execute the
=HPANP=>HA statement on the production database. Then we’d update the model in the pro-
duction environment and restart the Web server.
Removing Fields
Removing a field from a model is a lot easier than adding one. Just follow these steps:
1. Remove the field’s code from your model class and restart the Web server.
2. Remove the column from your database, using a command like this:
=HPANP=>HA^kkgo[^kkg@NKL?KHQIJjqi[l]cao7
Be sure to perform the steps in this order. If you remove the column from your database
first, Django will immediately begin raising errors.
Removing Many-to-Many Fields
Because many-to-many fields are different from normal fields, the removal process is
different:
1. Remove the I]juPkI]juBeah` code from your model class and restart the Web server.
2. Remove the many-to-many table from your database, using a command like this:
@NKLP=>HA^kkgo[^kkg[]qpdkno7
As in the previous section, be sure to perform the steps in this order.
Removing Models
Removing a model entirely is as easy as removing a field. Just follow these steps:
1. Remove the model class from your ik`aho*lu file and restart the Web server.
2. Remove the table from your database, using a command like this:
@NKLP=>HA^kkgo[^kkg7
Note that you might need to remove any dependent tables from your database first—for
instance, any tables that have foreign keys to ^kkgo[^kkg.
As in the previous sections, be sure to perform the steps in the order shown here.
CHAPTER 10 N ADVANCED MODELS 197
Managers
In the statement >kkg*k^fa_po*]hh$%, k^fa_po is a special attribute through which you query
your database. In Chapter 5 we briefly identified this as the model’s manager. Now it’s time to
dive a bit deeper into what managers are and how you can use them.
In short, a model’s manager is an object through which Django models perform database
queries. Each Django model has at least one manager, and you can create custom managers to
customize database access.
There are two reasons you might want to create a custom manager: to add extra manager
methods, and/or to modify the initial MqanuOap the manager returns.
Adding Extra Manager Methods
Adding extra manager methods is the preferred way to add table-level functionality to your
models. A table-level function is one that acts on multiple instances of models, as opposed to
single instances. (For row-level functionality—i.e., functions that act on a single instance of a
model object—use model methods, which are explained later in this chapter.)
For example, let’s give our >kkg model a manager method pepha[_kqjp$% that takes a
keyword and returns the number of books that have a title containing that keyword. (This
example is slightly contrived, but it demonstrates how managers work.)
ik`aho*lu
bnki`f]jck*`^eilknpik`aho
***=qpdkn]j`Lq^heodanik`ahodana***
_h]oo>kkgI]j]can$ik`aho*I]j]can%6
`abpepha[_kqjp$oahb(gauskn`%6
napqnjoahb*behpan$pepha[[e_kjp]ejo9gauskn`%*_kqjp$%
_h]oo>kkg$ik`aho*Ik`ah%6
pepha9ik`aho*?d]nBeah`$i]t[hajcpd9-,,%
]qpdkno9ik`aho*I]juPkI]juBeah`$=qpdkn%
lq^heodan9ik`aho*BknaecjGau$Lq^heodan%
lq^he_]pekj[`]pa9ik`aho*@]paBeah`$%
jqi[l]cao9ik`aho*EjpacanBeah`$^h]jg9Pnqa(jqhh9Pnqa%
k^fa_po9>kkgI]j]can$%
`ab[[qje_k`a[[$oahb%6
napqnjoahb*pepha
With this manager in place, we can now use the new methods:
:::>kkg*k^fa_po*pepha[_kqjp$#`f]jck#%
0
:::>kkg*k^fa_po*pepha[_kqjp$#lupdkj#%
-4
CHAPTER 10 N ADVANCED MODELS
198
Here are some notes about the code:
Ê UÊ 7i½ÛiÊVÀi>Ìi`Ê>Ê>kkgI]j]can class that extends `f]jck*`^*ik`aho*I]j]can. This has a
single method, pepha[_kqjp$%, which does the calculation. Note that the method uses
oahb*behpan$%, where oahb refers to the manager itself.
Ê UÊ 7i½ÛiÊ>ÃÃ}i`Ê>kkgI]j]can$% to the k^fa_po attribute on the model. This replaces the
default manager for the model, which is called k^fa_po and is automatically created if
you don’t specify a custom manager. By calling our manager k^fa_po rather than some-
thing else, we’re consistent with automatically created managers.
Why would we want to add a method such as pepha[_kqjp$%? To encapsulate commonly
executed queries so that we don’t have to duplicate code.
Modifying Initial Manager QuerySets
A manager’s base MqanuOap returns all objects in the system. For example, >kkg*k^fa_po*]hh$%
returns all books in the book database.
You can override a manager’s base MqanuOap by overriding the I]j]can*cap[mqanu[oap$%
method. cap[mqanu[oap$% should return a MqanuOap with the properties you require.
For example, the following model has two managers—one that returns all objects, and
one that returns only the books by Roald Dahl.
bnki`f]jck*`^eilknpik`aho
Benop(`abejapdaI]j]canoq^_h]oo*
_h]oo@]dhI]j]can$ik`aho*I]j]can%6
`abcap[mqanu[oap$oahb%6
napqnjoqlan$@]dhI]j]can(oahb%*cap[mqanu[oap$%*behpan$]qpdkn9#Nk]h`@]dh#%
Pdajdkkgepejpkpda>kkgik`ahatlhe_ephu*
_h]oo>kkg$ik`aho*Ik`ah%6
pepha9ik`aho*?d]nBeah`$i]t[hajcpd9-,,%
]qpdkn9ik`aho*?d]nBeah`$i]t[hajcpd91,%
***
k^fa_po9ik`aho*I]j]can$%Pda`ab]qhpi]j]can*
`]dh[k^fa_po9@]dhI]j]can$%Pda@]dh)ola_ebe_i]j]can*
With this sample model, >kkg*k^fa_po*]hh$% will return all books in the database, but
>kkg*`]dh[k^fa_po*]hh$% will return only the ones written by Roald Dahl. Note that we explic-
itly set k^fa_po to a vanilla I]j]can instance because if we hadn’t, the only available manager
would be `]dh[k^fa_po.
Of course, because cap[mqanu[oap$% returns a MqanuOap object, you can use behpan$%,
at_hq`a$%, and all the other MqanuOap methods on it. So these statements are all legal:
>kkg*`]dh[k^fa_po*]hh$%
>kkg*`]dh[k^fa_po*behpan$pepha9#I]peh`]#%
>kkg*`]dh[k^fa_po*_kqjp$%
CHAPTER 10 N ADVANCED MODELS 199
This example points out another interesting technique: using multiple managers on the
same model. You can attach as many I]j]can$% instances to a model as you’d like. This is an
easy way to define common filters for your models.
Consider this example:
_h]ooI]haI]j]can$ik`aho*I]j]can%6
`abcap[mqanu[oap$oahb%6
napqnjoqlan$I]haI]j]can(oahb%*cap[mqanu[oap$%*behpan$oat9#I#%
_h]ooBai]haI]j]can$ik`aho*I]j]can%6
`abcap[mqanu[oap$oahb%6
napqnjoqlan$Bai]haI]j]can(oahb%*cap[mqanu[oap$%*behpan$oat9#B#%
_h]ooLanokj$ik`aho*Ik`ah%6
benop[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd91,%
h]op[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd91,%
oat9ik`aho*?d]nBeah`$i]t[hajcpd9-(_dke_ao9$$#I#(#I]ha#%($#B#(#Bai]ha#%%%
laklha9ik`aho*I]j]can$%
iaj9I]haI]j]can$%
skiaj9Bai]haI]j]can$%
This example allows you to request Lanokj*iaj*]hh$%, Lanokj*skiaj*]hh$%, and Lanokj*
laklha*]hh$%, yielding predictable results.
If you use custom I]j]can objects, take note that the first I]j]can Django encounters (in
the order in which they’re defined in the model) has a special status. Django interprets this
first I]j]can defined in a class as the default I]j]can, and several parts of Django (though not
the admin application) will use that default I]j]can exclusively for that model. As a result, it’s
a good idea to be careful in your choice of default manager, in order to avoid a situation where
overriding cap[mqanu[oap$% results in an inability to retrieve objects you’d like to work with.
Model Methods
Model methods allow you to define custom methods on a model to add custom row-level
functionality to your objects. Whereas managers are intended to do table-wide things, model
methods should act on a particular model instance.
Model methods are valuable for keeping business logic in one place—the model. An
example is the easiest way to explain this. Here’s a model with a few custom methods:
bnki`f]jck*_kjpne^*hk_]hbh]rkn*qo*ik`ahoeilknpQOOp]paBeah`
bnki`f]jck*`^eilknpik`aho
_h]ooLanokj$ik`aho*Ik`ah%6
benop[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd91,%
h]op[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd91,%
^enpd[`]pa9ik`aho*@]paBeah`$%
]``naoo9ik`aho*?d]nBeah`$i]t[hajcpd9-,,%
_epu9ik`aho*?d]nBeah`$i]t[hajcpd91,%
op]pa9QOOp]paBeah`$%Uao(pdeoeoQO)_ajpne_***
CHAPTER 10 N ADVANCED MODELS
200
`ab^]^u[^kkian[op]pqo$oahb%6
Napqnjopdalanokj#o^]^u)^kkianop]pqo*
eilknp`]papeia
eb`]papeia*`]pa$-501(4(-%89oahb*^enpd[`]paX
]j`oahb*^enpd[`]pa89`]papeia*`]pa$-520(-.(/-%6
napqnj>]^u^kkian
eboahb*^enpd[`]pa8`]papeia*`]pa$-501(4(-%6
napqnjLna)^kkian
napqnjLkop)^kkian
`abeo[ie`saopanj$oahb%6
NapqnjoPnqaebpdeolanokjeobnkipdaIe`saop*
napqnjoahb*op]paej$#EH#(#SE#(#IE#(#EJ#(#KD#(#E=#(#IK#%
`ab[cap[bqhh[j]ia$oahb%6
Napqnjopdalanokj#obqhhj]ia*
napqnjq#!o!o#!$oahb*benop[j]ia(oahb*h]op[j]ia%
bqhh[j]ia9lnklanpu$[cap[bqhh[j]ia%
The last method in this example is a property. (You can read more about properties at dppl6++
sss*lupdkj*knc+`ksjhk]`+naha]oao+.*.+`ao_nejpnk+lnklanpu.) Here’s an example usage:
:::l9Lanokj*k^fa_po*cap$benop[j]ia9#>]n]_g#(h]op[j]ia9#K^]i]#%
:::l*^enpd[`]pa
`]papeia*`]pa$-52-(4(0%
:::l*^]^u[^kkian[op]pqo$%
#>]^u^kkian#
:::l*eo[ie`saopanj$%
Pnqa
:::l*bqhh[j]iaJkpapdeoeoj#p]iapdk`Íep#opna]pa`]o]j]ppne^qpa
q#>]n]_gK^]i]#
Executing Raw SQL Queries
The Django database API can take you only so far, so sometimes you’ll want to write custom
SQL queries against your database. You can do this very easily by accessing the object `f]jck*
`^*_kjja_pekj, which represents the current database connection. To use it, call _kjja_pekj*
_qnokn$% to get a cursor object. Then call _qnokn*ata_qpa$omh(Wl]n]ioY% to execute the SQL
and _qnokn*bap_dkja$% or _qnokn*bap_d]hh$% to return the resulting rows. Here’s an example:
:::bnki`f]jck*`^eilknp_kjja_pekj
:::_qnokn9_kjja_pekj*_qnokn$%
:::_qnokn*ata_qpa$
***OAHA?P@EOPEJ?Pbenop[j]ia
***BNKIlaklha[lanokj
***SDANAh]op[j]ia9!o(W#Hajjkj#Y%
:::nks9_qnokn*bap_dkja$%
:::lnejpnks
W#Fkdj#Y
CHAPTER 10 N ADVANCED MODELS 201
_kjja_pekj and _qnokn mostly implement the standard Python Database API, which you
can read about at dppl6++sss*lupdkj*knc+lalo+lal),.05*dpih. If you’re not familiar with
the Python Database API, note that the SQL statement in _qnokn*ata_qpa$% uses placehold-
ers, !o, rather than adding parameters directly within the SQL. If you use this technique,
the underlying database library will automatically add quotes and escape characters to your
parameter(s) as necessary.
Rather than littering your view code with `f]jck*`^*_kjja_pekj statements, it’s a good
idea to put them in custom model methods or manager methods. For instance, the preceding
example could be integrated into a custom manager method like this:
bnki`f]jck*`^eilknp_kjja_pekj(ik`aho
_h]ooLanokjI]j]can$ik`aho*I]j]can%6
`abbenop[j]iao$oahb(h]op[j]ia%6
_qnokn9_kjja_pekj*_qnokn$%
_qnokn*ata_qpa$
OAHA?P@EOPEJ?Pbenop[j]ia
BNKIlaklha[lanokj
SDANAh]op[j]ia9!o(Wh]op[j]iaY%
napqnjWnksW,Ybknnksej_qnokn*bap_dkja$%Y
_h]ooLanokj$ik`aho*Ik`ah%6
benop[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd91,%
h]op[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd91,%
k^fa_po9LanokjI]j]can$%
Here’s a sample usage:
:::Lanokj*k^fa_po*benop[j]iao$#Hajjkj#%
W#Fkdj#(#?ujpde]#Y
What’s Next?
In the next chapter we’ll show you Django’s “generic views” framework, which lets you save
time building Web sites that follow common patterns.
CHAPTER 11
Generic Views
Here again is a recurring theme of this book: at its worst, Web development is boring and
monotonous. So far, we’ve covered how Django tries to take away some of that monotony
at the model and template layers, but Web developers also experience this boredom at the
view level.
Django’s generic views were developed to ease that pain. They 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. In fact, nearly every view
example in the preceding chapters could be rewritten with the help of generic views.
Chapter 8 touched briefly on how you’d go about making a view generic. To review, we
can recognize certain common tasks, like displaying a list of objects, and write code that dis-
plays a list of any object. Then the model in question can be passed as an extra argument to
the URLconf.
Django ships with generic views to do the following:
Ê UÊ *iÀvÀÊVʺÃ«i»ÊÌ>ÃÃ\ÊÀi`ÀiVÌÊÌÊ>Ê`vviÀiÌÊ«>}iÊÀÊÀi`iÀÊ>Ê}ÛiÊ
template.
Ê UÊ ë>ÞÊÃÌÊ>`Ê`iÌ>Ê«>}iÃÊvÀÊ>ÊÃ}iÊLiVÌ°Ê/iÊarajp[heop and ajpnu[heop views
from Chapter 8 are examples of list views. A single event page is an example of what we
call a detail view.
Ê UÊ *ÀiÃiÌÊ`>ÌiL>Ãi`ÊLiVÌÃÊÊÞi>ÀÉÌÉ`>ÞÊ>ÀVÛiÊ«>}iÃ]Ê>ÃÃV>Ìi`Ê`iÌ>]Ê>`Ê
º>ÌiÃ̻ʫ>}iðÊ/iÊ>}ÊÜiL}½ÃÊdppl6++sss*`f]jcklnkfa_p*_ki+sa^hkc+) year,
month, and day archives are built with these, as would be a typical newspaper’s
archives.
Taken together, these views provide easy interfaces to perform the most common tasks
developers encounter.
203
CHAPTER 11 N GENERIC VIEWS
204
Using Generic Views
All of these views are used by creating configuration dictionaries in your URLconf files and
«>ÃÃ}ÊÌÃiÊ`VÌ>ÀiÃÊ>ÃÊÌiÊÌÀ`ÊiLiÀÊvÊÌiÊ1,VvÊÌÕ«iÊvÀÊ>Ê}ÛiÊ«>ÌÌiÀ°Ê-iiÊ
º*>ÃÃ}ÊÝÌÀ>Ê"«ÌÃÊÌÊ6iÜÊÕVÌûÊÊ>«ÌiÀÊnÊvÀÊ>ÊÛiÀÛiÜÊvÊÌÃÊÌiVµÕi°®
ÀÊiÝ>«i]ÊiÀi½ÃÊ>ÊÃ«iÊ1,VvÊÞÕÊVÕ`ÊÕÃiÊÌÊ«ÀiÃiÌÊ>ÊÃÌ>ÌVʺ>LÕ̻ʫ>}i\
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnki`f]jck*reaso*cajane_*oeilhaeilknp`ena_p[pk[pailh]pa
qnhl]ppanjo9l]ppanjo$##(
$n#Z]^kqp+ #(`ena_p[pk[pailh]pa(w
#pailh]pa#6#]^kqp*dpih#
y%
%
/Õ}ÊÌÃÊ}ÌÊÃiiÊ>ÊLÌʺ>}V>»Ê>ÌÊvÀÃÌÊ}>Vip]Ê>ÊÛiÜÊÜÌÊÊV`itp̽ÃÊ
actually exactly the same as the examples in Chapter 8. The `ena_p[pk[pailh]pa view simply
grabs information from the extra-parameters dictionary and uses that information when ren-
dering the view.
iV>ÕÃiÊÌÃÊ}iiÀVÊÛiÜp>`Ê>ÊÌiÊÌiÀÃpÃÊ>ÊÀi}Õ>ÀÊÛiÜÊvÕVÌÊiÊ>ÞÊÌiÀ]Ê
ÜiÊV>ÊÀiÕÃiÊÌÊÃ`iÊÕÀÊÜÊÛiÜðÊÃÊ>ÊiÝ>«i]Êi̽ÃÊiÝÌi`ÊÕÀʺ>LÕÌ»ÊiÝ>«iÊÌÊ>«Ê
URLs of the form +]^kqp+8sd]paran:+ to statically rendered ]^kqp+8sd]paran:*dpih. We’ll do
this by first modifying the URLconf to point to a view function:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnki`f]jck*reaso*cajane_*oeilhaeilknp`ena_p[pk[pailh]pa
bnkiiuoepa*^kkgo*reasoeilknp]^kqp[l]cao
qnhl]ppanjo9l]ppanjo$##(
$n#Z]^kqp+ #(`ena_p[pk[pailh]pa(w
#pailh]pa#6#]^kqp*dpih#
y%(
$n#Z]^kqp+$Xs'%+ #(]^kqp[l]cao%(
%
Next, we’ll write the ]^kqp[l]cao view:
bnki`f]jck*dppleilknpDppl0,0
bnki`f]jck*pailh]paeilknpPailh]pa@kaoJkpAteop
bnki`f]jck*reaso*cajane_*oeilhaeilknp`ena_p[pk[pailh]pa
`ab]^kqp[l]cao$namqaop(l]ca%6
pnu6
napqnj`ena_p[pk[pailh]pa$namqaop(pailh]pa9]^kqp+!o*dpih!l]ca%
at_alpPailh]pa@kaoJkpAteop6
n]eoaDppl0,0$%
CHAPTER 11 N GENERIC VIEWS 205
Here we’re treating `ena_p[pk[pailh]pa like any other function. Since it returns an
DpplNaolkjoa, we can simply return it as is. The only slightly tricky business here is dealing
with missing templates. We don’t want a nonexistent template to cause a server error, so we
catch Pailh]pa@kaoJkpAteop exceptions and return 404 errors instead.
IS THERE A SECURITY VULNERABILITY HERE?
Sharp-eyed readers may have noticed a possible security hole: we’re constructing the template name using
interpolated content from the browser (pailh]pa9]^kqp+!o*dpih!l]ca). At first glance, this looks
like a classic directory-traversal vulnerability (discussed in detail in Chapter 20). But is it really?
Not exactly. Yes, a maliciously crafted value of l]ca could cause directory traversal, but although l]ca
is taken from the request URL, not every value will be accepted. The key is in the URLconf: we’re using the
regular expression Xs' to match the l]ca part of the URL, and Xs accepts only letters and numbers. Thus,
any malicious characters (such as dots and slashes) will be rejected by the URL resolver before they reach the
view itself.
Generic Views of Objects
The `ena_p[pk[pailh]pa view certainly is useful, but Django’s generic views really shine when
it comes to presenting views on your database content. Because it’s such a common task,
Django comes with a handful of built-in generic views that make generating list and detail
views of objects incredibly easy.
i̽ÃÊÌ>iÊ>ÊÊ>ÌÊiÊvÊÌiÃiÊ}iiÀVÊÛiÜÃ\ÊÌiʺLiVÌÊÃÌ»ÊÛiÜ. We’ll be using this
Lq^heodan object from Chapter 5:
_h]ooLq^heodan$ik`aho*Ik`ah%6
j]ia9ik`aho*?d]nBeah`$i]t[hajcpd9/,%
]``naoo9ik`aho*?d]nBeah`$i]t[hajcpd91,%
_epu9ik`aho*?d]nBeah`$i]t[hajcpd92,%
op]pa[lnkrej_a9ik`aho*?d]nBeah`$i]t[hajcpd9/,%
_kqjpnu9ik`aho*?d]nBeah`$i]t[hajcpd91,%
sa^oepa9ik`aho*QNHBeah`$%
`ab[[qje_k`a[[$oahb%6
napqnjoahb*j]ia
_h]ooIap]6
kn`anejc9W#j]ia#Y
CHAPTER 11 N GENERIC VIEWS
206
To build a list page of all publishers, we’d use a URLconf along these lines:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnki`f]jck*reaso*cajane_eilknpheop[`ap]eh
bnkiiuoepa*^kkgo*ik`ahoeilknpLq^heodan
lq^heodan[ejbk9w
#mqanuoap#6Lq^heodan*k^fa_po*]hh$%(
y
qnhl]ppanjo9l]ppanjo$##(
$n#Zlq^heodano+ #(heop[`ap]eh*k^fa_p[heop(lq^heodan[ejbk%
%
/>̽ÃÊ>ÊÌiÊ*ÞÌÊV`iÊÜiÊii`ÊÌÊÜÀÌi°Ê7iÊÃÌÊii`ÊÌÊÜÀÌiÊ>ÊÌi«>Ìi]ÊÜiÛiÀ°Ê
We can explicitly tell the k^fa_p[heop view which template to use by including a pailh]pa[j]ia
key in the extra-arguments dictionary:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnki`f]jck*reaso*cajane_eilknpheop[`ap]eh
bnkiiuoepa*^kkgo*ik`ahoeilknpLq^heodan
lq^heodan[ejbk9w
#mqanuoap#6Lq^heodan*k^fa_po*]hh$%(
#pailh]pa[j]ia#6#lq^heodan[heop[l]ca*dpih#(
y
qnhl]ppanjo9l]ppanjo$##(
$n#Zlq^heodano+ #(heop[`ap]eh*k^fa_p[heop(lq^heodan[ejbk%
%
In the absence of pailh]pa[j]ia, though, the k^fa_p[heop generic view will infer one from
the object’s name. In this case, the inferred template will be ^kkgo+lq^heodan[heop*dpihpÌiÊ
^kkgo part comes from the name of the app that defines the model, while the lq^heodan bit is
just the lowercased version of the model’s name.
This template will be rendered against a context containing a variable called k^fa_p[heop
that contains all the lq^heodan objects. A very simple template might look like the following:
w!atpaj`o^]oa*dpih!y
w!^hk_g_kjpajp!y
8d.:Lq^heodano8+d.:
8qh:
w!bknlq^heodanejk^fa_p[heop!y
8he:wwlq^heodan*j]iayy8+he:
w!aj`bkn!y
8+qh:
w!aj`^hk_g!y
CHAPTER 11 N GENERIC VIEWS 207
 ÌiÊÌ>ÌÊÌÃÊ>ÃÃÕiÃÊÌiÊiÝÃÌiViÊvÊ>Ê^]oa*dpih template, as we provided in an exam-
ple in Chapter 4.)
That’s really all there is to it. All the cool features of generic views come from changing the
ºv»Ê`VÌ>ÀÞÊ«>ÃÃi`ÊÌÊÌiÊ}iiÀVÊÛiÜ°Ê««i`ÝÊÊ`VÕiÌÃÊ>ÊÌiÊ}iiÀVÊÛiÜÃÊ>`Ê
all their options in detail; the rest of this chapter will consider some of the common ways you
might customize and extend generic views.
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. Indeed,
one of the most common questions asked by new Django developers is how to make generic
views handle a wider array of situations.
Luckily, in nearly every one of these cases there are ways to simply extend generic views
to handle a larger array of use cases. These situations usually fall into the handful of patterns
dealt with in the following sections.
Making “Friendly” Template Contexts
You might have noticed that the sample publisher list template stores all the books in a vari-
able named k^fa_p[heop. While this works just fine, it isn’t all that friendly to template authors:
ÌiÞÊ>ÛiÊÌʺÕÃÌÊÜ»ÊÌ>ÌÊÌiÞ½ÀiÊ`i>}ÊÜÌÊLÃÊiÀi°ÊÊLiÌÌiÀÊ>iÊvÀÊÌ>ÌÊÛ>À>LiÊ
would be lq^heodan[heop; that variable’s content is pretty obvious.
We can change the name of that variable easily with the pailh]pa[k^fa_p[j]ia argument:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnki`f]jck*reaso*cajane_eilknpheop[`ap]eh
bnkiiuoepa*^kkgo*ik`ahoeilknpLq^heodan
lq^heodan[ejbk9w
#mqanuoap#6Lq^heodan*k^fa_po*]hh$%(
#pailh]pa[j]ia#6#lq^heodan[heop[l]ca*dpih#(
#pailh]pa[k^fa_p[j]ia#6#lq^heodan#(
y
qnhl]ppanjo9l]ppanjo$##(
$n#Zlq^heodano+ #(heop[`ap]eh*k^fa_p[heop(lq^heodan[ejbk%
%
In the template, the generic view will append [heop to the pailh]pa[k^fa_p[j]ia to create
the variable name representing the list of items.
*ÀÛ`}Ê>ÊÕÃivÕÊpailh]pa[k^fa_p[j]ia is always a good idea. Your coworkers who
design templates will thank you.
CHAPTER 11 N GENERIC VIEWS
208
Adding Extra Context
Sometimes you might need to present information beyond that provided in the generic view.
ÀÊiÝ>«i]ÊÌÊvÊÃÜ}Ê>ÊÃÌÊvÊ>ÊÌiÊÌiÀÊ«ÕLÃiÀÃÊÊi>VÊ«ÕLÃiÀÊ`iÌ>Ê«>}i°Ê
The k^fa_p[`ap]eh 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.
But there is: all generic views take an extra optional parameter, atpn][_kjpatp. This is a
dictionary of extra objects that will be added to the template’s context. So, to provide the list of
all publishers on the detail view, we’d use an info dictionary like this:
lq^heodan[ejbk9w
#mqanuoap#6Lq^heodan*k^fa_po*]hh$%(
#pailh]pa[k^fa_p[j]ia#6#lq^heodan#(
#atpn][_kjpatp#6w#^kkg[heop#6>kkg*k^fa_po*]hh$%y
y
This would populate a ww^kkg[heopyy variable in the template context. This pattern can
be used to pass any information down into the template for the generic view. It’s very handy.
ÜiÛiÀ]ÊÌiÀi½ÃÊ>VÌÕ>ÞÊ>ÊÃÕLÌiÊLÕ}ÊiÀipV>ÊÞÕÊëÌÊ̶
The problem has to do with when the queries in atpn][_kjpatp are evaluated. Because
this example puts >kkg*k^fa_po*]hh$%ÊÊÌiÊ1,Vv]ÊÌÊÜÊLiÊiÛ>Õ>Ìi`ÊÞÊViÊÜiÊÌiÊ
1,VvÊÃÊvÀÃÌÊ>`i`®°Ê"ViÊÞÕÊ>``ÊÀÊÀiÛiÊ«ÕLÃiÀÃ]ÊÞÕ½ÊÌViÊÌ>ÌÊÌiÊ}iiÀVÊÛiÜÊ
`iÃ½ÌÊÀiviVÌÊÌÃiÊV>}iÃÊÕÌÊÞÕÊÀi>`ÊÌiÊ7iLÊÃiÀÛiÀÊÃiiʺ>V}Ê>`Ê+ÕiÀÞ-iÌûÊÊ
Appendix B for more information about when MqanuOap objects are cached and evaluated).
NNote This problem doesn’t apply to the mqanuoap generic view argument. Since Django knows that par-
ticular MqanuOap should never be cached, the generic view takes care of clearing the cache when each view
is rendered.
The solution is to use a callback in atpn][_kjpatpÊÃÌi>`ÊvÊ>ÊÛ>Õi°ÊÞÊV>>LiÊ°i°]Ê>Ê
function) that’s passed to atpn][_kjpatpÊÜÊLiÊiÛ>Õ>Ìi`ÊÜiÊÌiÊÛiÜÊÃÊÀi`iÀi`ÊÃÌi>`Ê
of only once). You could do this with an explicitly defined function:
`abcap[^kkgo$%6
napqnj>kkg*k^fa_po*]hh$%
lq^heodan[ejbk9w
#mqanuoap#6Lq^heodan*k^fa_po*]hh$%(
#pailh]pa[k^fa_p[j]ia#6#lq^heodan#(
#atpn][_kjpatp#6w#^kkg[heop#6cap[^kkgoy
y
CHAPTER 11 N GENERIC VIEWS 209
"ÀÊÞÕÊVÕ`ÊÕÃiÊ>ÊiÃÃÊLÛÕÃÊLÕÌÊÃÀÌiÀÊÛiÀÃÊÌ>ÌÊÀiiÃÊÊÌiÊv>VÌÊÌ>ÌÊ>kkg*k^fa_po*]hh is
itself a callable:
lq^heodan[ejbk9w
#mqanuoap#6Lq^heodan*k^fa_po*]hh$%(
#pailh]pa[k^fa_p[j]ia#6#lq^heodan#(
#atpn][_kjpatp#6w#^kkg[heop#6>kkg*k^fa_po*]hhy
y
Notice the lack of parentheses after >kkg*k^fa_po*]hh. This references the function with-
ÕÌÊ>VÌÕ>ÞÊV>}ÊÌÊÜVÊÌiÊ}iiÀV view will do later).
Viewing Subsets of Objects
Now let’s take a closer look at this mqanuoap key we’ve been using all along. Most generic
views take one of these mqanuoapÊ>À}ÕiÌÃp̽ÃÊÜÊÌiÊÛiÜÊÜÃÊÜVÊÃiÌÊvÊLiVÌÃÊ
ÌÊ`ë>ÞÊÃiiʺ-iiVÌ}Ê"LiVÌûÊÊ>«ÌiÀÊxÊvÀÊ>ÊÌÀ`ÕVÌÊÌÊMqanuOap objects, and
see Appendix B for the complete details).
Suppose, for example, that you want to order a list of books by publication date, with the
most recent first:
^kkg[ejbk9w
#mqanuoap#6>kkg*k^fa_po*kn`an[^u$#)lq^he_]pekj[`]pa#%(
y
qnhl]ppanjo9l]ppanjo$##(
$n#Zlq^heodano+ #(heop[`ap]eh*k^fa_p[heop(lq^heodan[ejbk%(
$n#Z^kkgo+ #(heop[`ap]eh*k^fa_p[heop(^kkg[ejbk%(
%
/>̽ÃÊ>Ê«ÀiÌÌÞÊÃ«iÊiÝ>«i]ÊLÕÌÊÌÊÕÃÌÀ>ÌiÃÊÌiÊ`i>ÊViÞ°Ê"vÊVÕÀÃi]ÊÞÕ½ÊÕÃÕ>ÞÊ
want to do more than just reorder objects. If you want to present a list of books by a particular
publisher, you can use the same technique:
]lnaoo[^kkgo9w
#mqanuoap#6>kkg*k^fa_po*behpan$lq^heodan[[j]ia9#=lnaooLq^heodejc#%(
#pailh]pa[j]ia#6#^kkgo+]lnaoo[heop*dpih#
y
qnhl]ppanjo9l]ppanjo$##(
$n#Zlq^heodano+ #(heop[`ap]eh*k^fa_p[heop(lq^heodan[ejbk%(
$n#Z^kkgo+]lnaoo+ #(heop[`ap]eh*k^fa_p[heop(]lnaoo[^kkgo%(
%
Notice that along with a filtered mqanuoap, we’re also using a custom template name. If we
``½Ì]ÊÌiÊ}iiÀVÊÛiÜÊÜÕ`ÊÕÃiÊÌiÊÃ>iÊÌi«>ÌiÊ>ÃÊÌiʺÛ>>»ÊLiVÌÊÃÌ]ÊÜVÊ}ÌÊ
not be what we want.
CHAPTER 11 N GENERIC VIEWS
210
Also notice that this isn’t a very elegant way of doing publisher-specific books. If we want
to add another publisher page, we’d need another handful of lines in the URLconf, and more
than a few publishers would get unreasonable. We’ll deal with this problem in the next section.
Complex Filtering with Wrapper Functions
Another common need is to filter the objects given in a list page by some key in the URL.
>ÀiÀÊÜiÊ>À`V`i`ÊÌiÊ«ÕLÃiÀ½ÃÊ>iÊÊÌiÊ1,Vv]ÊLÕÌÊÜ>ÌÊvÊÜiÊÜ>Ìi`ÊÌÊÜÀÌiÊ
>ÊÛiÜÊÌ>ÌÊ`ë>Þi`Ê>ÊÌiÊLÃÊLÞÊÃiÊ>ÀLÌÀ>ÀÞÊ«ÕLÃiÀ¶Ê/iÊÃÕÌÊÃÊÌʺÜÀ>«»ÊÌiÊ
k^fa_p[heop generic view to avoid writing a lot of code by hand. As usual, we’ll start by writing
a URLconf:
qnhl]ppanjo9l]ppanjo$##(
$n#Zlq^heodano+ #(heop[`ap]eh*k^fa_p[heop(lq^heodan[ejbk%(
$n#Z^kkgo+$Xs'%+ #(^kkgo[^u[lq^heodan%(
%
Next we’ll write the ^kkgo[^u[lq^heodan view itself:
bnki`f]jck*odknp_qpoeilknpcap[k^fa_p[kn[0,0
bnki`f]jck*reaso*cajane_eilknpheop[`ap]eh
bnkiiuoepa*^kkgo*ik`ahoeilknp>kkg(Lq^heodan
`ab^kkgo[^u[lq^heodan$namqaop(j]ia%6
Hkkgqlpdalq^heodan$]j`n]eoa]0,0ebep_]j#p^abkqj`%*
lq^heodan9cap[k^fa_p[kn[0,0$Lq^heodan(j]ia[[eat]_p9j]ia%
Qoapdak^fa_p[heopreasbknpdada]ruhebpejc*
napqnjheop[`ap]eh*k^fa_p[heop$
namqaop(
mqanuoap9>kkg*k^fa_po*behpan$lq^heodan9lq^heodan%(
pailh]pa[j]ia9#^kkgo+^kkgo[^u[lq^heodan*dpih#(
pailh]pa[k^fa_p[j]ia9#^kkg#(
atpn][_kjpatp9w#lq^heodan#6lq^heodany
%
/ÃÊÜÀÃÊLiV>ÕÃiÊÌiÀi½ÃÊÀi>ÞÊÌ}ÊëiV>Ê>LÕÌÊ}iiÀVÊÛiÜÃpÌiÞ½ÀiÊÕÃÌÊ*ÞÌÊ
functions. Like any view function, generic views expect a certain set of arguments and return
DpplNaolkjoa objects. Thus, it’s incredibly easy to wrap a small function around a generic
ÛiÜÊÌ>ÌÊ`iÃÊ>``Ì>ÊÜÀÊLivÀiÊÀÊ>vÌiÀÆÊÃiiÊÌiÊiÝÌÊÃiVÌ®Ê>`}ÊÌ}ÃÊvvÊÌ the
generic view.
NNote Notice that in the preceding example we passed the current publisher being displayed in the
atpn][_kjpatp. This is usually a good idea in wrappers of this nature; it lets the template know which
“parent” object is currently being browsed.
CHAPTER 11 N GENERIC VIEWS 211
Performing Extra Work
The last common pattern we’ll look at involves doing some extra work before or after calling
the generic view.
Imagine we had a h]op[]__aooa` field on our =qpdkn object that we were using to keep
track of the last time anybody looked at that author. The generic k^fa_p[`ap]eh view, of
course, wouldn’t know anything about this field, but once again we could easily write a custom
view to keep that field updated.
ÀÃÌ]ÊÜi½`Êii`ÊÌÊ>``Ê>Ê]qpdkn[`ap]eh bit in the URLconf to point to a custom view:
bnkiiuoepa*^kkgo*reasoeilknp]qpdkn[`ap]eh
qnhl]ppanjo9l]ppanjo$##(
***
$n#Z]qpdkno+$;L8]qpdkn[e`:X`'%+ #(]qpdkn[`ap]eh%(
***
%
Then we’d write our wrapper function:
eilknp`]papeia
bnki`f]jck*odknp_qpoeilknpcap[k^fa_p[kn[0,0
bnki`f]jck*reaso*cajane_eilknpheop[`ap]eh
bnkiiuoepa*^kkgo*ik`ahoeilknp=qpdkn
`ab]qpdkn[`ap]eh$namqaop(]qpdkn[e`%6
@ahac]papkpdacajane_reas]j`cap]jDpplNaolkjoa*
naolkjoa9heop[`ap]eh*k^fa_p[`ap]eh$
namqaop(
mqanuoap9=qpdkn*k^fa_po*]hh$%(
k^fa_p[e`9]qpdkn[e`(
%
Na_kn`pdah]op]__aooa``]pa*Sa`kpdeo&]bpan&pda_]hh
pkk^fa_p[`ap]eh$%(jkp^abknaep(okpd]ppdeoskj#p^a_]hha`
qjhaoopda=qpdkn]_pq]hhuateopo*$Ebpda]qpdkn`kaoj#pateop(
k^fa_p[`ap]eh$%sehhn]eoaDppl0,0(]j`saskj#pna]_dpdeolkejp*%
jks9`]papeia*`]papeia*jks$%
=qpdkn*k^fa_po*behpan$e`9]qpdkn[e`%*ql`]pa$h]op[]__aooa`9jks%
napqnjnaolkjoa
NNote This code won’t work unless you add a h]op[]__aooa` field to your =qpdkn model and create a
^kkgo+]qpdkn[`ap]eh*dpih template.
CHAPTER 11 N GENERIC VIEWS
212
We can use a similar idiom to alter the response returned by the generic view. If we
wanted to provide a downloadable plain-text version of the list of authors, we could use a
view like this:
`ab]qpdkn[heop[lh]ejpatp$namqaop%6
naolkjoa9heop[`ap]eh*k^fa_p[heop$
namqaop(
mqanuoap9=qpdkn*k^fa_po*]hh$%(
ieiapula9#patp+lh]ej#(
pailh]pa[j]ia9#^kkgo+]qpdkn[heop*ptp#
%
naolkjoaW?kjpajp)@eolkoepekjY9]pp]_diajp7behaj]ia9]qpdkno*ptp
napqnjnaolkjoa
This works because the generic views return simple DpplNaolkjoa objects that can be
ÌÀi>Ìi`ÊiÊ`VÌ>ÀiÃÊÌÊÃiÌÊ//*Êi>`iÀðÊ/ÃÊ?kjpajp)@eolkoepekj business, by the way,
instructs the browser to download and save the page instead of displaying it in the browser.
What’s Next?
In this chapter we looked at only a couple of the generic views Django ships with, but the gen-
eral ideas presented here should apply pretty closely to any generic view. Appendix C covers
all the available views in detail, and it’s recommended reading if you want to get the most out
of this powerful feature.
/ÃÊVVÕ`iÃÊÌiÊÃiVÌÊvÊÌÃÊLÊ`iÛÌi`ÊÌʺ>`Û>Vi`ÊÕÃ>}i°»ÊÊÌiÊiÝÌÊV>«ÌiÀÊ
we cover deployment of Django applications.
CHAPTER 12
Deploying Django
This chapter covers the last essential step of building a Django application: deploying it to
a production server.
If you’ve been following along with our ongoing examples, you probably used the
nqjoanran, which makes things very easy (you don’t have to worry about Web server setup).
But nqjoanran is intended only for development on your local machine, not for exposure on
the public Web. To deploy your Django application, you’ll need to hook it into an industrial-
strength Web server such as Apache. In this chapter, we’ll show you how to do that, but first
we’ll give you a checklist of things to do in your codebase before you go live.
Preparing Your Codebase for Production
Fortunately, the nqjoanran approximates a “real” Web server closely enough that not very
many changes need to be made to a Django application in order to make it production-ready.
But there are a few essential things you should do before you turn the switch.
Turning Off Debug Mode
When we created a project in Chapter 2, the command `f]jck)]`iej*luop]nplnkfa_p created
a oappejco*lu file with @A>QC set to Pnqa. Many internal parts of Django check this setting and
change their behavior if @A>QC mode is on. For example, if @A>QC is set to Pnqa, then:
Ê UÊ Ê`>Ì>L>ÃiʵÕiÀiÃÊÜÊLiÊÃ>Ûi`ÊÊiÀÞÊ>ÃÊÌiÊLiVÌÊ`f]jck*`^*_kjja_pekj*
mqaneao. As you can imagine, this eats up memory!
Ê UÊ ÞÊ{ä{ÊiÀÀÀÊÜÊLiÊÀi`iÀi`ÊLÞÊ>}½ÃÊëiV>Ê{ä{ÊiÀÀÀÊ«>}iÊVÛiÀi`ÊÊ>«ÌiÀÊήÊ
ÃÌi>`ÊvÊÀiÌÕÀ}Ê>Ê«À«iÀÊ{ä{ÊÀiëÃi°Ê/ÃÊ«>}iÊVÌ>ÃÊ«ÌiÌ>ÞÊÃiÃÌÛiÊ
information and should not be exposed to the public Internet.
Ê UÊ ÞÊÕV>Õ}ÌÊiÝVi«ÌÊÊÞÕÀÊ>}Ê>««V>ÌpvÀÊL>ÃVÊ*ÞÌÊÃÞÌ>ÝÊiÀÀÀÃÊ
ÌÊ`>Ì>L>ÃiÊiÀÀÀÃÊÌÊÌi«>ÌiÊÃÞÌ>ÝÊiÀÀÀÃpÜÊLiÊÀi`iÀi`ÊLÞÊÌiÊ>}Ê«ÀiÌÌÞÊ
error page that you’ve likely come to know and love. This page contains even more sen-
ÃÌÛiÊvÀ>ÌÊÌ>ÊÌiÊ{ä{Ê«>}iÊ>`ÊÃÕ`Ênever be exposed to the public.
213
CHAPTER 12 N DEPLOYING DJANGO
214
In short, setting @A>QC to Pnqa tells Django to assume that only trusted developers are
using your site. The Internet is full of untrustworthy hooligans, and the first thing you should
do when you’re preparing your application for deployment is set @A>QC to B]hoa.
Turning Off Template Debug Mode
Similarly, you should set PAILH=PA[@A>QC to B]hoa in production. If Pnqa, this setting tells
Django’s template system to save some extra information about every template for use on the
pretty error pages.
Implementing a 404 Template
If @A>QC is Pnqa, DjangoÊ`ë>ÞÃÊÌiÊÕÃivÕÊ{ä{ÊiÀÀÀÊ«>}i°ÊÕÌÊvÊ@A>QC is B]hoa, it does some-
thing different: it renders a template called 0,0*dpih in your root template directory. So, when
ÞÕ½ÀiÊÀi>`ÞÊÌÊ`i«Þ]ÊÞÕ½Êii`ÊÌÊVÀi>ÌiÊÌÃÊÌi«>ÌiÊ>`Ê«ÕÌÊ>ÊÕÃivÕʺ*>}iÊÌÊvÕ`»Ê
message in it.
Here’s a sample 0,0*dpih you can use as a starting point. It assumes that you’re using
template inheritance and have defined a ^]oa*dpih with blocks called pepha and _kjpajp:
w!atpaj`o^]oa*dpih!y
w!^hk_gpepha!yL]cajkpbkqj`w!aj`^hk_g!y
w!^hk_g_kjpajp!y
8d-:L]cajkpbkqj`8+d-:
8l:Oknnu(^qppdanamqaopa`l]ca_kqh`jkp^abkqj`*8+l:
w!aj`^hk_g!y
To test that your 0,0*dpih is working, just change @A>QC to B]hoa and visit a nonexistent
URL. (This works on the nqjoanran just as well as it works on a production server.)
Implementing a 500 Template
Similarly, if @A>QC is B]hoa, then Django no longer displays its useful error/traceback pages in
V>ÃiÊvÊ>ÊÕ>`i`Ê*ÞÌÊiÝVi«Ì°ÊÃÌi>`]ÊÌÊÃÊvÀÊ>ÊÌi«>ÌiÊV>i`Ê1,,*dpih and
renders it. Like 0,0*dpih, this template should live in your root template directory.
There’s one slightly tricky thing about 1,,*dpih. You can never be sure why this template
ÃÊLi}ÊÀi`iÀi`]ÊÃÊÌÊÃÕ`½ÌÊ`Ê>ÞÌ}ÊÌ>ÌÊÀiµÕÀiÃÊ>Ê`>Ì>L>ÃiÊViVÌÊÀÊÀiiÃÊ
on any potentially broken part of your infrastructure. (For example, it should not use custom
template tags.) If it uses template inheritance, then the parent template(s) shouldn’t rely on
potentially broken infrastructure, either. Therefore, the best approach is to avoid template
inheritance and use something very simple. Here’s an example 1,,*dpih as a starting point:
8@K?PULAdpihLQ>HE?)++S/?++@P@DPIH0*,-++AJ
dppl6++sss*s/*knc+PN+dpih0+opne_p*`p`:
8dpihh]jc9aj:
8da]`:
8pepha:L]caqj]r]eh]^ha8+pepha:
8+da]`:
CHAPTER 12 N DEPLOYING DJANGO 215
8^k`u:
8d-:L]caqj]r]eh]^ha8+d-:
8l:Oknnu(^qppdanamqaopa`l]caeoqj]r]eh]^ha`qapk]
oanrande__ql*8+l:
8l:Kqnajcejaanod]ra^aajjkpebea`(ok_da_g^]_gh]pan*8+l:
8+^k`u:
8+dpih:
Setting Up Error Alerts
When your Django-powered site is running and an exception is raised, you’ll want to know
about it, so you can fix it. By default, Django is configured to send an e-mail to the site developers
ÜiiÛiÀÊÞÕÀÊV`iÊÀ>ÃiÃÊ>ÊÕ>`i`ÊiÝVi«ÌpLÕÌÊÞÕÊii`ÊÌÊ`ÊÌÜÊÌ}ÃÊÌÊÃiÌÊÌÊÕ«°
First, change your =@IEJO setting to include your e-mail address, along with the e-mail
addresses of any other people who need to be notified. This setting takes $j]ia(ai]eh% tuples,
like this:
=@IEJO9$
$#FkdjHajjkj#(#fhajjkj<at]ilha*_ki#%(
$#L]qhI_?]npjau#(#li]__]<at]ilha*_ki#%(
%
Second, make sure that your server is configured to send e-mail. Setting up lkopbet,
oaj`i]eh, or any other mail server is outside the scope of this book, but on the Django side of
things, you’ll want to make sure that your AI=EH[DKOP setting is set to the proper hostname for
your mail server. It’s set to #hk_]hdkop# by default, which works out of the box for most shared-
hosting environments. You might also need to set AI=EH[DKOP[QOAN, AI=EH[DKOP[L=OOSKN@,
AI=EH[LKNP, or AI=EH[QOA[PHO, depending on the complexity of your arrangement.
Also, you can set AI=EH[OQ>FA?P[LNABET to control the prefix Django uses in front of its
error e-mail. It is set to #W@f]jckY# by default.
Setting Up Broken Link Alerts
If you have the ?kiikjIe``has]na installed (e.g., if your IE@@HAS=NA[?H=OOAO setting includes
#`f]jck*ie``has]na*_kiikj*?kiikjIe``has]na#, which it does by default), you have the option
of receiving an e-mail any time somebody visits a page on your Django-powered site that
À>ÃiÃÊ{ä{ÊÜÌÊ>Êi«ÌÞÊÀiviÀÀiÀpÌ>ÌÊÃ]ÊiÛiÀÞÊLÀiÊ°ÊvÊÞÕÊÜ>ÌÊÌÊ>VÌÛ>ÌiÊÌÃÊ
feature, set OAJ@[>NKGAJ[HEJG[AI=EHO to Pnqa (it’s B]hoa by default) and set your I=J=CANO set-
ting to a person or people who will receive this broken-link e-mail. I=J=CANO uses the same
syntax as =@IEJO. For example:
I=J=CANO9$
$#CakncaD]nneokj#(#cd]nneokj<at]ilha*_ki#%(
$#NejckOp]nn#(#nejck<at]ilha*_ki#%(
%
Note that error e-mail can get annoying; they’re not for everybody.
CHAPTER 12 N DEPLOYING DJANGO
216
Using Different Settings for Production
So far in this book, we’ve dealt with only a single settings file: the oappejco*lu generated
by `f]jck)]`iej*luop]nplnkfa_p. But as you get ready to deploy, you’ll likely find yourself
needing multiple settings files to keep your development environment isolated from your pro-
duction environment. (For example, you probably won’t want to change @A>QC from B]hoa to
Pnqa whenever you want to test code changes on your local machine.) Django makes this very
easy by allowing you to use multiple settings files.
If you want to organize your settings files into “production” and “development” settings,
you can accomplish it in three ways:
Ê UÊ -iÌÊÕ«ÊÌÜÊvÕLÜ]Ê`i«i`iÌÊÃiÌÌ}ÃÊvið
Ê UÊ -iÌÊÕ«Ê>ʺL>Ãi»ÊÃiÌÌ}ÃÊviÊÃ>Þ]ÊvÀÊ`iÛi«iÌ®Ê>`Ê>ÊÃiV`ÊÃ>Þ]Ê«À`ÕVÌ®ÊÃiÌ-
tings file that merely imports from the first one and defines whatever overrides it needs
to define.
Ê UÊ 1ÃiÊÞÊ>ÊÃ}iÊÃiÌÌ}ÃÊviÊÌ>ÌÊ>ÃÊ*ÞÌÊ}VÊÌÊV>}iÊÌiÊÃiÌÌ}ÃÊL>Ãi`ÊÊ
context.
We’ll take these one at a time.
First, the most basic approach is to define two separate settings files. If you’re following
along, you’ve already got oappejco*lu. Now, just make a copy of it called oappejco[lnk`q_pekj*lu.
(We made this name up; you can call it whatever you want.) In this new file, change @A>QC, and
so on.
The second approach is similar, but cuts down on redundancy. Instead of having two set-
tings files whose contents are mostly similar, you can treat one as the “base” file and create
another file that imports from it. For example:
oappejco*lu
@A>QC9Pnqa
PAILH=PA[@A>QC9@A>QC
@=P=>=OA[AJCEJA9#lkopcnaomh[lou_klc.#
@=P=>=OA[J=IA9#`ar`^#
@=P=>=OA[QOAN9##
@=P=>=OA[L=OOSKN@9##
@=P=>=OA[LKNP9##
***
oappejco[lnk`q_pekj*lu
bnkioappejcoeilknp&
@A>QC9PAILH=PA[@A>QC9B]hoa
@=P=>=OA[J=IA9#lnk`q_pekj#
@=P=>=OA[QOAN9#]ll#
@=P=>=OA[L=OOSKN@9#hapiaej#
CHAPTER 12 N DEPLOYING DJANGO 217
Here, oappejco[lnk`q_pekj*lu imports everything from oappejco*lu and just redefines the
settings that are particular to production. In this case, @A>QC is set to B]hoa, but we also set dif-
ferent database access parameters for the production setting. (The latter goes to show that you
can redefine any setting, not just the basic ones such as @A>QC.)
Finally, the most concise way of accomplishing two settings environments is to use a
single settings file that branches based on the environment. One way to do this is to check the
current hostname. For example:
oappejco*lu
eilknpok_gap
ebok_gap*capdkopj]ia$%99#iu)h]lpkl#6
@A>QC9PAILH=PA[@A>QC9Pnqa
ahoa6
@A>QC9PAILH=PA[@A>QC9B]hoa
***
Here, we import the ok_gap moduleÊvÀÊ*ÞÌ½ÃÊÃÌ>`>À`ÊLÀ>ÀÞÊ>`ÊÕÃiÊÌÊÌÊViVÊ
the current system’s hostname. We can check the hostname to determine whether the code is
being run on the production server.
A core lesson here is that settings files are just Python code. They can import from other
files, they can execute arbitrary logic, and so on. Just make sure that if you go down this road,
ÌiÊ*ÞÌÊV`iÊÊÞÕÀÊÃiÌÌ}ÃÊviÃÊÃÊLÕiÌ«Àv°ÊvÊÌÊÀ>ÃiÃÊ>ÞÊiÝVi«ÌÃ]Ê>}ÊÜÊ
likely crash badly.
RENAMING SETTINGS.PY
Feel free to rename your oappejco*lu to oappejco[`ar*lu, or oappejco+`ar*lu, or bkk^]n*lu
Django doesn’t care, as long as you tell it what settings file you’re using.
But if you do rename the oappejco*lu file that is generated by `f]jck)]`iej*luop]nplnkfa_p,
you’ll find that i]j]ca*lu will give you an error message saying that it can’t find the settings. That’s
because it tries to import a module called oappejco. You can fix this either by editing i]j]ca*lu to change
oappejco to the name of your module, or by using `f]jck)]`iej*lu instead of i]j]ca*lu. In the latter
case, you’ll need to set the @F=JCK[OAPPEJCO[IK@QHA environment variable to the Python path to your set-
tings file (e.g., #iuoepa*oappejco#).
DJANGO_SETTINGS_MODULE
With those code changes out of the way, the next part of this chapter will focus on deploy-
ment instructions for specific environments, such as Apache. The instructions are different
for each environment, but one thing remains the same: in each case, you have to tell the Web
server your @F=JCK[OAPPEJCO[IK@QHA. This is the entry point into your Django application. The
@F=JCK[OAPPEJCO[IK@QHA points to your settings file, which points to your NKKP[QNH?KJB, which
points to your views, and so on.
CHAPTER 12 N DEPLOYING DJANGO
218
@F=JCK[OAPPEJCO[IK@QHAÊÃÊÌiÊ*ÞÌÊ«>ÌÊÌÊÞÕÀÊÃiÌÌ}ÃÊvi°ÊÀÊiÝ>«i]Ê>ÃÃÕ}Ê
that the iuoepa directoryÊÃÊÊÞÕÀÊ*ÞÌÊ«>Ì]ÊÌiÊ@F=JCK[OAPPEJCO[IK@QHA for our ongoing
example is #iuoepa*oappejco#.
Using Django with Apache and mod_python
Apache with mod_python historically has been the suggested setup for using Django on a pro-
duction server.
mod_python (dppl6++sss*`f]jcklnkfa_p*_ki+n+ik`[lupdkj+) is an Apache plug-in that
iLi`ÃÊ*ÞÌÊÜÌÊ«>ViÊ>`Ê>`ÃÊ*ÞÌÊV`iÊÌÊiÀÞÊÜiÊÌiÊÃiÀÛiÀÊÃÌ>ÀÌðÊ
Code stays in memory throughout the life of an Apache process, which leads to significant per-
formance gains over other server arrangements.
>}ÊÀiµÕÀiÃÊ«>ViÊÓ°ÝÊ>`Ê`Ú«ÞÌÊΰݰ
NNote Configuring Apache is well beyond the scope of this book, so we’ll simply mention details as
needed. Luckily, many great resources are available if you need to learn more about Apache. A few of them
we like are the following.
Ê UÊ /iÊvÀiiÊiÊ«>ViÊ`VÕiÌ>Ì]Ê>Û>>LiÊÛ>Êdppl6++sss*`f]jcklnkfa_p*
_ki+n+]l]_da+`k_o+
ÊUÊPro Apache, Third EditionÊLÞÊ*iÌiÀÊ7>ÜÀ}ÌÊ«ÀiÃÃ]ÊÓää{®]Ê>Û>>LiÊÛ>Êdppl6++
sss*`f]jcklnkfa_p*_ki+n+^kkgo+lnk)]l]_da+
ÊUÊApache: The Definitive Guide, Third EditionÊLÞÊiÊ>ÕÀiÊ>`Ê*iÌiÀÊ>ÕÀiÊ"½,iÞ]Ê
ÓääÓ®]Ê>Û>>LiÊÛ>Êdppl6++sss*`f]jcklnkfa_p*_ki+n+^kkgo+lnk)]l]_da+
Basic Configuration
To configure Django with mod_python, first make sure you have Apache installed with the
mod_python module activated. This usually means having a Hk]`Ik`qha directive in your
Apache configuration file. It will look something like this:
Hk]`Ik`qhalupdkj[ik`qha+qon+he^+]l]_da.+ik`qhao+ik`[lupdkj*ok
Then, edit your Apache configuration file and add a 8Hk_]pekj: directive that ties a spe-
cific URL path to a specific Django installation. For example:
8Hk_]pekj+:
OapD]j`hanlupdkj)lnkcn]i
LupdkjD]j`han`f]jck*_kna*d]j`hano*ik`lupdkj
OapAjr@F=JCK[OAPPEJCO[IK@QHAiuoepa*oappejco
Lupdkj@a^qcKbb
8+Hk_]pekj:
CHAPTER 12 N DEPLOYING DJANGO 219
Make sure to replace iuoepa*oappejco with the appropriate @F=JCK[OAPPEJCO[IK@QHA for
your site.
This tells Apache, “Use mod_python for any URL at or under ‘/’, using the Django mod_
python handler.” It passes the value of @F=JCK[OAPPEJCO[IK@QHA so mod_python knows which
settings to use.
Note that we’re using the 8Hk_]pekj: directive, not the 8@ena_pknu: directive. The latter is
used for pointing at places on your filesystem, whereas 8Hk_]pekj: points at places in the URL
structure of a Web site. 8@ena_pknu: would be meaningless here.
Apache likely runs as a different user than your normal login and may have a different
path and ouo*l]pd. You may need to tell mod_python how to find your project and Django
itself.
LupdkjL]pdW#+l]pd+pk+lnkfa_p#(#+l]pd+pk+`f]jck#Y'ouo*l]pd
You can also add directives such as Lupdkj=qpkNahk]`Kbb for performance. See the mod_
python documentation for a full list of options.
Note that you should set Lupdkj@a^qcKbb on a production server. If you leave Lupdkj@a^qc
Kj]ÊÞÕÀÊÕÃiÀÃÊÜÊÃiiÊÕ}ÞÊ>`ÊÀiÛi>}®Ê*ÞÌÊÌÀ>ViL>VÃÊvÊÃiÌ}Ê}iÃÊÜÀ}ÊÜÌÊ
mod_python.
,iÃÌ>ÀÌÊ«>Vi]Ê>`Ê>ÞÊÀiµÕiÃÌÊÌÊÞÕÀÊÃÌiÊÀÊÛÀÌÕ>ÊÃÌÊvÊÞÕ½ÛiÊ«ÕÌÊÌÃÊ`ÀiVÌÛiÊ
inside a 8Renpq]hDkop: block) will be served by Django.
Running Multiple Django Installations on the
Same Apache Instance
It’s entirely possible to run multiple Django installations on the same Apache instance. You
might want to do this if you’re an independent Web developer with multiple clients but only a
single server.
To accomplish this, just use Renpq]hDkop like so:
J]iaRenpq]hDkop&
8Renpq]hDkop&:
OanranJ]iasss*at]ilha*_ki
***
OapAjr@F=JCK[OAPPEJCO[IK@QHAiuoepa*oappejco
8+Renpq]hDkop:
8Renpq]hDkop&:
OanranJ]iasss.*at]ilha*_ki
***
OapAjr@F=JCK[OAPPEJCO[IK@QHAiuoepa*kpdan[oappejco
8+Renpq]hDkop:
If you need to put two Django installations within the same Renpq]hDkop, you’ll need to
take a special precaution to ensure mod_python’s code cache doesn’t mess things up. Use the
LupdkjEjpanlnapan directive to give different 8Hk_]pekj: directives separate interpreters:
CHAPTER 12 N DEPLOYING DJANGO
220
8Renpq]hDkop&:
OanranJ]iasss*at]ilha*_ki
***
8Hk_]pekj+okiapdejc:
OapAjr@F=JCK[OAPPEJCO[IK@QHAiuoepa*oappejco
LupdkjEjpanlnapaniuoepa
8+Hk_]pekj:
8Hk_]pekj+kpdanpdejc:
OapAjr@F=JCK[OAPPEJCO[IK@QHAiuoepa*kpdan[oappejco
LupdkjEjpanlnapaniuoepa[kpdan
8+Hk_]pekj:
8+Renpq]hDkop:
The values of LupdkjEjpanlnapan don’t really matter, as long as they’re different between
the two Hk_]pekj blocks.
Running a Development Server with mod_python
Because mod_python cachesÊ>`i`Ê*ÞÌÊV`i]ÊÜiÊ`i«Þ}Ê>}ÊÃÌiÃÊÊ`Ú
python you’ll need to restart Apache each time you make changes to your code. This can be a
>ÃÃi]ÊÃÊiÀi½ÃÊ>ʵÕVÊÌÀVÊÌÊ>Û`ÊÌ\ÊÕÃÌÊ>``ÊI]tNamqaopoLan?deh`- to your config file to
vÀViÊ«>ViÊÌÊÀi>`ÊiÛiÀÞÌ}ÊvÀÊi>VÊÀiµÕiÃÌ°ÊÕÌÊ`½ÌÊ`ÊÌ>ÌÊÊ>Ê«À`ÕVÌÊÃiÀÛiÀ]Ê
or we’ll revoke your Django privileges.
If you’re the type of programmer who debugs using scattered lnejp statements (we are),
note that lnejp statements have no effect in mod_python; they don’t appear in the Apache log,
as you might expect. If you have the need to print debugging information in a mod_python
ÃiÌÕ«]ÊÞÕ½Ê«ÀL>LÞÊÜ>ÌÊÌÊÕÃiÊ*ÞÌ½ÃÊÃÌ>`>À`Ê}}}Ê«>V>}i°ÊÀi information is
available at dppl6++`k_o*lupdkj*knc+he^+ik`qha)hkccejc*dpih.
Serving Django and Media Files from the Same Apache Instance
Django should not be used to serve media files itself; leave that job to whichever Web server
you choose. We recommend using a separate Web server (i.e., one that’s not also running
Django) for serving media. For more information, see the “Scaling” section.
If, however, you have no option but to serve media files on the same Apache Renpq]hDkop
as Django, here’s how you can turn off mod_python for a particular part of the site:
8Hk_]pekj+ia`e]+:
OapD]j`hanJkja
8+Hk_]pekj:
Change Hk_]pekj to the root URL of your media files.
You can also use 8Hk_]pekjI]p_d: to match a regular expression. For example, this sets up
Django at the site root but explicitly disables Django for the ia`e] subdirectory and any URL
that ends with *flc, *ceb, or *ljc:
CHAPTER 12 N DEPLOYING DJANGO 221
8Hk_]pekj+:
OapD]j`hanlupdkj)lnkcn]i
LupdkjD]j`han`f]jck*_kna*d]j`hano*ik`lupdkj
OapAjr@F=JCK[OAPPEJCO[IK@QHAiuoepa*oappejco
8+Hk_]pekj:
8Hk_]pekj+ia`e]+:
OapD]j`hanJkja
8+Hk_]pekj:
8Hk_]pekjI]p_dX*$flcxcebxljc% :
OapD]j`hanJkja
8+Hk_]pekjI]p_d:
In all of these cases, you’ll need to set the @k_qiajpNkkp directive so Apache knows where
to find your static files.
Error Handling
When youÊÕÃiÊ«>ViÉ`Ú«ÞÌ]ÊiÀÀÀÃÊÜÊLiÊV>Õ}ÌÊLÞÊ>}pÊÌiÀÊÜÀ`Ã]ÊÌiÞÊ
won’t propagate to the Apache level and won’t appear in the Apache annkn[hkc.
The exception to this is if something is really messed up in your Django setup. In that
V>Ãi]ÊÞÕ½ÊÃiiÊ>ÊÕÃʺÌiÀ>Ê-iÀÛiÀÊÀÀÀ»Ê«>}iÊÊÞÕÀÊLÀÜÃiÀÊ>`ÊÌiÊvÕÊ*ÞÌÊ
traceback in your Apache annkn[hkc file. The annkn[hkc traceback is spread over multiple lines.
(Yes, this is ugly and rather hard to read, but it’s how mod_python does things.)
Handling a Segmentation Fault
Sometimes, Apache segfaults when you install Django. When this happens, it’s almost always
one of two causes mostly unrelated to Django itself:
Ê UÊ ÌÊ>ÞÊLiÊÌ>ÌÊÞÕÀÊ*ÞÌÊV`iÊÃÊ«ÀÌ}ÊÌiÊluatl]p module (used for XML pars-
ing), which may conflict with the version embedded in Apache. For full information,
see “Expat Causing Apache Crash” at dppl6++sss*`f]jcklnkfa_p*_ki+n+]npe_hao+
atl]p)]l]_da)_n]od+.
Ê UÊ ÌÊ>ÞÊLiÊLiV>ÕÃiÊÞÕ½ÀiÊÀÕ}Ê`Ú«ÞÌÊ>`Ê`Ú««ÊÊÌiÊÃ>iÊ«>ViÊ
instance, with MySQL as your database back-end. In some cases, this causes a known
`Ú«ÞÌÊÃÃÕiÊ`ÕiÊÌÊÛiÀÃÊVvVÌÃÊÊ**Ê>`ÊÌiÊ*ÞÌÊÞ-+ÊL>Vi`°Ê
There’s full information in a mod_python FAQ entry, accessible via dppl6++sss*
`f]jcklnkfa_p*_ki+n+]npe_hao+ldl)ik`lupdkj)b]m+.
If you continue to have problems setting up mod_python, a good thing to do is get a bare-
bones mod_python site working, without the Django framework. This is an easy way to isolate
mod_python-specific problems. The article “Getting mod_python Working” details this proce-
dure: dppl6++sss*`f]jcklnkfa_p*_ki+n+]npe_hao+cappejc)ik`lupdkj)skngejc+.
CHAPTER 12 N DEPLOYING DJANGO
222
The next step should be to edit your test code and add an import of any Django-specific
V`iÊÞÕ½ÀiÊÕÃ}pÞÕÀÊÛiÜÃ]ÊÞÕÀÊ`iÃ]ÊÞÕÀÊ1,Vv]ÊÞÕÀÊ,--ÊVv}ÕÀ>Ì]Ê>`ÊÃÊ
vÀÌ°Ê*ÕÌÊÌiÃiÊ«ÀÌÃÊÊÞÕÀÊÌiÃÌÊ>`iÀÊvÕVÌÊ>`Ê>VViÃÃÊÞÕÀÊÌiÃÌÊ1,ÊÊ>ÊLÀÜÃiÀ°Ê
If this causes a crash, you’ve confirmed it’s the importing of Django code that causes the
problem. Gradually reduce the set of imports until it stops crashing, so as to find the specific
module that causes the problem. Drop down further into modules and look into their imports
as necessary. For more help, system tools like h`_kjbec on Linux, kpkkh on Mac OS, and
Heop@HHo (from SysInternals) on Windows can help you identify shared dependencies and
possible version conflicts.
An Alternative: mod_wsgi
As an alternative to mod_python, you might consider using mod_wsgi (dppl6++_k`a*ckkcha*
_ki+l+ik`soce+), which has been developed more recently than mod_python and is getting
some traction in the Django community. A full overview is outside the scope of this book, but
see the official Django documentation for more information.
Using Django with FastCGI
Although Django under Apache and mod_python is the most robust deployment setup, many
people use shared hosting, on which FastCGI is the only available deployment option.
Additionally, in some situations, FastCGI allows better security and possibly better perfor-
mance than mod_python. For small sites, FastCGI can also be more lightweight than Apache.
FastCGI Overview
FastCGI is an efficient way of letting an external application serve pages to a Web server. The
7iLÊÃiÀÛiÀÊ`ii}>ÌiÃÊÌiÊV}Ê7iLÊÀiµÕiÃÌÃÊÛ>Ê>ÊÃViÌ®ÊÌÊ>ÃÌ]ÊÜVÊiÝiVÕÌiÃÊÌiÊ
code and passes the response back to the Web server, which, in turn, passes it back to the cli-
ent’s Web browser.
iÊ`Ú«ÞÌ]Ê>ÃÌÊ>ÜÃÊV`iÊÌÊÃÌ>ÞÊÊiÀÞ]Ê>Ü}ÊÀiµÕiÃÌÃÊÌÊLiÊÃiÀÛi`Ê
with no startup time. Unlike mod_python, a FastCGI process doesn’t run inside the Web
server process, but in a separate, persistent process.
WHY RUN CODE IN A SEPARATE PROCESS?
The traditional ik`[& arrangements in Apache embed various scripting languages (most notably PHP, Python/
mod_python, and Perl/mod_perl) inside the process space of your Web server. Although this lowers startup
time (because code doesn’t have to be read off disk for every request), it comes at the cost of memory use.
Each Apache process gets a copy of the Apache engine, complete with all the features of Apache that
Django simply doesn’t take advantage of. FastCGI processes, on the other hand, only have the memory over-
head of Python and Django.
Due to the nature of FastCGI, it’s also possible to have processes that run under a different user account
than the Web server process. That’s a nice security benefit on shared systems, because it means you can
secure your code from other users.
CHAPTER 12 N DEPLOYING DJANGO 223
Before you can start using FastCGI with Django, you’ll need to install bhql]Ê>Ê*ÞÌÊ
library for dealing with FastCGI. Some users have reported stalled pages with older bhql ver-
sions, so you may want to use the latest SVN version. Get bhql at dppl6++sss*`f]jcklnkfa_p*
_ki+n+bhql+.
Running Your FastCGI Server
FastCGI operates on a client/server model, and in most cases you’ll be starting the FastCGI
server process on your own. Your Web server (be it Apache, lighttpd, or otherwise) contacts
your Django-FastCGI process only when the server needs a dynamic page to be loaded.
Because the daemon is already running with the code in memory, it’s able to serve the
ÀiëÃiÊÛiÀÞʵÕVÞ°
NNote If you’re on a shared hosting system, you’ll probably be forced to use Web server-managed FastCGI
processes. If you’re in this situation, you should read the section titled “Running Django on a Shared-Hosting
Provider with Apache,” later in this chapter.
A Web server can connect to a FastCGI server in one of two ways: it can use either a Unix
domain socket (a named pipeÊÊ7ÎÓÊÃÞÃÌiîÊÀÊ>Ê/*ÊÃViÌ°Ê7>ÌÊÞÕÊVÃiÊÃÊ>Ê>ÌÌiÀÊ
vÊ«ÀiviÀiViÆÊ>Ê/*ÊÃViÌÊÃÊÕÃÕ>ÞÊi>ÃiÀÊ`ÕiÊÌÊ«iÀÃÃÃÊÃÃÕið
To start your server, first change into the directory of your project (wherever your i]j]ca*
lu is), and then run i]j]ca*lu with the nqjb_ce command:
*+i]j]ca*lunqjb_ceWklpekjoY
If you specify dahl as the only option after nqjb_ce, a list of all the available options will
display.
You’ll need to specify either a ok_gap or both dkop and lknp. Then, when you set up your
Web server, you’ll just need to point it at the socket or host/port you specified when starting
the FastCGI server.
A few examples should help explain this:
Ê UÊ ,Õ}Ê>ÊÌÀi>`i`ÊÃiÀÛiÀÊÊ>Ê/*Ê«ÀÌ\
*+i]j]ca*lunqjb_ceiapdk`9pdna]`a`dkop9-.3*,*,*-lknp9/,//
Ê UÊ ,Õ}Ê>Ê«ÀivÀi`ÊÃiÀÛiÀÊÊ>Ê1ÝÊ`>ÊÃViÌ\
*+i]j]ca*lunqjb_ceiapdk`9lnabkng£
ok_gap9+dkia+qoan+iuoepa*ok_gle`beha9`f]jck*le`
Ê UÊ ,Õ}ÊÜÌÕÌÊ`>iâ}ÊL>V}ÀÕ`}®ÊÌiÊ«ÀViÃÃÊ}`ÊvÀÊ`iLÕ}}}®\
*+i]j]ca*lunqjb_ce`]aikjeva9b]hoaok_gap9+pil+iuoepa*ok_g
CHAPTER 12 N DEPLOYING DJANGO
224
Stopping the FastCGI Daemon
If you have the process running in the foreground, it’s easy enough to stop it: simply press
ÌÀ³ÊÌÊÃÌ«Ê>`ʵÕÌÊÌiÊ>ÃÌÊÃiÀÛiÀ°ÊÜiÛiÀ]ÊÜiÊÞÕ½ÀiÊ`i>}ÊÜÌÊL>V}ÀÕ`Ê
processes, you’ll need to resort to the Unix gehh command.
If you specify the le`beha option to your i]j]ca*lunqjb_ce, you can kill the running
FastCGI daemon like this:
gehh#_]p LE@BEHA#
where LE@BEHA is the le`beha you specified.
To easily restart your FastCGI daemon on Unix, you can use this small shell script:
+^ej+^]od
Nalh]_apdaoapdnaaoappejco*
LNKF@EN9+dkia+qoan+iulnkfa_p
LE@BEHA9 LNKF@EN+iuoepa*le`
OK?GAP9 LNKF@EN+iuoepa*ok_g
_` LNKF@EN
ebW)b LE@BEHAY7pdaj
gehh#_]pÍ LE@BEHA#
ni)bÍ LE@BEHA
be
ata_+qon+^ej+ajr)X
LUPDKJL=PD9**+lupdkj6**X
*+i]j]ca*lunqjb_ceok_gap9 OK?GAPle`beha9 LE@BEHA
Using Django with Apache and FastCGI
To use Django with Apache and FastCGI, you’ll need Apache installed and configured, with
mod_fastcgi installed and enabled. Consult the Apache and mod_fastcgi documentation for
instructions: dppl6++sss*`f]jcklnkfa_p*_ki+n+ik`[b]op_ce+.
Once you’ve completed the setup, point Apache at your Django FastCGI instance by edit-
ing the dppl`*_kjb (Apache configuration) file. You’ll need to do two things:
Ê UÊ 1ÃiÊÌiÊB]op?CEAtpanj]hOanran directive to specify the location of your FastCGI server.
Ê UÊ 1ÃiÊik`[nasnepa to point URLs at FastCGI as appropriate.
CHAPTER 12 N DEPLOYING DJANGO 225
Specifying the Location of the FastCGI Server
The B]op?CEAtpanj]hOanran directive tells Apache how to find your FastCGI server. As
the FastCGIExternalServer docs (dppl6++sss*`f]jcklnkfa_p*_ki+n+ik`[b]op_ce+
B]op?CEAtpanj]hOanran+) explain, you can specify either a ok_gap or a dkop. Here are
examples of both:
?kjja_ppkB]op?CEre]]ok_gap+j]ia`lela6
B]op?CEAtpanj]hOanran+dkia+qoan+lq^he_[dpih+iuoepa*b_ce£
)ok_gap+dkia+qoan+iuoepa*ok_g
?kjja_ppkB]op?CEre]]P?Ldkop+lknp6
B]op?CEAtpanj]hOanran+dkia+qoan+lq^he_[dpih+iuoepa*b_ce)dkop-.3*,*,*-6/,//
In either case, the directory +dkia+qoan+lq^he_[dpih+ should exist, though the file
+dkia+qoan+lq^he_[dpih+iuoepa*b_ce doesn’t actually have to exist. It’s just a URL used by the
7iLÊÃiÀÛiÀÊÌiÀ>Þp>ÊÊvÀÊÃ}vÞ}ÊÜVÊÀiµÕiÃÌÃÊ>ÌÊ>Ê1,ÊÃÕ`ÊLiÊ>`i`ÊLÞÊ
FastCGI. (More on this in the next section.)
Using mod_rewrite to Point URLs at FastCGI
The second step is telling Apache to use FastCGI for URLs that match a certain pattern. To do
this, use the ik`[nasnepa module and rewrite URLs to iuoepa*b_ce (or whatever you specified
in the B]op?CEAtpanj]hOanran directive, as explained in the previous section).
ÊÌÃÊiÝ>«i]ÊÜiÊÌiÊ«>ViÊÌÊÕÃiÊ>ÃÌÊÌÊ>`iÊ>ÞÊÀiµÕiÃÌÊÌ>ÌÊ`iÃ½ÌÊÀi«Ài-
sent a file on the filesystem and doesn’t start with +ia`e]+. This is probably the most common
case, if you’re using Django’s admin site:
8Renpq]hDkop-.*/0*12*34:
OanranJ]iaat]ilha*_ki
@k_qiajpNkkp+dkia+qoan+lq^he_[dpih
=he]o+ia`e]+dkia+qoan+lupdkj+`f]jck+_kjpne^+]`iej+ia`e]
NasnepaAjcejaKj
NasnepaNqhaZ+$ia`e]*&% + -WMO=(HY
Nasnepa?kj`!wNAMQAOP[BEHAJ=IAy)b
NasnepaNqhaZ+$*&% +iuoepa*b_ce+ -WMO=(HY
8+Renpq]hDkop:
FastCGI and lighttpd
lighttpd (dppl6++sss*`f]jcklnkfa_p*_ki+n+hecdppl`+) is a lightweight Web server commonly
used for serving static files. It supports FastCGI natively and thus is also an ideal choice for
serving both static and dynamic pages, if your site doesn’t have any Apache-specific needs.
Make sure ik`[b]op_ce is in your modules list, somewhere after ik`[nasnepa and ik`[
]__aoo, but not after ik`[]__aoohkc. You’ll probably want ik`[]he]o as well, for serving admin
media.
CHAPTER 12 N DEPLOYING DJANGO
226
Add the following to your lighttpd config file:
oanran*`k_qiajp)nkkp9+dkia+qoan+lq^he_[dpih
b]op_ce*oanran9$
+iuoepa*b_ce9:$
i]ej9:$
Qoadkop+lknpejopa]`kbok_gapbknP?Lb]op_ce
dkop9:-.3*,*,*-(
lknp9:/,//(
ok_gap9:+dkia+qoan+iuoepa*ok_g(
_da_g)hk_]h9:`eo]^ha(
%
%(
%
]he]o*qnh9$
+ia`e]+9:+dkia+qoan+`f]jck+_kjpne^+]`iej+ia`e]+(
%
qnh*nasnepa)kj_a9$
Z$+ia`e]*&% 9: -(
Z+b]re_kjX*e_k 9:+ia`e]+b]re_kj*e_k(
Z$+*&% 9:+iuoepa*b_ce -(
%
Running Multiple Django Sites on One lighttpd Instance
lighttpd lets you use “conditional configuration” to allow configuration to be customized per
host. To specify multiple FastCGI sites, just add a conditional block around your FastCGI con-
fig for each site:
Ebpdadkopj]iaeo#sss*at]ilha-*_ki#***
DPPLWdkopY99sss*at]ilha-*_kiw
oanran*`k_qiajp)nkkp9+bkk+oepa-
b]op_ce*oanran9$
***
%
***
y
Ebpdadkopj]iaeo#sss*at]ilha.*_ki#***
DPPLWdkopY99sss*at]ilha.*_kiw
oanran*`k_qiajp)nkkp9+bkk+oepa.
b]op_ce*oanran9$
***
%
***
y
CHAPTER 12 N DEPLOYING DJANGO 227
You can also run multiple Django installations on the same site simply by specifying mul-
tiple entries in the b]op_ce*oanran directive. Add one FastCGI host for each.
Running Django on a Shared-Hosting Provider with Apache
Many shared-hosting providers don’t allow you to run your own server daemons or edit the dppl`*
_kjb file. In these cases, it’s still possible to run Django using Web server-spawned processes.
NNote If you’re using Web server-spawned processes, as explained in this section, there’s no need for you
to start the FastCGI server on your own. Apache will spawn a number of processes, scaling as it needs to.
In your Web root directory, add this to a file named *dp]__aoo:
=``D]j`hanb]op_ce)o_nelp*b_ce
NasnepaAjcejaKj
Nasnepa?kj`!wNAMQAOP[BEHAJ=IAy)b
NasnepaNqhaZ$*&% iuoepa*b_ce+ -WMO=(HY
Then, create a small script that tells Apache how to spawn your FastCGI program. Create a
file, iuoepa*b_ce, and place it in your Web directory, and be sure to make it executable:
+qon+^ej+lupdkj
eilknpouo(ko
=``]_qopkiLupdkjl]pd*
ouo*l]pd*ejoanp$,(+dkia+qoan+lupdkj%
Osep_dpkpda`ena_pknukbukqnlnkfa_p*$Klpekj]h*%
ko*_d`en$+dkia+qoan+iulnkfa_p%
Oappda@F=JCK[OAPPEJCO[IK@QHAajrenkjiajpr]ne]^ha*
ko*ajrenkjW#@F=JCK[OAPPEJCO[IK@QHA#Y9iulnkfa_p*oappejco
bnki`f]jck*_kna*oanrano*b]op_ceeilknpnqjb]op_ce
nqjb]op_ce$iapdk`9pdna]`a`(`]aikjeva9b]hoa%
Restarting the Spawned Server
If youÊV>}iÊ>ÞÊ*ÞÌÊV`iÊÊÞÕÀÊÃÌi]ÊÞÕ½Êii`ÊÌÊÌiÊ>ÃÌÊÌiÊV`iÊ>ÃÊV>}i`°Ê
But there’s no need to restart Apache in this case. Rather, just reupload iuoepa*b_cepÀÊ
i`ÌÊÌiÊvipÃÊÌ>ÌÊÌiÊÌiÃÌ>«ÊÊÌiÊviÊV>}iðÊ7iÊ«>ViÊÃiiÃÊÌiÊviÊ>ÃÊLiiÊ
updated, it will restart your Django application for you.
If you have access to a command shell on a Unix system, you can accomplish this easily by
using the pkq_d command:
pkq_diuoepa*b_ce
CHAPTER 12 N DEPLOYING DJANGO
228
Scaling
Now that you know how to get Django running on a single server, let’s look at how you can
scale out a Django installation. This section walks through how a site might scale from a single
server to a large-scale cluster that could serve millions of hits an hour.
It’s important to note, however, that nearly every large site is large in different ways, so
scaling is anything but a one-size-fits-all operation. The following coverage should suffice
to show the general principle, and whenever possible we’ll try to point out where different
choices could be made.
First off, we’ll make a pretty big assumption and exclusively talk about scaling under
Apache and mod_python. Though we know of a number of successful medium- to large-scale
FastCGI deployments, we’re much more familiar with Apache.
Running on a Single Server
Most sites start out running on a single server, with an architecture that looks something like
Figure 12-1.
Server
Django
Database
Media
Figure 12-1. A single-server Django setup
/ÃÊÜÀÃÊÕÃÌÊviÊvÀÊÃ>ÊÌÊi`ÕÃâi`ÊÃÌiÃ]Ê>`Ê̽ÃÊÀi>ÌÛiÞÊVi>«pÞÕÊV>Ê
«ÕÌÊÌ}iÌiÀÊ>ÊÃ}iÃiÀÛiÀÊÃÌiÊ`iÃ}i`ÊvÀÊ>}ÊvÀÊÜiÊÕ`iÀÊfÎ]äää°
ÜiÛiÀ]Ê>ÃÊÌÀ>vvVÊVÀi>ÃiÃÊÞÕ½ʵÕVÞÊÀÕÊÌÊresource contention between the dif-
ferent pieces of software. Database servers and Web servers love to have the entire server
to themselves, so when run on the same server they often end up “fighting” over the same
ÀiÃÕÀViÃÊ,]Ê*1®ÊÌ>ÌÊÌiÞ½`Ê«ÀiviÀÊÌÊ«âi°
This is solved easily by moving the database server to a second machine, as explained in
the following section.
CHAPTER 12 N DEPLOYING DJANGO 229
Separating Out the Database Server
As far as Django is concerned, the process of separating out the database server is extremely
easy: you’ll simply need to change the @=P=>=OA[DKOP settingÊÌÊÌiÊ*ÊÀÊ -Ê>iÊvÊÞÕÀÊ
`>Ì>L>ÃiÊÃiÀÛiÀ°Ê̽ÃÊ«ÀL>LÞÊ>Ê}`Ê`i>ÊÌÊÕÃiÊÌiÊ*ÊvÊ>ÌÊ>Ê«ÃÃLi]Ê>ÃÊÀiÞ}ÊÊ -ÊvÀÊ
the connection between your Web server and database server isn’t recommended.
With a separate database server, our architecture now looks like Figure 12-2.
Django
Media
Web Server
Database Server
Database
Figure 12-2. Moving the database onto a dedicated server
Here we’re starting to move into what’s usually called n-tier architecture. Don’t be scared
LÞÊÌiÊLÕââÜÀ`pÌÊÕÃÌÊÀiviÀÃÊÌÊÌiÊv>VÌÊÌ>ÌÊ`vviÀiÌʺÌiÀûÊvÊÌiÊ7iLÊÃÌ>VÊ}iÌÊÃi«>À>Ìi`Ê
out onto different physical machines.
At this point, if you anticipate ever needing to grow beyond a single database server, it’s
probably a good idea to start thinking about connection pooling and/or database replication.
Unfortunately, there’s not nearly enough space to do those topics justice in this book, so you’ll
need to consult your database’s documentation and/or community for more information.
Running a Separate Media Server
We still have a big problem left over from the single-server setup: the serving of media from
the same box that handles dynamic content.
Those two activities perform best under different circumstances, and by smashing them
together on the same box you end up with neither performing particularly well. So the next
ÃÌi«ÊÃÊÌÊÃi«>À>ÌiÊÕÌÊÌiÊi`>pÌ>ÌÊÃ]Ê>ÞÌ}ÊnotÊ}iiÀ>Ìi`ÊLÞÊ>Ê>}ÊÛiÜpÌÊ>Ê
`i`V>Ìi`ÊÃiÀÛiÀÊÃiiÊ}ÕÀiÊ£Óή°
CHAPTER 12 N DEPLOYING DJANGO
230
Web Server
Database Server
Django
Database
Media Server
Media
Figure 12-3. Separating out the media server
Ideally, this media server should run a stripped-down Web server optimized for static
media delivery. lighttpd and tux (dppl6++sss*`f]jcklnkfa_p*_ki+n+pqt+) are both excellent
choices here, but a heavily stripped down Apache could work, too.
For sites heavy in static content (photos, videos, etc.), moving to a separate media server
is doubly important and should likely be the first step in scaling up.
This step can be slightly tricky, however. If your application involves file uploads, Django
needs to be able to write uploaded media to the media server. If media lives on another server,
you’ll need to arrange a way for that write to happen across the network.
Implementing Load Balancing and Redundancy
At this point, we’ve broken things down as much as possible. This three-server setup should
>`iÊ>ÊÛiÀÞÊ>À}iÊ>ÕÌÊvÊÌÀ>vvVpÜiÊÃiÀÛi`Ê>ÀÕ`Ê£äÊÊÌÃÊ>Ê`>ÞÊvÀÊ>Ê>ÀVÌiV-
ÌÕÀiÊvÊÌÃÊÃÀÌpÃÊvÊÞÕÊ}ÀÜÊvÕÀÌiÀ]ÊÞÕ½Êii`ÊÌÊÃÌ>ÀÌÊ>``}ÊÀi`Õ`>VÞ°
/ÃÊÃÊ>Ê}`ÊÌ}]Ê>VÌÕ>Þ°Ê"iÊ}>ViÊ>ÌÊ}ÕÀiÊ£ÓÎÊÃÜÃÊÞÕÊÌ>ÌÊvÊiÛiÊ>ÊÃ}iÊiÊ
of your three servers fails, you’ll bring down your entire site. So as you add redundant servers,
not only do you increase capacity, but you also increase reliability.
For the sake of this example, let’s assume that the Web server hits capacity first. It’s rela-
ÌÛiÞÊi>ÃÞÊÌÊ}iÌÊÕÌ«iÊV«iÃÊvÊ>Ê>}ÊÃÌiÊÀÕ}ÊÊ`vviÀiÌÊ>À`Ü>ÀipÕÃÌÊV«ÞÊ>Ê
the code onto multiple machines, and start Apache on all of them.
However, you’ll need another piece of software to distribute traffic over your multiple
servers: a load balancer. You can buy expensive and proprietary hardware load balancers, but
ÌiÀiÊ>ÀiÊ>ÊviÜÊ}µÕ>ÌÞÊ«iÊÃÕÀViÊÃvÌÜ>ÀiÊ>`ÊL>>ViÀÃÊÕÌÊÌiÀi°
CHAPTER 12 N DEPLOYING DJANGO 231
Apache’s ik`[lnktuÊÃÊiÊ«Ì]ÊLÕÌÊÜi½ÛiÊvÕ`Ê*iÀL>Êdppl6++sss*`f]jcklnkfa_p*
_ki+n+lanh^]h+) to be fantastic. It’s a load balancer and reverse proxy written by the same
folks who wrote Memcached (see Chapter 15).
NNote If you’re using FastCGI, you can accomplish this same distribution/load-balancing step by separat-
ing your front-end Web servers and back-end FastCGI processes onto different machines. The front-end
server essentially becomes the load balancer, and the back-end FastCGI processes replace the Apache/
mod_python/Django servers.
With the Web servers now clustered, our evolving architecture starts to look more com-
«iÝ]Ê>ÃÊÃÜÊÊ}ÕÀiÊ£Ó{°
Load Balancer
Perlbal
Django DjangoDjango
Web Server Cluster
Database Server
Database
Media Server
Media
Figure 12-4. A load-balanced, redundant server setup
Notice that in the diagram the Web servers are referred to as a “cluster” to indicate that
the number of servers is basically variable. Once you have a load balancer out front, you can
easily add and remove back-end Web servers without a second of downtime.
CHAPTER 12 N DEPLOYING DJANGO
232
Going Big
At this point, the next few steps are pretty much derivatives of the last one:
Ê UÊ ÃÊÞÕÊii`ÊÀiÊ`>Ì>L>ÃiÊ«iÀvÀ>Vi]ÊÞÕÊ}ÌÊÜ>ÌÊÌÊ>``ÊÀi«V>Ìi`Ê`>Ì>L>ÃiÊ
servers. MySQLÊVÕ`iÃÊLÕÌÊÀi«V>ÌÆÊ*ÃÌ}Ài-+ users should look into Slony
(dppl6++sss*`f]jcklnkfa_p*_ki+n+ohkju+) and pgpool (dppl6++sss*`f]jcklnkfa_p*
_ki+n+lclkkh+) for replication and connection pooling, respectively.
Ê UÊ vÊÌiÊÃ}iÊ>`ÊL>>ViÀÊÃ½ÌÊiÕ}]ÊÞÕÊV>Ê>``ÊÀiÊ>`ÊL>>ViÀÊ>ViÃÊÕÌÊ
front and distribute among them using round-robin DNS.
Ê UÊ vÊ>ÊÃ}iÊi`>ÊÃiÀÛiÀÊ`iÃ½ÌÊÃÕvvVi]ÊÞÕÊV>Ê>``ÊÀiÊi`>ÊÃiÀÛiÀÃÊ>`Ê`ÃÌÀLÕÌiÊ
the load with your load-balancing cluster.
Ê UÊ vÊÞÕÊii`ÊÀiÊV>ViÊÃÌÀ>}i]ÊÞÕÊV>Ê>``Ê`i`V>Ìi`ÊV>ViÊÃiÀÛiÀð
Ê UÊ ÌÊ>ÞÊÃÌ>}i]ÊvÊ>ÊVÕÃÌiÀÊÃ½ÌÊ«iÀvÀ}ÊÜi]ÊÞÕÊV>Ê>``ÊÀiÊÃiÀÛiÀÃÊÌÊÌiÊVÕÃÌiÀ°
After a few of these iterations, a large-scale architecture might look like Figure 12-5.
Django DjangoDjango
Web Server Cluster
Database DatabaseDatabase
Database Server Cluster
Perlbal PerlbalPerlbal
Media Server ClusterLoad Balancing Cluster
Cache Cluster
Media Media
Memcached Memcached
Figure 12-5. An example large-scale Django setup
Though we’ve shown only two or three servers at each level, there’s no fundamental limit
to how many you can add.
Performance Tuning
If you have a huge amount of money, you can just keep throwing hardware at scaling prob-
lems. For the rest of us, though, performance tuning is a must.
CHAPTER 12 N DEPLOYING DJANGO 233
NNote Incidentally, if anyone with monstrous gobs of cash is actually reading this book, please consider a
substantial donation to the Django Foundation. We accept uncut diamonds and gold ingots, too.
Unfortunately, performance tuning is much more of an art than a science, and it is even
more difficult to write about than scaling. If you’re serious about deploying a large-scale
Django application, you should spend a great deal of time learning how to tune each piece of
your stack.
The following sections, though, present a few Django-specific tuning tips we’ve discov-
ered over the years.
There’s No Such Thing As Too Much RAM
Even the really expensive RAM is relatively affordable these days. Buy as much RAM as you can
possibly afford, and then buy a little bit more.
Faster processors won’t improve performance all that much; most Web servers spend up
ÌÊä¯ÊvÊÌiÀÊÌiÊÜ>Ì}ÊÊ`ÃÊÉ"°ÊÃÊÃÊ>ÃÊÞÕÊÃÌ>ÀÌÊÃÜ>««}]Ê«iÀvÀ>ViÊÜÊÕÃÌÊ
die. Faster disks might help slightly, but they’re much more expensive than RAM, such that it
doesn’t really matter.
If you have multiple servers, the first place to put your RAM is in the database server. If
you can afford it, get enough RAM to get fit your entire database into memory. This shouldn’t
be too hard; we’ve developed a site with more than half a million newspaper articles, and it
took under 2GB of space.
Next, max out the RAM on your Web server. The ideal situation is one where neither server
ÃÜ>«ÃpiÛiÀ°ÊvÊÞÕÊ}iÌÊÌÊÌ>ÌÊ«Ì]ÊÞÕÊÃÕ`ÊLiÊ>LiÊÌ withstand most normal traffic.
Turn Off Keep-Alive
Gaal)=hera is aÊvi>ÌÕÀiÊvÊ//*ÊÌ>ÌÊ>ÜÃÊÕÌ«iÊ//*ÊÀiµÕiÃÌÃÊÌÊLiÊÃiÀÛi`ÊÛiÀÊ>ÊÃ}iÊ
/*ÊViVÌ]Ê>Û`}ÊÌiÊ/*ÊÃiÌÕ«ÉÌi>À`ÜÊÛiÀi>`°
This looks good at first glance, but it can kill the performance of a Django site. If you’re
«À«iÀÞÊÃiÀÛ}Êi`>ÊvÀÊ>ÊÃi«>À>ÌiÊÃiÀÛiÀ]Êi>VÊÕÃiÀÊLÀÜÃ}ÊÞÕÀÊÃÌiÊÜÊÞÊÀiµÕiÃÌÊ
>Ê«>}iÊvÀÊÞÕÀÊ>}ÊÃiÀÛiÀÊiÛiÀÞÊÌiÊÃiV`ÃÊÀÊÃ°Ê/ÃÊi>ÛiÃÊ//*ÊÃiÀÛiÀÃÊÜ>Ì}Ê
>ÀÕ`ÊvÀÊÌiÊiÝÌÊii«>ÛiÊÀiµÕiÃÌ]Ê>`Ê>Ê`iÊ//*ÊÃiÀÛiÀÊÕÃÌÊVÃÕiÃÊ,ÊÌ>ÌÊ>Ê
active one should be using.
Use Memcached
Although Django supports a number of different cache back-ends, none of them even come
close to being as fast as Memcached. If you have a high-traffic site, don’t even bother with the
ÌiÀÊL>Vi`Ãp}ÊÃÌÀ>}ÌÊÌÊiV>Vi`°
CHAPTER 12 N DEPLOYING DJANGO
234
Use Memcached Often
Of course, selecting Memcached does you no good if you don’t actually use it. Chapter 15 is
your best friend here: learn how to use Django’s cache framework, and use it everywhere pos-
sible. Aggressive, preemptive caching is usually the only thing that will keep a site up under
major traffic.
Join the Conversation
Each pieceÊvÊÌiÊ>}ÊÃÌ>VpvÀÊÕÝÊÌÊ«>ViÊÌÊ*ÃÌ}Ài-+ÊÀÊÞ-+p>ÃÊ>Ê>Üi-
ÃiÊVÕÌÞÊLi`ÊÌ°ÊvÊÞÕÊÀi>ÞÊÜ>ÌÊÌÊ}iÌÊÌ>ÌÊ>ÃÌÊ£¯ÊÕÌÊvÊÞÕÀÊÃiÀÛiÀÃ]ÊÊÌiÊ
open source communities behind your software and ask for help. Most free-software commu-
nity members will be happy to help.
And also be sure to join the Django community. Your humble authors are only two mem-
bers of an incredibly active, growing group of Django developers. Our community has a huge
amount of collective experience to offer.
What’s Next?
The remaining chapters focus on other Django features that you might or might not need,
depending on your application. Feel free to read them in any order you choose.
PART 3
Other Django Features
237
CHAPTER 13
Generating Non-HTML Content
Usually when we talk about developing Web sites, we’re talking about producing HTML. Of
course, there’s a lot more to the Web than HTML; we use the Web to distribute data in all sorts
of formats: RSS, PDFs, images, and so forth.
So far, we’ve focused on the common case of HTML production, but in this chapter we’ll
take a detour and look at using Django to produce other types of content.
Django has convenient built-in tools that you can use to produce some common non-
HTML content:
Ê UÊ ,--ÉÌÊÃÞ`V>ÌÊvii`Ã
Ê UÊ -Ìi>«ÃÊ>Ê8ÊvÀ>ÌÊÀ}>ÞÊ`iÛi«i`ÊLÞÊ}iÊÌ>ÌÊ}ÛiÃÊÌÃÊÌÊÃi>ÀVÊ
engines)
We’ll examine each of those tools a little later, but first we’ll cover the basic principles.
The Basics: Views and MIME Types
Recall from Chapter 3 that a view function is simply a Python function that takes a Web
request and returns a Web response. This response can be the HTML contents of a Web page,
ÀÊ>ÊÀi`ÀiVÌ]ÊÀÊ>Ê{ä{ÊiÀÀÀ]ÊÀÊ>Ê8Ê`VÕiÌ]ÊÀÊ>Ê>}iÊ°Ê°Ê°ÊÀÊ>ÞÌ}]ÊÀi>Þ°
More formally, a Django view function must
Ê UÊ VVi«ÌÊ>ÊDpplNamqaop instance as its first argument
Ê UÊ ,iÌÕÀÊ>ÊDpplNaolkjoa instance
The key to returning non-HTML content from a view lies in the DpplNaolkjoa class, spe-
cifically the ieiapula argument. By tweaking the MIME type, we can indicate to the browser
that we’ve returned a response of a different format.
ÀÊiÝ>«i]Êi̽ÃÊÊ>ÌÊ>ÊÛiÜÊÌ>ÌÊÀiÌÕÀÃÊ>Ê* Ê>}i°Ê/Êii«ÊÌ}ÃÊÃ«i]ÊÜi½Ê
just read the file off the disk:
bnki`f]jck*dppleilknpDpplNaolkjoa
`abiu[ei]ca$namqaop%6
ei]ca[`]p]9klaj$+l]pd+pk+iu+ei]ca*ljc(n^%*na]`$%
napqnjDpplNaolkjoa$ei]ca[`]p](ieiapula9ei]ca+ljc%
CHAPTER 13 N GENERATING NON-HTML CONTENT
238
That’s it! If you replace the image path in the klaj$% call with a path to a real image, you
can use this very simple view to serve an image, and the browser will display it correctly.
The other important thing to keep in mind is that DpplNaolkjoa objects implement
*ÞÌ½ÃÊÃÌ>`>À`ʺviiÊLiVÌ»Ê*. This means that you can use an DpplNaolkjoa instance
Ê>ÞÊ«>ViÊ*ÞÌÊÀÊ>ÊÌÀ`«>ÀÌÞÊLÀ>ÀÞ®ÊiÝ«iVÌÃÊ>Êvi°
For an example of how that works, let’s take a look at producing CSV with Django.
Producing CSV
CSV is a simple data format usually used by spreadsheet software. It’s basically a series of table
ÀÜÃ]ÊÜÌÊi>VÊViÊÊÌiÊÀÜÊÃi«>À>Ìi`ÊLÞÊ>ÊV>ÊCSV stands for comma-separated val-
ues). For example, here’s some data on “unruly” airline passengers in CSV format:
Ua]n(Qjnqhu=enhejaL]ooajcano
-551(-02
-552(-40
-553(./1
-554(.,,
-555(..2
.,,,(.1-
.,,-(.55
.,,.(.3/
.,,/(.4-
.,,0(/,0
.,,1(.,/
.,,2(-/0
.,,3(-03
NNote The preceding listing contains real numbers! They come from the US Federal Aviation Administration.
Though CSV looks simple, its formatting details haven’t been universally agreed upon.
Different pieces of software produce and consume different variants of CSV, making it a bit
tricky to use. Luckily, Python comes with a standard CSV library, _or, that is pretty much bul-
letproof.
Because the _or module operates on filelike objects, it’s a snap to use an DpplNaolkjoa
instead:
eilknp_or
bnki`f]jck*dppleilknpDpplNaolkjoa
Jqi^ankbqjnqhul]ooajcanoa]_dua]n-551).,,3*Ej]na]h]llhe_]pekj
pdeoskqh`hegahu_kiabnki]`]p]^]oaknokiakpdan^]_g)aj``]p]opkna*
QJNQHU[L=OOAJCANO9W-02(-40(./1(.,,(..2(.1-(.55(.3/(
.4-(/,0(.,/(-/0(-03Y
CHAPTER 13 N GENERATING NON-HTML CONTENT 239
`abqjnqhu[l]ooajcano[_or$namqaop%6
?na]papdaDpplNaolkjoak^fa_psepdpda]llnklne]pa?ORda]`an*
naolkjoa9DpplNaolkjoa$ieiapula9#patp+_or#%
naolkjoaW#?kjpajp)@eolkoepekj#Y9#]pp]_diajp7behaj]ia9qjnqhu*_or#
?na]papda?ORsnepanqoejcpdaDpplNaolkjoa]opdabeha*
snepan9_or*snepan$naolkjoa%
snepan*snepanks$W#Ua]n#(#Qjnqhu=enhejaL]ooajcano#Y%
bkn$ua]n(jqi%ejvel$n]jca$-551(.,,2%(QJNQHU[L=OOAJCANO%6
snepan*snepanks$Wua]n(jqiY%
napqnjnaolkjoa
The code and comments should be pretty clear, but a few things deserve special mention:
Ê UÊ /iÊÀiëÃiÊÃÊ}ÛiÊÌiÊpatp+_orÊÊÌÞ«iÊÃÌi>`ÊvÊÌiÊ`iv>ÕÌÊpatp+dpih). This
tells browsers that the document is a CSV file.
Ê UÊ /iÊÀiëÃiÊ}iÌÃÊ>Ê>``Ì>Ê?kjpajp)@eolkoepekj header, which contains the name
vÊÌiÊ-6Êvi°Ê/ÃÊi>`iÀÊÜi]ÊÌiʺ>ÌÌ>Vi̻ʫ>ÀÌ®ÊÜÊÃÌÀÕVÌÊÌiÊLÀÜÃiÀÊÌÊ
prompt for a location to save the file instead of just displaying it. This file name is arbi-
ÌÀ>ÀÞÆÊV>ÊÌÊÜ>ÌiÛiÀÊÞÕÊÜ>Ì°ÊÀÜÃiÀÃÊÜÊÕÃiÊÌÊÊÌiÊ->ÛiÊÃÊ`>}°
Ê UÊ /Ê>ÃÃ}Ê>Êi>`iÀÊÊ>ÊDpplNaolkjoa, just treat the DpplNaolkjoa as a dictionary and
ÃiÌÊ>ÊiÞÉÛ>Õi°
Ê UÊ }ÊÌÊÌiÊ-6}iiÀ>ÌÊ*ÊÃÊi>ÃÞ\ÊÕÃÌÊ«>ÃÃÊnaolkjoa as the first argument to
_or*snepan. The _or*snepan function expects a filelike object, and DpplNaolkjoa objects
fit the bill.
Ê UÊ ÀÊi>VÊÀÜÊÊÞÕÀÊ-6Êvi]ÊV>Êsnepan*snepanks, passing it an iterable object such as
a list or a tuple.
Ê UÊ /iÊ-6Ê`ÕiÊÌ>iÃÊV>ÀiÊvʵÕÌ}ÊvÀÊÞÕ]ÊÃÊÞÕÊ`½ÌÊ>ÛiÊÌÊÜÀÀÞÊ>LÕÌÊiÃV>«-
ing strings with quotes or commas in them. Just pass information to snepanks$%, and it
will do the right thing.
This is the general pattern you’ll use any time you need to return non-HTML content:
create an DpplNaolkjoa response objectÊÜÌÊ>ÊëiV>ÊÊÌÞ«i®]Ê«>ÃÃÊÌÊÌÊÃiÌ}Ê
expecting a file, and then return the response.
Let’s look at a few more examples.
Generating PDFs
*ÀÌ>LiÊVÕiÌÊÀ>ÌÊ*® isÊ>ÊvÀ>ÌÊ`iÛi«i`ÊLÞÊ`LiÊÌ>̽à used to represent
printable documents, complete with pixel-perfect formatting, embedded fonts, and 2D vector
graphics. You can think of a PDF document as the digital equivalent of a printed document;
indeed, PDFs are often used to distribute documents for printing.
You can easily generate PDFs with Python and Django thanks to the excellent open source
ReportLab libraryÊdppl6++sss*nalknph]^*knc+nh[pkkhgep*dpih). The advantage of generating
PDF files dynamically is that you can create customized PDFs for different purposes—say, for
different users or different pieces of content.
CHAPTER 13 N GENERATING NON-HTML CONTENT
240
For example, your humble authors used Django and ReportLab at KUsports.com to gener-
ate customized, printer-readyÊ ÊÌÕÀ>iÌÊLÀ>ViÌð
Installing ReportLab
Before you do any PDF generation, however, you’ll need to install ReportLab. It’s usually sim-
ple: just download and install the library from dppl6++sss*nalknph]^*knc+`ksjhk]`o*dpih.
NNote If you’re using a modern Linux distribution, you might want to check your package-management
utility before installing ReportLab. Most package repositories have added ReportLab. For example, if you’re
using Ubuntu, a simple ]lp)capejop]hhlupdkj)nalknph]^ will do the trick nicely.
/iÊÕÃiÀÊ}Õ`iÊ>ÌÕÀ>ÞÊ>Û>>LiÊÞÊ>ÃÊ>Ê*Êvi®Ê>ÌÊdppl6++sss*nalknph]^*knc+non_+
qoancqe`a*l`b has additional installation instructions.
Test your installation by importing it in the Python interactive interpreter:
:::eilknpnalknph]^
If that command doesn’t raise any errors, the installation worked.
Writing Your View
Like CSV, generatingÊ*ÃÊ`Þ>V>ÞÊÜÌÊ>}ÊÃÊi>ÃÞÊLiV>ÕÃiÊÌiÊ,i«ÀÌ>LÊ*Ê>VÌÃÊÊ
filelike objects.
Here’s a “Hello World” example:
bnkinalknph]^*l`bcajeilknp_]jr]o
bnki`f]jck*dppleilknpDpplNaolkjoa
`abdahhk[l`b$namqaop%6
?na]papdaDpplNaolkjoak^fa_psepdpda]llnklne]paL@Bda]`ano*
naolkjoa9DpplNaolkjoa$ieiapula9#]llhe_]pekj+l`b#%
naolkjoaW#?kjpajp)@eolkoepekj#Y9#]pp]_diajp7behaj]ia9dahhk*l`b#
?na]papdaL@Bk^fa_p(qoejcpdanaolkjoak^fa_p]oepobeha*
l9_]jr]o*?]jr]o$naolkjoa%
@n]spdejcokjpdaL@B*Dana#osdanapdaL@Bcajan]pekjd]llajo*
OaapdaNalknpH]^`k_qiajp]pekjbknpdabqhhheopkbbqj_pekj]hepu*
l*`n]sOpnejc$-,,(-,,(Dahhksknh`*%
?hkoapdaL@Bk^fa_p_ha]jhu(]j`sa#na`kja*
l*odksL]ca$%
l*o]ra$%
napqnjnaolkjoa
CHAPTER 13 N GENERATING NON-HTML CONTENT 241
ÊviÜÊÌiÃÊ>ÀiÊÊÀ`iÀ\
Ê UÊ iÀiÊÜiÊÕÃiÊÌiÊ]llhe_]pekj+l`b MIME type. This tells browsers that the document
is a PDF file, rather than an HTML file. If you leave off this information, browsers will
probably interpret the response as HTML, which will result in scary gobbledygook in
the browser window.
Ê UÊ }ÊÌÊÌiÊ,i«ÀÌ>LÊ* is easy: just pass naolkjoa as the first argument to
_]jr]o*?]jr]o. The ?]jr]o class expects a filelike object, and DpplNaolkjoa objects fit
the bill.
Ê UÊ ÊÃÕLÃiµÕiÌÊ*}iiÀ>ÌÊiÌ`ÃÊ>ÀiÊV>i`ÊÊÌiÊ*ÊLiVÌÊÊÌÃÊV>Ãi]Êl),
not on naolkjoa.
Ê UÊ >Þ]Ê̽ÃÊ«ÀÌ>Ì to call odksL]ca$% and o]ra$% on the PDF file—or else you’ll end
up with a corrupted PDF file.
Complex PDFs
If you’reÊVÀi>Ì}Ê>ÊV«iÝÊ*Ê`VÕiÌÊÀÊ>ÞÊ>À}iÊ`>Ì>ÊLL®]ÊVÃ`iÀÊÕÃ}ÊÌiÊ
_OpnejcEK library as a temporary holding place for your PDF file. The _OpnejcEK library pro-
vides a filelike object interface that is written in C for maximum efficiency.
Here’s the previous “Hello World” example rewritten to use _OpnejcEK:
bnki_OpnejcEKeilknpOpnejcEK
bnkinalknph]^*l`bcajeilknp_]jr]o
bnki`f]jck*dppleilknpDpplNaolkjoa
`abdahhk[l`b$namqaop%6
?na]papdaDpplNaolkjoak^fa_psepdpda]llnklne]paL@Bda]`ano*
naolkjoa9DpplNaolkjoa$ieiapula9#]llhe_]pekj+l`b#%
naolkjoaW#?kjpajp)@eolkoepekj#Y9#]pp]_diajp7behaj]ia9dahhk*l`b#
pail9OpnejcEK$%
?na]papdaL@Bk^fa_p(qoejcpdaOpnejcEKk^fa_p]oepobeha*
l9_]jr]o*?]jr]o$pail%
@n]spdejcokjpdaL@B*Dana#osdanapdaL@Bcajan]pekjd]llajo*
OaapdaNalknpH]^`k_qiajp]pekjbknpdabqhhheopkbbqj_pekj]hepu*
l*`n]sOpnejc$-,,(-,,(Dahhksknh`*%
?hkoapdaL@Bk^fa_p_ha]jhu*
l*odksL]ca$%
l*o]ra$%
Cappdar]hqakbpdaOpnejcEK^qbban]j`snepaeppkpdanaolkjoa*
naolkjoa*snepa$pail*capr]hqa$%%
napqnjnaolkjoa
CHAPTER 13 N GENERATING NON-HTML CONTENT
242
Other Possibilities
There’s a whole host of other types of content you can generate in Python. Here are a few more
ideas and some pointers to libraries you could use to implement them:
ÊUÊZIP files: Python’s standard library ships with the velbeha module, which can both read
and write compressed ZIP files. You could use it to provide on-demand archives of a
bunch of files, or perhaps compress large documents when requested. You could simi-
>ÀÞÊ«À`ÕViÊ/,ÊviÃÊÕÃ}ÊÌiÊÃÌ>`>À`ÊLÀ>ÀÞ½ÃÊp]nbeha module.
ÊUÊDynamic images\Ê/iÊ*ÞÌÊ>}}ÊLÀ>ÀÞÊ*ÆÊdppl6++sss*lupdkjs]na*_ki+
lnk`q_po+leh+) is a fantastic toolkit for producing images Ê* ]Ê*]Ê]Ê>`Ê>ÊÜiÊ
lot more). You could use it to automatically scale down images into thumbnails, com-
posite multiple images into a single frame, or even do Web-based image processing.
ÊUÊPlots and charts: There is a number of powerful Python plotting and charting libraries
you could use to produce on-demand maps, charts, plots, and graphs. We can’t possi-
bly list them all, so here are two of the highlights:
ÊUÊi]plhkphe^Êdppl6++i]plhkphe^*okqn_abknca*jap+) can be used to produce the type
of high-quality plots usually generated with MatLab or Mathematica.
ÊUÊlucn]ldrevÊdppl6++japskngt*h]jh*ckr+lucn]ldrev+®]Ê>ÊÌiÀv>ViÊÌÊÌiÊÀ>«ÛâÊ
}À>«Ê>ÞÕÌÊÌÌÊdppl6++cn]ldrev*knc+), can be used for generating structured
diagrams of graphs and networks.
In general, any Python library capable of writing to a file can be hooked into Django. The
possibilities are immense.
Now that we’ve looked at the basics of generating non-HTML content, let’s step up a level
of abstraction. Django ships with some pretty nifty built-in tools for generating some common
types of non-HTML content.
The Syndication-Feed Framework
Django comes with a high-level syndication-feed-generating framework that makes creating
,--Ê>`ÊÌÊvii`ÃÊi>ÃÞ°
WHAT'S RSS? WHAT'S ATOM?
RSS and Atom are both XML-based formats you can use to provide automatically updating “feeds” of your
site’s content. Read more about RSS at dppl6++sss*sd]peonoo*_ki+, and get information on Atom at
dppl6++sss*]pkiaj]^ha`*knc+.
To create any syndication feed, all you have to do is write a short Python class. You can
create as many feeds as you want.
CHAPTER 13 N GENERATING NON-HTML CONTENT 243
The high-level syndication-feed-generating framework is a view that’s hooked to +baa`o+
LÞÊVÛiÌ°Ê>}ÊÕÃiÃÊÌiÊÀi>`iÀÊvÊÌiÊ1,ÊiÛiÀÞÌ}Ê>vÌiÀÊ+baa`o+) to determine
which feed to return.
To create a feed, you’ll write a Baa` class and point to it in your URLconf.
Initialization
To activate syndication feeds on your Django site, add this URLconf:
$n#Zbaa`o+$;L8qnh:*&%+ #(#`f]jck*_kjpne^*ouj`e_]pekj*reaso*baa`#(
w#baa`[`e_p#6baa`oy
%(
This line tells Django to use the RSS framework to handle all URLs starting with baa`o+.
9ÕÊV>ÊV>}iÊÌ>ÌÊbaa`o+prefix to fit your own needs.)
This URLconf line has an extra argument: w#baa`[`e_p#6baa`oy. Use this extra argument
to pass the syndication framework the feeds that should be published under that URL.
Specifically, baa`[`e_pÊÃÕ`ÊLiÊ>Ê`VÌ>ÀÞÊÌ>ÌÊ>«ÃÊ>Êvii`½ÃÊÃÕ}ÊÃÀÌÊ1,Ê>Li®ÊÌÊÌÃÊ
Baa` class. You can define the baa`[`e_p in the URLconf itself. Here’s a full example URLconf:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnkiiuoepa*baa`oeilknpH]paopAjpneao(H]paopAjpneao>u?]packnu
baa`o9w
#h]paop#6H]paopAjpneao(
#_]packneao#6H]paopAjpneao>u?]packnu(
y
qnhl]ppanjo9l]ppanjo$##(
***
$n#Zbaa`o+$;L8qnh:*&%+ #(#`f]jck*_kjpne^*ouj`e_]pekj*reaso*baa`#(
w#baa`[`e_p#6baa`oy%(
***
%
The preceding example registers two feeds:
Ê UÊ /iÊvii`ÊÀi«ÀiÃiÌi`ÊLÞÊH]paopAjpneao will live at baa`o+h]paop+.
Ê UÊ /iÊvii`ÊÀi«ÀiÃiÌi`ÊLÞÊH]paopAjpneao>u?]packnu will live at baa`o+_]packneao+.
Once that’s set up, you’ll need to define the Baa` classes themselves.
ÊBaa` classÊÃÊ>ÊÃ«iÊ*ÞÌÊV>ÃÃÊÌ>ÌÊÀi«ÀiÃiÌÃÊ>ÊÃÞ`V>ÌÊvii`°ÊÊvii`ÊV>ÊLiÊÃ-
«iÊi°}°]Ê>ʺÃÌiÊiÜûÊvii`]ÊÜVÊÃÊ>ÊL>ÃVÊvii`Ê`ë>Þ}ÊÌiÊ>ÌiÃÌÊiÌÀiÃÊvÊ>ÊL}®ÊÀÊÀiÊ
V«iÝÊi°}°]Ê>Êvii`Ê`ë>Þ}Ê>ÊÌiÊL}ÊiÌÀiÃÊÊ>Ê«>ÀÌVÕ>ÀÊV>Ìi}ÀÞ]ÊÜiÀiÊÌiÊV>Ìi}ÀÞÊ
is variable).
Baa` classes must subclass `f]jck*_kjpne^*ouj`e_]pekj*baa`o*Baa`. They can live any-
where in your code tree.
CHAPTER 13 N GENERATING NON-HTML CONTENT
244
A Simple Feed
This simple example describes a feed of the latest five blog entries for a given blog:
bnki`f]jck*_kjpne^*ouj`e_]pekj*baa`oeilknpBaa`
bnkiiuoepa*^hkc*ik`ahoeilknpAjpnu
_h]ooH]paopAjpneao$Baa`%6
pepha9Iu>hkc
hejg9+]n_dera+
`ao_nelpekj9Pdah]paopjaso]^kqpopqbb*
`abepaio$oahb%6
napqnjAjpnu*k^fa_po*kn`an[^u$#)lq^[`]pa#%W61Y
The important things to notice here are as follows:
Ê UÊ /iÊV>ÃÃÊÃÕLV>ÃÃiÃÊ`f]jck*_kjpne^*ouj`e_]pekj*baa`o*Baa`.
ÊUÊpepha, hejg, and `ao_nelpekj correspond to the standard RSS 8pepha:, 8hejg:, and
8`ao_nelpekj: elements, respectively.
ÊUÊepaio$% is simply a method that returns a list of objects that should be included in the
feed as 8epai:ÊiiiÌðÊÌÕ}ÊÌÃÊiÝ>«iÊÀiÌÕÀÃÊAjpnu objects using Django’s
`>Ì>L>ÃiÊ*]Êepaio$% doesn’t have to return model instances.
There’s just one more step. In an RSS feed, each 8epai: has a 8pepha:, 8hejg:, and
8`ao_nelpekj:. We need to tell the framework what data to put into those elements.
Ê UÊ /ÊëiVvÞÊÌiÊVÌiÌÃÊvÊ8pepha: and 8`ao_nelpekj:, create Django templates called
baa`o+h]paop[pepha*dpih and baa`o+h]paop[`ao_nelpekj*dpih, where h]paop is the
ohqc specified in the URLconf for the given feed. Note that the *dpih extension is
required.
The RSS system renders that template for each item, passing it two template context
variables:
ÊUÊk^f\Ê/iÊVÕÀÀiÌÊLiVÌÊiÊvÊÜViÛiÀÊLiVÌÃÊÞÕÊÀiÌÕÀi`ÊÊepaio$%).
ÊUÊoepa\ÊÊ`f]jck*ik`aho*_kna*oepao*Oepa object representing the current site. This is
useful for wwoepa*`ki]ejyy or wwoepa*j]iayy.
If you don’t create a template for either the title or description, the framework will use
the template wwk^fyy by default—that is, the normal string representation of the
LiVÌ°ÊÀÊ`iÊLiVÌÃ]ÊÌÃÊÜÊLiÊÌiÊ[[qje_k`a[[$% method.)
You can also change the names of these two templates by specifying pepha[pailh]pa
and `ao_nelpekj[pailh]pa as attributes of your Baa` class.
CHAPTER 13 N GENERATING NON-HTML CONTENT 245
Ê UÊ /ÊëiVvÞÊÌiÊVÌiÌÃÊvÊ8hejg:, you have two options. For each item in epaio$%,
Django first tries executing a cap[]^okhqpa[qnh$% method on that object. If that method
doesn’t exist, it tries calling a method epai[hejg$% in the Baa` class, passing it a single
parameter, epai, which is the object itself.
Both cap[]^okhqpa[qnh$% and epai[hejg$% should return the item’s URL as a normal
Python string.
Ê UÊ ÀÊÌiÊ«ÀiÛÕÃÊH]paopAjpneao example, we could have very simple feed templates.
h]paop[pepha*dpih contains
wwk^f*pephayy
and h]paop[`ao_nelpekj*dpih contains
wwk^f*`ao_nelpekjyy
It’s almost too easy. . . .
A More Complex Feed
The framework also supports more-complex feeds, via parameters.
For example, say your blog offers an RSS feed for every distinct “tag” you’ve used to catego-
rize your entries. It would be silly to create a separate Baa` class for each tag; that would violate
ÌiÊ½ÌÊ,i«i>ÌÊ9ÕÀÃivÊ,9®Ê«ÀV«i and would couple data to programming logic.
Instead, the syndication framework lets you make generic feeds that return items based
on information in the feed’s URL.
Your tag-specific feeds could use URLs like this:
ÊUÊdppl6++at]ilha*_ki+baa`o+p]co+lupdkj+: Returns recent entries tagged with “python”
ÊUÊdppl6++at]ilha*_ki+baa`o+p]co+_]po+: Returns recent entries tagged with “cats”
The slug here is p]co. The syndication framework sees the extra URL bits after the slug—
lupdkj and _]po and gives you a hook to tell it what those URL bits mean and how they should
influence which items get published in the feed.
ÊiÝ>«iÊ>iÃÊÌÃÊVi>À°ÊiÀi½ÃÊÌiÊV`iÊvÀÊÌiÃiÊÌ>}ëiVvVÊvii`Ã\
bnki`f]jck*_kna*at_alpekjoeilknpK^fa_p@kaoJkpAteop
bnkiiuoepa*^hkc*ik`ahoeilknpAjpnu(P]c
_h]ooP]cBaa`$Baa`%6
`abcap[k^fa_p$oahb(^epo%6
Ej_]oakb+baa`o+p]co+_]po+`kco+ie_a+(knkpdanoq_d
_hqppan(_da_gpd]p^epod]okjhukjaiai^an*
ebhaj$^epo%9-6
n]eoaK^fa_p@kaoJkpAteop
napqnjP]c*k^fa_po*cap$p]c9^epoW,Y%
CHAPTER 13 N GENERATING NON-HTML CONTENT
246
`abpepha$oahb(k^f%6
napqnjIu>hkc6Ajpneaop]cca`sepd!o!k^f*p]c
`abhejg$oahb(k^f%6
napqnjk^f*cap[]^okhqpa[qnh$%
`ab`ao_nelpekj$oahb(k^f%6
napqnjAjpneaop]cca`sepd!o!k^f*p]c
`abepaio$oahb(k^f%6
ajpneao9Ajpnu*k^fa_po*behpan$p]co[[e`[[at]_p9k^f*e`%
napqnjajpneao*kn`an[^u$#)lq^[`]pa#%W6/,Y
Here’s the basic algorithm of the RSS framework, given this class and a request to the URL
+baa`o+p]co+lupdkj+:
1. The framework gets the URL +baa`o+p]co+lupdkj+ and notices there’s an extra bit of
1,Ê>vÌiÀÊÌiÊÃÕ}°ÊÌÊëÌÃÊÌ>ÌÊÀi>}ÊÃÌÀ}ÊLÞÊÌiÊÃ>ÃÊV>À>VÌiÀÊ+) and calls the
Baa` class’s cap[k^fa_p$% method, passing it the bits.
In this case, bits is WlupdkjY. For a request to +baa`o+p]co+lupdkj+`f]jck+, bits would
be W#lupdkj#(#`f]jck#Y.
2. cap[k^fa_p$% is responsible for retrieving the given P]c object, from the given ^epo.
ÊÌÃÊV>Ãi]ÊÌÊÕÃiÃÊÌiÊ>}Ê`>Ì>L>ÃiÊ*ÊÌÊÀiÌÀiÛiÊÌiÊP]c. Note that cap[k^fa_p$%
should raise `f]jck*_kna*at_alpekjo*K^fa_p@kaoJkpAteop if given invalid parameters.
There’s no pnuÉat_alp around the P]c*k^fa_po*cap$% call, because it’s not necessary.
That function raises P]c*@kaoJkpAteop on failure, and P]c*@kaoJkpAteop is a subclass of
K^fa_p@kaoJkpAteop. Raising K^fa_p@kaoJkpAteop in cap[k^fa_p$% tells Django to pro-
duce a 404 error for that request.
3. To generate the feed’s 8pepha:, 8hejg:, and 8`ao_nelpekj:, Django uses the pepha$%,
hejg$%, and `ao_nelpekj$% methods. In the previous example, they were simple string
class attributes, but this example illustrates that they can be either strings or methods.
For each of pepha, hejg, and `ao_nelpekj, Django follows this algorithm:
a. It tries to call a method, passing the k^f argument, where k^f is the object returned
by cap[k^fa_p$%.
b. Failing that, it tries to call a method with no arguments.
c. Failing that, it uses the class attribute.
4. Finally, note that epaio$% in this example also takes the k^f argument. The algorithm
for epaio is the same as described in the previous step—first, it tries epaio$k^f%, then
epaio$%, and then finally an epaioÊV>ÃÃÊ>ÌÌÀLÕÌiÊÜVÊÃÕ`ÊLiÊ>ÊÃÌ®°
Full documentation of all the methods and attributes of the Baa` classes is always avail-
able from theÊvvV>Ê>}Ê`VÕiÌ>ÌÊdppl6++`k_o*`f]jcklnkfa_p*_ki+aj+`ar+nab+
_kjpne^+ouj`e_]pekj+).
CHAPTER 13 N GENERATING NON-HTML CONTENT 247
Specifying the Type of Feed
By default, the syndication framework produces RSS 2.0. To change that, add a baa`[pula attri-
bute to your Baa` class:
bnki`f]jck*qpeho*baa`cajan]pkneilknp=pki-Baa`
_h]ooIuBaa`$Baa`%6
baa`[pula9=pki-Baa`
Note that you set baa`[pula to a class object, not an instance. Currently available feed
types are shown in Table 13-1.
Table 13-1. Feed Types
Feed Class Format
`f]jck*qpeho*baa`cajan]pkn*Noo.,-nar.Baa` ,--ÊÓ°ä£Ê`iv>ÕÌ®
`f]jck*qpeho*baa`cajan]pkn*NooQoanh]j`,5-Baa` RSS 0.91
`f]jck*qpeho*baa`cajan]pkn*=pki-Baa` ÌÊ£°ä
Enclosures
To specifyÊiVÃÕÀiÃÊ°i°]Êi`>ÊÀiÃÕÀViÃÊ>ÃÃV>Ìi`ÊÜÌÊ>Êvii`ÊÌiÊÃÕVÊ>ÃÊ*ÎÊ«`V>ÃÌÊ
feeds), use the epai[aj_hkoqna[qnh, epai[aj_hkoqna[hajcpd, and epai[aj_hkoqna[ieia[pula
hooks, as in this example:
bnkiiulnkfa_p*ik`ahoeilknpOkjc
_h]ooIuBaa`SepdAj_hkoqnao$Baa`%6
pepha9At]ilhabaa`sepdaj_hkoqnao
hejg9+baa`o+at]ilha)sepd)aj_hkoqnao+
`abepaio$oahb%6
napqnjOkjc*k^fa_po*]hh$%W6/,Y
`abepai[aj_hkoqna[qnh$oahb(epai%6
napqnjepai*okjc[qnh
`abepai[aj_hkoqna[hajcpd$oahb(epai%6
napqnjepai*okjc[hajcpd
epai[aj_hkoqna[ieia[pula9]q`ek+ilac
This assumes, of course, that you’ve created a Okjc object with okjc[qnh and okjc[hajcpd
°i°]ÊÌi size in bytes) fields.
CHAPTER 13 N GENERATING NON-HTML CONTENT
248
Language
Feeds created by the syndication framework automatically include the appropriate 8h]jcq]ca:
Ì>}Ê,--ÊÓ°ä®ÊÀÊtih6h]jc attributeÊÌ®°Ê/ÃÊViÃÊ`ÀiVÌÞ from your H=JCQ=CA[?K@A
setting.
URLs
The hejgÊiÌ`É>ÌÌÀLÕÌiÊV>ÊÀiÌÕÀÊiÌiÀÊ>Ê>LÃÕÌiÊ1,Êi°}°]Ê+^hkc+) or a URL with
ÌiÊvÕÞʵÕ>vi`Ê`>Ê>`Ê«ÀÌVÊi°}°]Êdppl6++sss*at]ilha*_ki+^hkc+). If hejg
doesn’t return the domain, the syndication framework will insert the domain of the current
site, according to your OEPA[E@ÊÃiÌÌ}°Ê-iiÊ>«ÌiÀÊ£ÈÊvÀÊÀiÊÊOEPA[E@ and the sites
framework.)
ÌÊvii`ÃÊÀiµÕÀiÊ>Ê8hejgnah9oahb: that defines the feed’s current location. The syn-
dication framework populates this automatically.
Publishing Atom and RSS Feeds in Tandem
Some developersÊiÊÌÊ>iÊ>Û>>LiÊLÌÊÌÊand RSS versions of their feeds. That’s easy
to do with Django: just create a subclass of your Baa` class and set the baa`[pula to something
different. Then update your URLconf to add the extra versions. Here’s a full example:
bnki`f]jck*_kjpne^*ouj`e_]pekj*baa`oeilknpBaa`
bnki`f]jck*qpeho*baa`cajan]pkneilknp=pki-Baa`
bnkiiuoepa*^hkc*ik`ahoeilknpAjpnu
_h]ooNooH]paopAjpneao$Baa`%6
pepha9Iu>hkc
hejg9+]n_dera+
`ao_nelpekj9Pdah]paopjaso]^kqpopqbb*
`abepaio$oahb%6
napqnjAjpnu*k^fa_po*kn`an[^u$#)lq^[`]pa#%W61Y
_h]oo=pkiH]paopAjpneao$NooH]paopAjpneao%6
baa`[pula9=pki-Baa`
`ÊiÀi½ÃÊÌi accompanying URLconf:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnkiiulnkfa_p*baa`oeilknpNooH]paopAjpneao(=pkiH]paopAjpneao
baa`o9w
#noo#6NooH]paopAjpneao(
#]pki#6=pkiH]paopAjpneao(
y
CHAPTER 13 N GENERATING NON-HTML CONTENT 249
qnhl]ppanjo9l]ppanjo$##(
***
$n#Zbaa`o+$;L8qnh:*&%+ #(#`f]jck*_kjpne^*ouj`e_]pekj**reaso*baa`#(
w#baa`[`e_p#6baa`oy%(
***
%
The Sitemap Framework
Êsitemap isÊ>Ê8ÊviÊÊÞÕÀÊ7iLÊÃÌiÊÌ>ÌÊÌiÃÊÃi>ÀVi}iÊ`iÝiÀÃ how frequently
your pages change and how “important” certain pages are in relation to other pages on your
site. This information helps search engines index your site.
ÀÊiÝ>«i]ÊiÀi½ÃÊ>Ê«iViÊvÊÌiÊÃÌi>«ÊvÀÊ>}½ÃÊ7iLÊÃÌiÊdppl6++sss*`f]jcklnkfa_p*
_ki+oepai]l*tih):
8;tihranoekj9-*,aj_k`ejc9QPB)4;:
8qnhoaptihjo9dppl6++sss*oepai]lo*knc+o_dai]o+oepai]l+,*5:
8qnh:
8hk_:dppl6++sss*`f]jcklnkfa_p*_ki+`k_qiajp]pekj+8+hk_:
8_d]jcabnam:saaghu8+_d]jcabnam:
8lneknepu:,*18+lneknepu:
8+qnh:
8qnh:
8hk_:dppl6++sss*`f]jcklnkfa_p*_ki+`k_qiajp]pekj+,[5,+8+hk_:
8_d]jcabnam:jaran8+_d]jcabnam:
8lneknepu:,*-8+lneknepu:
8+qnh:
***
8+qnhoap:
For more on sitemaps, see dppl6++sss*oepai]lo*knc+.
/iÊ>}ÊÃÌi>«ÊvÀ>iÜÀÊ>ÕÌ>ÌiÃÊÌiÊVÀi>ÌÊvÊÌÃÊ8ÊviÊLÞÊiÌÌ}ÊÞÕÊ
express this information in Python code. To create a sitemap, you just need to write a Oepai]l
class and point to it in your URLconf.
Installation
To install the sitemap application, follow these steps:
1. ``Ê#`f]jck*_kjpne^*oepai]lo# to your EJOP=HHA@[=LLO setting.
2. Make sure #`f]jck*pailh]pa*hk]`ano*]ll[`ena_pkneao*hk]`[pailh]pa[okqn_a# is in
your PAILH=PA[HK=@ANO setting. It’s in there by default, so you’ll need to change this
only if you’ve changed that setting.
3. Make sure you’ve installed theÊÃÌiÃÊvÀ>iÜÀÊÃiiÊ>«ÌiÀʣȮ°
CHAPTER 13 N GENERATING NON-HTML CONTENT
250
NNote The sitemap application doesn’t install any database tables. The only reason it needs to go into
EJOP=HHA@[=LLO is so the hk]`[pailh]pa[okqn_a template loader can find the default templates.
Initialization
To activate sitemap generation on your Django site, add this line to your URLconf:
$n#Zoepai]lX*tih #(#`f]jck*_kjpne^*oepai]lo*reaso*oepai]l#(w#oepai]lo#6oepai]loy%
This line tells Django to build a sitemap when a client accesses +oepai]l*tih°Ê ÌiÊÌ>ÌÊ
the dot character in oepai]l*tih is escaped with a backslash because dots have a special
meaning in regular expressions.)
The name of the sitemap file is not important, but the location is. Search engines will
index links in your sitemap for only the current URL level and below. For instance, if oepai]l*
tih lives in your root directory, it may reference any URL in your site. However, if your sitemap
lives at +_kjpajp+oepai]l*tih, it may only reference URLs that begin with +_kjpajp+.
The sitemap view takes an extra, required argument: w#oepai]lo#6oepai]loy. oepai]lo
ÃÕ`ÊLiÊ>Ê`VÌ>ÀÞÊÌ>ÌÊ>«ÃÊ>ÊÃÀÌÊÃiVÌÊ>LiÊi°}°]Ê^hkc or jaso) to its Oepai]l class
i°}°]Ê>hkcOepai]l or JasoOepai]l). It may also map to an instance of a Oepai]lÊV>ÃÃÊi°}°]Ê
>hkcOepai]l$okia[r]n%).
Sitemap Classes
ÊOepai]l class is a simple Python class that represents a “section” of entries in your sitemap.
For example, one Oepai]l class could represent all the entries of your weblog, while another
could represent all of the events in your events calendar.
In the simplest case, all these sections get lumped together into one oepai]l*tih, but
it’s also possible to use the framework to generate a sitemap index that references individual
ÃÌi>«ÊviÃ]ÊiÊ«iÀÊÃiVÌÊ>ÃÊ`iÃVÀLi`ÊÃÀÌÞ®°
Oepai]l classes must subclass `f]jck*_kjpne^*oepai]lo*Oepai]l. They can live anywhere
in your code tree. For example, let’s assume you have a blog system, with an Ajpnu model, and
you want your sitemap to include all the links to your individual blog entries. Here’s how your
Oepai]l class might look:
bnki`f]jck*_kjpne^*oepai]loeilknpOepai]l
bnkiiuoepa*^hkc*ik`ahoeilknpAjpnu
_h]oo>hkcOepai]l$Oepai]l%6
_d]jcabnam9jaran
lneknepu9,*1
`abepaio$oahb%6
napqnjAjpnu*k^fa_po*behpan$eo[`n]bp9B]hoa%
`abh]opik`$oahb(k^f%6
napqnjk^f*lq^[`]pa
CHAPTER 13 N GENERATING NON-HTML CONTENT 251
Declaring a Oepai]l should look very similar to declaring a Baa`. That’s by design.
Like Baa` classes, Oepai]l members can be either methods or attributes. See the steps in
ÌiÊi>ÀiÀʺÊÀiÊ«iÝÊii`»ÊÃiVÌÊvÀÊÀiÊ>LÕÌÊÜÊÌÃÊÜÀð
ÊOepai]lÊV>ÃÃÊV>Ê`iviÊÌiÊvÜ}ÊiÌ`ÃÉ>ÌÌÀLÕÌiÃ\
ÊUÊepaio (required): Provides a list of objects. The framework doesn’t care what type of
objects they are; all that matters is that these objects get passed to the hk_]pekj$%,
h]opik`$%, _d]jcabnam$%, and lneknepu$% methods.
ÊUÊhk_]pekj (optional)\ÊÛiÃÊÌiÊ>LÃÕÌiÊ1,ÊvÀÊ>Ê}ÛiÊLiVÌ°ÊiÀi]ʺ>LÃÕÌiÊ1,»Ê
means a URL that doesn’t include the protocol or domain. Here are some examples:
ÊUÊGood: #+bkk+^]n+#
ÊUÊBad: #at]ilha*_ki+bkk+^]n+#
ÊUÊBad: #dppl6++at]ilha*_ki+bkk+^]n+#
If hk_]pekj isn’t provided, the framework will call the cap[]^okhqpa[qnh$% method on
each object as returned by epaio$%.
ÊUÊh]opik` (optional): The object’s “last modification” date, as a Python `]papeia object.
ÊUÊ_d]jcabnam (optional)\ÊÜÊvÌiÊÌiÊLiVÌÊV>}iðÊ*ÃÃLiÊÛ>ÕiÃÊ>ÃÊ}ÛiÊLÞÊÌiÊ
Sitemaps specification) are as follows:
ÊUÊ#]hs]uo#
ÊUÊ#dkqnhu#
ÊUÊ#`]ehu#
ÊUÊ#saaghu#
ÊUÊ#ikjpdhu#
ÊUÊ#ua]nhu#
ÊUÊ#jaran#
ÊUÊlneknepu (optional)\ÊÊÃÕ}}iÃÌi`Ê`iÝ} priority between ,*, and -*,. The default
priority of a page is ,*1; see the dppl6++sss*oepai]lo*knc+ documentation for more
about how lneknepu works.
Shortcuts
The sitemap framework provides a couple of convenience classes for common cases. These
are described in the sections that follow.
FlatPageSitemap
The `f]jck*_kjpne^*oepai]lo*Bh]pL]caOepai]l class looks at all flatpages defined for the
current site and creates an entry in the sitemap. These entries include only the hk_]pekj attri-
bute—not h]opik`, _d]jcabnam, or lneknepu.
-iiÊ>«ÌiÀÊ£ÈÊvÀÊÀi about flatpages.
CHAPTER 13 N GENERATING NON-HTML CONTENT
252
GenericSitemap
The Cajane_Oepai]l classÊÜÀÃÊÜÌÊ>ÞÊ}iiÀVÊÛiÜÃÊÃiiÊ>«ÌiÀÊ££®ÊÞÕÊ>Ài>`ÞÊ>Ûi°
To use it, create an instance, passing in the same ejbk[`e_p you pass to the generic views.
The only requirement is that the dictionary have a mqanuoap entry. It may also have a `]pa[
beah` entry that specifies a date field for objects retrieved from the mqanuoap. This will be used
for the h]opik` attribute in the generated sitemap. You may also pass lneknepu and _d]jcabnam
keyword arguments to the Cajane_Oepai]l constructor to specify these attributes for all URLs.
Here’s an example of a URLconf using both Bh]pL]caOepai]l and Cajane_OepaI]lÊÜÌÊ
the hypothetical Ajpnu object from earlier):
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnki`f]jck*_kjpne^*oepai]loeilknpBh]pL]caOepai]l(Cajane_Oepai]l
bnkiiuoepa*^hkc*ik`ahoeilknpAjpnu
ejbk[`e_p9w
#mqanuoap#6Ajpnu*k^fa_po*]hh$%(
#`]pa[beah`#6#lq^[`]pa#(
y
oepai]lo9w
#bh]pl]cao#6Bh]pL]caOepai]l(
#^hkc#6Cajane_Oepai]l$ejbk[`e_p(lneknepu9,*2%(
y
qnhl]ppanjo9l]ppanjo$##(
okiacajane_reasqoejcejbk[`e_p
***
pdaoepai]l
$n#Zoepai]lX*tih #(
#`f]jck*_kjpne^*oepai]lo*reaso*oepai]l#(
w#oepai]lo#6oepai]loy%
%
Creating a Sitemap Index
The sitemap framework also has the ability to create a sitemap index that references individual
sitemap files, one per section defined in your oepai]lo dictionary. The only differences in
usage are as follows:
Ê UÊ 9ÕÊÕÃiÊÌÜÊÛiÜÃÊÊÞÕÀÊ1,Vv\Ê`f]jck*_kjpne^*oepai]lo*reaso*ej`at and
`f]jck*_kjpne^*oepai]lo*reaso*oepai]l.
Ê UÊ /iÊ`f]jck*_kjpne^*oepai]lo*reaso*oepai]l view should take a oa_pekj keyword
argument.
CHAPTER 13 N GENERATING NON-HTML CONTENT 253
Here is what the relevant URLconf lines would look like for the previous example:
$n#Zoepai]l*tih #(
#`f]jck*_kjpne^*oepai]lo*reaso*ej`at#(
w#oepai]lo#6oepai]loy%(
$n#Zoepai]l)$;L8oa_pekj:*'%*tih #(
#`f]jck*_kjpne^*oepai]lo*reaso*oepai]l#(
w#oepai]lo#6oepai]loy%
This will automatically generate a oepai]l*tih file that references both oepai]l)bh]pl]cao*
tih and oepai]l)^hkc*tih. The Oepai]l classes and the oepai]lo dictionary don’t change at all.
Pinging Google
You mayÊÜ>ÌÊÌʺ«}»Ê}iÊÜiÊÞÕÀÊÃÌi>«ÊV>}iÃ]ÊÌÊiÌÊÌÊÜÊÌÊÀi`iÝÊÞÕÀÊÃÌi°Ê
The framework provides a function to do just that: `f]jck*_kjpne^*oepai]lo*lejc[ckkcha$%.
lejc[ckkcha$% takes an optional argument, oepai]l[qnh, which should be the absolute
1,ÊvÊÞÕÀÊÃÌi½ÃÊÃÌi>«Êi°}°]Ê#+oepai]l*tih#). If this argument isn’t provided, lejc[
ckkcha$% will attempt to figure out your sitemap by performing a reverse lookup on your
URLconf.
lejc[ckkcha$% raises the exception `f]jck*_kjpne^*oepai]lo*Oepai]lJkpBkqj` if it cannot
determine your sitemap URL.
One useful way to call lejc[ckkcha$% is from a model’s o]ra$% method:
bnki`f]jck*_kjpne^*oepai]loeilknplejc[ckkcha
_h]ooAjpnu$ik`aho*Ik`ah%6
***
`abo]ra$oahb(&]nco(&&gs]nco%6
oqlan$Ajpnu(oahb%*o]ra$&]nco(&&gs]nco%
pnu6
lejc[ckkcha$%
at_alpAt_alpekj6
>]na#at_alp#^a_]qoasa_kqh`cap]r]neapu
kbDPPL)nah]pa`at_alpekjo*
l]oo
ÊÀiÊivvViÌÊÃÕÌ]ÊÜiÛiÀ]ÊÜÕ`ÊLiÊÌÊV>Êlejc[ckkcha$% from a _nkj script or
ÃiÊÌiÀÊÃVi`Õi`ÊÌ>Ã°Ê/iÊvÕVÌÊ>iÃÊ>Ê//*ÊÀiµÕiÃÌÊÌÊ}i½ÃÊÃiÀÛiÀÃ]ÊÃÊÞÕÊ
may not want to introduce that network overhead each time you call o]ra$%.
Finally, if #`f]jck*_kjpne^*oepai]lo# is in your EJOP=HHA@[=LLO, then your i]j]ca*lu will
include a new command, lejc[ckkcha. This is useful for command-line access to pinging.
Here’s an example:
lupdkji]j]ca*lulejc[ckkcha+oepai]l*tih
CHAPTER 13 N GENERATING NON-HTML CONTENT
254
What's Next?
Next we’ll continue to dig deeper into Django’s built-in tools. Chapter 14 looks at all the tools
you need to provide user-customized sites: sessions, users, and authentication.
CHAPTER 14
Sessions, Users,
and Registration
It’s time for a confession: we’ve been deliberately ignoring an important aspect of Web
development prior to this point. So far, we’ve thought of the traffic visiting our sites as some
faceless, anonymous mass hurtling itself against our carefully designed pages.
This isn’t true, of course. The browsers hitting our sites have real humans behind them
(most of the time, at least). That’s a big thing to ignore: the Internet is at its best when it serves
to connect people, not machines. If we’re going to develop truly compelling sites, eventually
we’re going to have to deal with the bodies behind the browsers.
Unfortunately, it’s not all that easy. HTTP is designed to be stateless—that is, each and
every request happens in a vacuum. There’s no persistence between one request and the next,
and we can’t count on any aspects of a request (IP address, user agent, etc.) to consistently
indicate successive requests from the same person.
In this chapter you’ll learn how to handle this lack of state. We’ll start at the lowest level
(cookies), and work up to the high-level tools for handling sessions, users, and registration.
Cookies
Browser developers long ago recognized that HTTP’s statelessness poses a huge problem for
Web developers, and thus cookies were born. A cookie is a small piece of information that
browsers store on behalf of Web servers. Every time a browser requests a page from a certain
server, it gives back the cookie that it initially received.
Let’s take a look at how this might work. When you open your browser and type in ckkcha*
_ki, your browser sends an HTTP request to Google that starts something like this:
CAP+DPPL+-*-
Dkop6ckkcha*_ki
***
255
CHAPTER 14 N SESSIONS, USERS, AND REGISTRATION
256
When Google replies, the HTTP response looks something like the following:
DPPL+-*-.,,KG
?kjpajp)Pula6patp+dpih
Oap)?kkgea6LNAB9E@91^-0b..^`]b-a4-_6PI9--23,,,23-6HI9--23,,,23-7
atlenao9Oqj(-3)F]j).,/4-56-06,3CIP7
l]pd9+7`ki]ej9*ckkcha*_ki
Oanran6CSO+.*-
***
Notice the Oap)?kkgea header. Your browser will store that cookie value (LNAB9E@9
1^-0b..^`]b-a4-_6PI9--23,,,23-6HI9--23,,,23-) and serve it back to Google every time you
access the site. So the next time you access Google, your browser is going to send a request
like this:
CAP+DPPL+-*-
Dkop6ckkcha*_ki
?kkgea6LNAB9E@91^-0b..^`]b-a4-_6PI9--23,,,23-6HI9--23,,,23-
***
Google then can use that ?kkgea value to know that you’re the same person who accessed
the site earlier. This value might, for example, be a key into a database that stores user infor-
mation. Google could (and does) use it to display your account’s username on the page.
Getting and Setting Cookies
When dealing with persistence in Django, most of the time you’ll want to use the higher-level
session and/or user frameworks discussed a little later in this chapter. However, first look at
how to read and write cookies at a low level. This should help you understand how the rest of
the tools discussed in the chapter actually work, and it will come in handy if you ever need to
play with cookies directly.
Reading cookies that are already set is simple. Every DpplNamqaop object has a ?KKGEAO
object that acts like a dictionary; you can use it to read any cookies that the browser has sent
to the view:
`abodks[_khkn$namqaop%6
ebb]rknepa[_khknejnamqaop*?KKGEAO6
napqnjDpplNaolkjoa$Ukqnb]rknepa_khkneo!o!X
namqaop*?KKGEAOWb]rknepa[_khknY%
ahoa6
napqnjDpplNaolkjoa$Ukq`kj#pd]ra]b]rknepa_khkn*%
Writing cookies is slightly more complicated. You need to use the oap[_kkgea$% method
on an DpplNaolkjoa object. Here’s an example that sets the b]rknepa[_khkn cookie based on a
CAP parameter:
CHAPTER 14 N SESSIONS, USERS, AND REGISTRATION 257
`aboap[_khkn$namqaop%6
ebb]rknepa[_khknejnamqaop*CAP6
?na]pa]jDpplNaolkjoak^fa_p***
naolkjoa9DpplNaolkjoa$Ukqnb]rknepa_khkneojks!o!X
namqaop*CAPWb]rknepa[_khknY%
***]j`oap]_kkgeakjpdanaolkjoa
naolkjoa*oap[_kkgea$b]rknepa[_khkn(
namqaop*CAPWb]rknepa[_khknY%
napqnjnaolkjoa
ahoa6
napqnjDpplNaolkjoa$Ukq`e`j#pcera]b]rknepa_khkn*%
You can also pass a number of optional arguments to naolkjoa*oap[_kkgea$% that control
aspects of the cookie, as shown in Table 14-1.
Table 14-1. Cookie Options
Parameter Default Description
i]t[]ca Jkja Age (in seconds) that the cookie should last. If this parameter is Jkja, the
cookie will last only until the browser is closed.
atlenao Jkja The actual date/time when the cookie should expire. It needs to be in the
format S`u(@@)Ipd)UUDD6II6OOCIP. If given, this parameter over-
rides the i]t[]ca parameter.
l]pd + The path prefix that this cookie is valid for. Browsers will only pass the
cookie back to pages below this path prefix, so you can use this to prevent
cookies from being sent to other sections of your site.
This is especially useful when you don’t control the top level of your site’s
domain.
`ki]ej Jkja The domain that this cookie is valid for. You can use this parameter to set
a cross-domain cookie. For example, `ki]ej9*at]ilha*_ki will set a
cookie that is readable by the domains sss*at]ilha*_ki, sss.*at]ilha*
_ki, and ]j*kpdan*oq^*`ki]ej*at]ilha*_ki.
If this parameter is set to Jkja, a cookie will only be readable by the
domain that set it.
oa_qna B]hoa If set to Pnqa, this parameter instructs the browser to only return this
cookie to pages accessed over HTTPS.
The Mixed Blessing of Cookies
You might notice a number of potential problems with the way cookies work. Let’s look at
some of the more important ones:
CHAPTER 14 N SESSIONS, USERS, AND REGISTRATION
258
Ê UÊ -ÌÀ>}iÊvÊViÃÊÃÊÛÕÌ>ÀÞÆÊ>ÊViÌÊ`iÃÊÌÊ>ÛiÊÌÊ>VVi«ÌÊÀÊÃÌÀiÊViðÊÊv>VÌ]Ê
all browsers enable users to control the policy for accepting cookies. If you want to see
just how vital cookies are to the Web, try turning on your browser’s “prompt to accept
every cookie” option.
Despite their nearly universal use, cookies are still the definition of unreliability. This
means that developers should check that a user actually accepts cookies before relying
on them.
Ê UÊ iÃÊiëiV>ÞÊÌÃiÊÌÊÃiÌÊÛiÀÊ//*-®Ê>ÀiÊÌÊÃiVÕÀi°ÊiV>ÕÃiÊ//*Ê`>Ì>Ê
is sent in cleartext, cookies are extremely vulnerable to snooping attacks. That is, an
attacker snooping on the wire can intercept a cookie and read it. This means you
should never store sensitive information in a cookie.
There’s an even more insidious attack, known as a man-in-the-middle attack, wherein
>Ê>ÌÌ>ViÀÊÌiÀVi«ÌÃÊ>ÊViÊ>`ÊÕÃiÃÊÌÊÌÊ«ÃiÊ>ÃÊ>ÌiÀÊÕÃiÀ°Ê>«ÌiÀÊÓäÊ`Ã-
cusses attacks of this nature in depth, as well as ways to prevent it.
Ê UÊ iÃÊ>Ài½ÌÊiÛiÊÃiVÕÀiÊvÀÊÌiÀÊÌi`i`ÊÀiV«iÌðÊÃÌÊLÀÜÃiÀÃÊ«ÀÛ`iÊi>ÃÞÊ
ways to edit the content of individual cookies, and resourceful users can always use
tools like mechanize (dppl6++sssoa]n_d*okqn_abknca*jap+ia_d]jeva+) to construct
HTTP requests by hand.
So you can’t store data in cookies that might be sensitive to tampering. The canonical
mistake in this scenario is storing something like EoHkcca`Ej9- in a cookie when a user
logs in. You’d be amazed at the number of sites that make mistakes of this nature; it
takes only a second to fool these sites’ “security” systems.
Django’s Session Framework
With all of these limitations and potential security holes, it’s obvious that cookies and persis-
tent sessions are examples of those “pain points” in Web development. Of course, Django’s
goal is to be an effective painkiller, so it comes with a session framework designed to smooth
over these difficulties for you.
This session framework lets you store and retrieve arbitrary data on a per-site visitor basis.
ÌÊÃÌÀiÃÊ`>Ì>ÊÊÌiÊÃiÀÛiÀÊÃ`iÊ>`Ê>LÃÌÀ>VÌÃÊÌiÊÃi`}Ê>`ÊÀiViÛ}ÊvÊViðÊiÃÊ
use only a hashed session ID—not the data itself—thus protecting you from most of the com-
mon cookie problems.
Let’s look at how to enable sessions and use them in views.
Enabling Sessions
Sessions are implementedÊÛ>Ê>Ê«iViÊvÊ``iÜ>ÀiÊÃiiÊ>«ÌiÀʣǮÊ>`Ê>Ê>}Ê`i°Ê
To enable sessions, you’ll need to follow these steps:
1. Edit your IE@@HAS=NA[?H=OOAO setting and make sure IE@@HAS=NA[?H=OOAO contains
#`f]jck*_kjpne^*oaooekjo*ie``has]na*OaooekjIe``has]na#.
2. >iÊÃÕÀiÊ#`f]jck*_kjpne^*oaooekjo# is in your EJOP=HHA@[=LLO setting (and run
i]j]ca*luouj_`^ if you have to add it).
CHAPTER 14 N SESSIONS, USERS, AND REGISTRATION 259
The default skeleton settings created by op]nplnkfa_p have both of these bits already
installed, so unless you’ve removed them, you probably don’t have to change anything to get
sessions to work.
If you don’t want to use sessions, you might want to remove the OaooekjIe``has]na line
from IE@@HAS=NA[?H=OOAO and #`f]jck*_kjpne^*oaooekjo# from your EJOP=HHA@[=LLO. It will
save you only a small amount of overhead, but every little bit counts.
Using Sessions in Views
When OaooekjIe``has]na is activated, each DpplNamqaop object—the first argument to any
Django view function—will have a oaooekj attribute, which is a dictionary-like object. You can
read it and write to it in the same way you’d use a normal dictionary. For example, in a view
you could do stuff like this:
Oap]oaooekjr]hqa6
namqaop*oaooekjWb]r[_khknY9^hqa
Cap]oaooekjr]hqaÍpdeo_kqh`^a_]hha`ej]`ebbanajpreas(
kni]junamqaopoh]pan$kn^kpd%6
b]r[_khkn9namqaop*oaooekjWb]r[_khknY
?ha]n]jepaibnkipdaoaooekj6
`ahnamqaop*oaooekjWb]r[_khknY
?da_gebpdaoaooekjd]o]cerajgau6
ebb]r[_khknejnamqaop*oaooekj6
***
You can also use other dictionary methods like gauo$% and epaio$% on namqaop*oaooekj.
There are a couple of simple rules for using Django’s sessions effectively:
Ê UÊ 1ÃiÊÀ>Ê*ÞÌÊÃÌÀ}ÃÊ>ÃÊ`VÌ>ÀÞÊiÞÃÊÊnamqaop*oaooekj (as opposed to
integers, objects, etc.).
Ê UÊ -iÃÃÊ`VÌ>ÀÞÊiÞÃÊÌ>ÌÊLi}ÊÜÌÊ>ÊÕ`iÀÃVÀiÊ>ÀiÊÀiÃiÀÛi`ÊvÀÊÌiÀ>ÊÕÃiÊLÞÊ
Django. In practice, the framework uses only a small number of underscore-prefixed
session variables, but unless you know what they all are (and you are willing to keep
up with any changes in Django itself), staying away from underscore prefixes will keep
Django from interfering with your application.
For example, don’t use a session key called [b]r[_khkn like this:
namqaop*oaooekjW#[b]r[_khkn#Y9#^hqa#@kj#p`kpdeo
Ê UÊ ½ÌÊÀi«>ViÊnamqaop*oaooekj with a new object, and don’t access or set its attributes.
Use it like a Python dictionary. Here are a couple of examples:
namqaop*oaooekj9okia[kpdan[k^fa_p@kj#p`kpdeo
namqaop*oaooekj*bkk9#^]n#@kj#p`kpdeo
CHAPTER 14 N SESSIONS, USERS, AND REGISTRATION
260
Let’s take a look at a few quick examples. This simplistic view sets a d]o[_kiiajpa` vari-
able to Pnqa after a user posts a comment. It’s a simple (if not particularly secure) way of
preventing a user from posting more than one comment:
`ablkop[_kiiajp$namqaop%6
ebnamqaop*iapdk`9#LKOP#6
n]eoaDppl0,0$#KjhuLKOPo]na]hhksa`#%
eb#_kiiajp#jkpejnamqaop*LKOP6
n]eoaDppl0,0$#?kiiajpjkpoq^ieppa`#%
ebnamqaop*oaooekj*cap$#d]o[_kiiajpa`#(B]hoa%6
napqnjDpplNaolkjoa$Ukq#ra]hna]`u_kiiajpa`*%
_9_kiiajpo*?kiiajp$_kiiajp9namqaop*LKOPW#_kiiajp#Y%
_*o]ra$%
namqaop*oaooekjW#d]o[_kiiajpa`#Y9Pnqa
napqnjDpplNaolkjoa$#Pd]jgobknukqn_kiiajp#%
This simplistic view logs in a “member” of the site:
`abhkcej$namqaop%6
ebnamqaop*iapdk`9#LKOP#6
n]eoaDppl0,0$#KjhuLKOPo]na]hhksa`#%
pnu6
i9Iai^an*k^fa_po*cap$qoanj]ia9namqaop*LKOPW#qoanj]ia#Y%
ebi*l]ooskn`99namqaop*LKOPW#l]ooskn`#Y6
namqaop*oaooekjW#iai^an[e`#Y9i*e`
napqnjDpplNaolkjoaNa`ena_p$#+ukq)]na)hkcca`)ej+#%
at_alpIai^an*@kaoJkpAteop6
napqnjDpplNaolkjoa$Ukqnqoanj]ia]j`l]ooskn``e`j#pi]p_d*%
And this one logs out a member who has been logged in via hkcej$%:
`abhkckqp$namqaop%6
pnu6
`ahnamqaop*oaooekjW#iai^an[e`#Y
at_alpGauAnnkn6
l]oo
napqnjDpplNaolkjoa$Ukq#nahkcca`kqp*%
NNote In practice, this is a lousy way of logging users in. The authentication framework discussed shortly
handles this task for you in a much more robust and useful manner. These examples are deliberately sim-
plistic so that you can easily see what’s going on.
CHAPTER 14 N SESSIONS, USERS, AND REGISTRATION 261
Setting Test Cookies
As mentioned earlier, you can’t rely on every browser accepting cookies. So, as a conve-
nience, Django provides an easy way to test whether a user’s browser accepts cookies. Just
call namqaop*oaooekj*oap[paop[_kkgea$% in a view, and check namqaop*oaooekj*paop[_kkgea[
sknga`$% in a subsequent view—not in the same view call.
This awkward split between oap[paop[_kkgea$% and paop[_kkgea[sknga`$% is necessary
due to the way cookies work. When you set a cookie, you can’t actually tell whether a browser
accepted it until the browser’s next request.
It’s good practice to use `ahapa[paop[_kkgea$% to clean up after yourself. Do this after
you’ve verified that the test cookie worked.
Here’s a typical usage example:
`abhkcej$namqaop%6
Ebsaoq^ieppa`pdabkni***
ebnamqaop*iapdk`99#LKOP#6
?da_gpd]ppdapaop_kkgeasknga`$saoapep^ahks%6
ebnamqaop*oaooekj*paop[_kkgea[sknga`$%6
Pdapaop_kkgeasknga`(ok`ahapaep*
namqaop*oaooekj*`ahapa[paop[_kkgea$%
Ejln]_pe_a(sa#`jaa`okiahkce_pk_da_gqoanj]ia+l]ooskn`
dana(^qpoej_apdeoeo]jat]ilha***
napqnjDpplNaolkjoa$Ukq#nahkcca`ej*%
Pdapaop_kkgeab]eha`(ok`eolh]u]jannkniaoo]ca*Ebpdeo
sana]na]hoepa(sa#`s]jppk`eolh]u]bneaj`heaniaoo]ca*
ahoa6
napqnjDpplNaolkjoa$Lha]oaaj]^ha_kkgeao]j`pnu]c]ej*%
Ebsa`e`j#plkop(oaj`pdapaop_kkgea]hkjcsepdpdahkcejbkni*
namqaop*oaooekj*oap[paop[_kkgea$%
napqnjnaj`an[pk[naolkjoa$#bkk+hkcej[bkni*dpih#%
NNote Again, the built-in authentication functions handle this check for you.
Using Sessions Outside of Views
Internally, each session is just a normal Django model defined in `f]jck*_kjpne^*oaooekjo*
ik`aho°Ê>VÊÃiÃÃÊÃÊ`iÌvi`ÊLÞÊ>ÊÀiÀiÃÃÊÀ>`ÊÎÓV>À>VÌiÀÊ>ÃÊÃÌÀi`ÊÊ>Ê
cookie. Because it’s a normal model, you can access sessions using the normal Django data-
base API:
CHAPTER 14 N SESSIONS, USERS, AND REGISTRATION
262
:::bnki`f]jck*_kjpne^*oaooekjo*ik`ahoeilknpOaooekj
:::o9Oaooekj*k^fa_po*cap$lg9#.^--45]-44^00]`-4_/1a--/]_2_aa]`#%
:::o*atlena[`]pa
`]papeia*`]papeia$.,,1(4(.,(-/(/1(-.%
You’ll need to call cap[`a_k`a`$% to get the actual session data. This is necessary because
the dictionary is stored in an encoded format:
:::o*oaooekj[`]p]
#GCNsIMlPF-5d`TNkT/RvVTFb]SMj?j=u?ggt?jIqIPAtU.VfK@E.Uf***#
:::o*cap[`a_k`a`$%
w#qoan[e`#60.y
When Sessions Are Saved
By default, Django only saves to the database if the session has been modified—that is, if any
of its dictionary values have been assigned or deleted:
Oaooekjeoik`ebea`*
namqaop*oaooekjW#bkk#Y9#^]n#
Oaooekjeoik`ebea`*
`ahnamqaop*oaooekjW#bkk#Y
Oaooekjeoik`ebea`*
namqaop*oaooekjW#bkk#Y9wy
Ckp_d]6OaooekjeoJKPik`ebea`(^a_]qoapdeo]hpano
namqaop*oaooekjW#bkk#Yejopa]`kbnamqaop*oaooekj*
namqaop*oaooekjW#bkk#YW#^]n#Y9#^]v#
To change this default behavior, set OAOOEKJ[O=RA[ARANU[NAMQAOP to Pnqa. If OAOOEKJ[O=RA[
ARANU[NAMQAOP is Pnqa, Django will save the session to the database on every single request,
even if it wasn’t changed.
Note that the session cookie is sent only when a session has been created or modified. If
OAOOEKJ[O=RA[ARANU[NAMQAOP is Pnqa, the session cookie will be sent on every request. Similarly,
the atlenao part of a session cookie is updated each time the session cookie is sent.
Browser-Length Sessions vs. Persistent Sessions
You might have noticed that the cookie Google sent at the beginning of this chapter contained
atlenao9Oqj(-3)F]j).,/4-56-06,3CIP7°ÊiÃÊV>Ê«Ì>ÞÊVÌ>Ê>ÊiÝ«À>ÌÊ`>ÌiÊ
that advises the browser on when to remove the cookie. If a cookie doesn’t contain an expira-
tion value, the browser will expire it when the user closes his or her browser window. You can
control the session framework’s behavior in this regard with the OAOOEKJ[ATLENA[=P[>NKSOAN[
?HKOA setting.
CHAPTER 14 N SESSIONS, USERS, AND REGISTRATION 263
By default, OAOOEKJ[ATLENA[=P[>NKSOAN[?HKOA is set to B]hoa, which means session cookies
will be stored in users’ browsers for OAOOEKJ[?KKGEA[=CA seconds (which defaults to two weeks,
ÀÊ£]Óä]ÈääÊÃiV`î°Ê1ÃiÊÌÃÊvÊÞÕÊ`½ÌÊÜ>ÌÊ«i«iÊÌÊ>ÛiÊÌÊ}ÊÊiÛiÀÞÊÌiÊÌiÞÊ«iÊ
a browser.
If OAOOEKJ[ATLENA[=P[>NKSOAN[?HKOA is set to Pnqa, Django will use browser-length cookies.
Other Session Settings
Besides the settings already mentioned, a few other settings influence how Django’s session
framework uses cookies, asÊÃÜÊÊ/>LiÊ£{Ó°
Table 14-2. Settings That Influence Cookie Behavior
Setting Description Default
OAOOEKJ[?KKGEA[@KI=EJ The domain to use for session cookies. Set this to a
string such as *at]ilha*_ki for cross-domain cook-
ies, or use Jkja for a standard cookie.
Jkja
OAOOEKJ[?KKGEA[J=IA The name of the cookie to use for sessions. This can be
any string.
oaooekje`
OAOOEKJ[?KKGEA[OA?QNA Whether to use a “secure” cookie for the session
cookie. If this is set to Pnqa, the cookie will be marked
as “secure,” which means that browsers will ensure
that the cookie is only sent via HTTPS.
B]hoa
TECHNICAL DETAILS
For the curious, here are a few technical notes about the inner workings of the session framework:
s 4HESESSIONDICTIONARYACCEPTSANY0YTHONOBJECTCAPABLEOFBEINGhPICKLEDv3EETHEDOCUMENTATION
FOR0YTHONSBUILTINle_gha module for information about how this works.
s 3ESSIONDATAISSTOREDINADATABASETABLENAMED`f]jck[oaooekj.
s 3ESSIONDATAISFETCHEDUPONDEMAND)FYOUNEVERACCESSnamqaop*oaooekj$JANGOWONTHITTHAT
database table.
s $JANGOSENDSACOOKIEONLYIFITNEEDSTO)FYOUDONTSETANYSESSIONDATAITWONTSENDASESSION
cookie (unless OAOOEKJ[O=RA[ARANU[NAMQAOP is set to Pnqa).
s 4HE$JANGOSESSIONSFRAMEWORKISENTIRELYANDSOLELYCOOKIEBASED)TDOESNOTFALLBACKTOPUTTING
SESSION)$SIN52,SASALASTRESORTASSOMEOTHERTOOLS0(0*30DO
 4HISISANINTENTIONALDESIGNDECISION0UTTINGSESSIONSIN52,SDOESNgTJUSTMAKE52,SUGLYTHEYALSO
MAKEYOURSITEVULNERABLETOACERTAINFORMOFSESSION)$THEFTVIATHENabanan header.
)FYOURESTILLCURIOUSTHESOURCEISPRETTYSTRAIGHTFORWARDLOOKIN`f]jck*_kjpne^*oaooekjo for
more details.
CHAPTER 14 N SESSIONS, USERS, AND REGISTRATION
264
Users and Authentication
Sessions give us a way of persisting data through multiple browser requests; the second part of
the equation is using those sessions for user login. Of course, we can’t just trust that users are
who they say they are, so we need to authenticate them along the way.
Naturally, Django provides tools to handle this common task (and many others). Django’s
user authentication system handles user accounts, groups, permissions, and cookie-based
user sessions. This system is often referred to as an auth/auth (authentication and authoriza-
tion) system. That name recognizes that dealing with users is often a two-step process. We
need to
1. Verify (authenticate) that a user is who he or she claims to be (usually by checking a
username and password against a database of users)
2. Verify that the user is authorized to perform some given operation (usually by checking
against a table of permissions)
Following these needs, Django’s auth/auth system consists of a number of parts:
ÊUÊUsers: People registered with your site
ÊUÊPermissions: Binary (yes/no) flags designating whether a user may perform a certain
task
ÊUÊGroups: A generic way of applying labels and permissions to more than one user
ÊUÊMessages: A simple way to queue and display system messages to users
vÊÞÕ½ÛiÊÕÃi`ÊÌiÊ>`ÊÌÊ`ÃVÕÃÃi`ÊÊ>«ÌiÀÊÈ®]ÊÞÕ½ÛiÊ>Ài>`ÞÊÃiiÊ>ÞÊvÊÌiÃiÊ
tools, and if you’ve edited users or groups in the admin tool, you’ve actually been editing data
in the auth system’s database tables.
Enabling Authentication Support
Like the session tools, authentication support is bundled as a Django application in `f]jck*
_kjpne^ that needs to be installed. Similar to the session tools, it’s also installed by default, but
if you’ve removed it, you’ll need to follow these steps to install it:
1. >iÊÃÕÀiÊÌiÊÃiÃÃÊvÀ>iÜÀÊÃÊÃÌ>i`Ê>ÃÊ`iÃVÀLi`Êi>ÀiÀÊÊÌÃÊV>«ÌiÀ°Ê
Keeping track of users obviously requires cookies, and thus builds on the session
framework.
2. Put #`f]jck*_kjpne^*]qpd# in your EJOP=HHA@[=LLO setting and run i]j]ca*luouj_`^
to install the appropriate database tables.
3. >iÊÃÕÀiÊÌ>ÌÊ#`f]jck*_kjpne^*]qpd*ie``has]na*=qpdajpe_]pekjIe``has]na# is in
your IE@@HAS=NA[?H=OOAO setting—after OaooekjIe``has]na.
With that installation out of the way, we’re ready to deal with users in view functions.
The main interface you’ll use to access users within a view is namqaop*qoan; this is an object
that represents the currently logged-in user. If the user isn’t logged in, this will instead be an
=jkjuikqoQoan object (see the following section for more details).
CHAPTER 14 N SESSIONS, USERS, AND REGISTRATION 265
You can easily tell if a user is logged in with the eo[]qpdajpe_]pa`$% method:
ebnamqaop*qoan*eo[]qpdajpe_]pa`$%6
@kokiapdejcbkn]qpdajpe_]pa`qoano*
ahoa6
@kokiapdejcbkn]jkjuikqoqoano*
Using Users
Once you have a Qoan—often from namqaop*qoan, but possibly through one of the other meth-
ods discussed shortly—you have a number of fields and methods available on that object.
=jkjuikqoQoan objects emulate some of this interface, but not all of it, so you should always
check qoan*eo[]qpdajpe_]pa`$% before assuming you’re dealing with a bona fide qoan object.
Tables 14-3 and 14-4 list the fields and methods, respectively, on Qoan objects.
Table 14-3. Fields on User Objects
Field Description
qoanj]ia ,iµÕÀi`ÆÊÎäÊV>À>VÌiÀÃÊÀÊviÜiÀ°Ê«>ÕiÀVÊV>À>VÌiÀÃÊÞÊiÌÌiÀÃ]Ê`}ÌÃ]Ê
and underscores).
benop[j]ia "«Ì>ÆÊÎäÊV>À>VÌiÀÃÊÀÊviÜiÀ°
h]op[j]ia "«Ì>ÆÊÎäÊV>À>VÌiÀÃÊÀÊviÜiÀ°
ai]eh Optional. E-mail address.
l]ooskn` Required. A hash of, and metadata about, the password (Django doesn’t store the
raw password). See the “Passwords” section for more about this value.
eo[op]bb Boolean. Designates whether this user can access the admin site.
eo[]_pera Boolean. Designates whether this account can be used to log in. Set this flag to
B]hoa instead of deleting accounts.
eo[oqlanqoan Boolean. Designates that this user has all permissions without explicitly assign-
ing them.
h]op[hkcej A datetime of the user’s last login. This is set to the current date/time by default.
`]pa[fkeja` A datetime designating when the account was created. This is set to the current
date/time by default when the account is created.
Table 14-4. Methods on User Objects
Method Description
eo[]qpdajpe_]pa`$% Always returns Pnqa for “real” Qoan objects. This is a way to tell
if the user has been authenticated. This does not imply any
permissions, and it doesn’t check if the user is active. It only
indicates that the user has successfully authenticated.
eo[]jkjuikqo$% Returns Pnqa only for =jkjuikqoQoan objects (and B]hoa for
“real” Qoan objects). Generally, you should prefer using eo[
]qpdajpe_]pa`$% to this method.
cap[bqhh[j]ia$% Returns the benop[j]ia plus the h]op[j]ia, with a space in
between.
Continued
CHAPTER 14 N SESSIONS, USERS, AND REGISTRATION
266
Table 14-4. Continued
Method Description
oap[l]ooskn`$l]oos`% Sets the user’s password to the given raw string, taking care of
the password hashing. This doesn’t actually save the Qoan object.
_da_g[l]ooskn`$l]oos`% Returns Pnqa if the given raw string is the correct password for
the user. This takes care of the password hashing in making the
comparison.
cap[cnkql[lanieooekjo$% Returns a list of permission strings that the user has through the
groups he or she belongs to.
cap[]hh[lanieooekjo$% Returns a list of permission strings that the user has, both
through group and user permissions.
d]o[lani$lani% Returns Pnqa if the user has the specified permission, where
lani is in the format l]_g]ca*_k`aj]ia. If the user is inactive,
this method will always return B]hoa.
d]o[lanio$lani[heop% Returns Pnqa if the user has all of the specified permissions.
If the user is inactive, this method will always return B]hoa.
d]o[ik`qha[lanio$]ll[h]^ah% Returns Pnqa if the user has any permissions in the given
]ll[h]^ah. If the user is inactive, this method will always return
B]hoa.
cap[]j`[`ahapa[iaoo]cao$% Returns a list of Iaoo]ca objects in the user’s queue and deletes
the messages from the queue.
ai]eh[qoan$oq^f(ioc% Sends an e-mail to the user. This e-mail is sent from the @AB=QHP[
BNKI[AI=EH setting. You can also pass a third argument, bnki[
ai]eh, to override the From address on the e-mail.
Finally, Qoan objects have two many-to-many fields: cnkqlo and lanieooekjo. Qoan objects
can access their related objects in the same way as any other many-to-many field:
Oap]qoan#ocnkqlo6
iuqoan*cnkqlo9cnkql[heop
=``]qoanpkokiacnkqlo6
iuqoan*cnkqlo*]``$cnkql-(cnkql.(***%
Naikra]qoanbnkiokiacnkqlo6
iuqoan*cnkqlo*naikra$cnkql-(cnkql.(***%
Naikra]qoanbnki]hhcnkqlo6
iuqoan*cnkqlo*_ha]n$%
Lanieooekjoskngpdao]ias]u
iuqoan*lanieooekjo9lanieooekj[heop
iuqoan*lanieooekjo*]``$lanieooekj-(lanieooekj.(***%
iuqoan*lanieooekjo*naikra$lanieooekj-(lanieooekj.(***%
iuqoan*lanieooekjo*_ha]n$%
CHAPTER 14 N SESSIONS, USERS, AND REGISTRATION 267
Logging In and Out
Django provides built-in view functions for handling logging in and out (and a few other nifty
tricks), but before we get to those, let’s take a look at how to log users in and out “by hand.”
Django provides two functions to perform these actions in `f]jck*_kjpne^*]qpd: ]qpdajpe_]pa$%
and hkcej$%.
To authenticate a given username and password, use ]qpdajpe_]pa$%. It takes two key-
word arguments, qoanj]ia and l]ooskn`, and it returns a Qoan object if the password is valid
for the given username. If the password is invalid, ]qpdajpe_]pa$% returns Jkja:
:::bnki`f]jck*_kjpne^eilknp]qpd
:::qoan9]qpd*]qpdajpe_]pa$qoanj]ia9#fkdj#(l]ooskn`9#oa_nap#%
:::ebqoaneojkpJkja6
***lnejp?knna_p
***ahoa6
***lnejpEjr]he`l]ooskn`*
]qpdajpe_]pa$% only verifies a user’s credentials. To log in a user, use hkcej$%. It takes an
DpplNamqaop object and a Qoan object and saves the user’s ID in the session, using Django’s ses-
sion framework.
This example shows how you might use both ]qpdajpe_]pa$% and hkcej$% within a view
function:
bnki`f]jck*_kjpne^eilknp]qpd
`abhkcej[reas$namqaop%6
qoanj]ia9namqaop*LKOP*cap$#qoanj]ia#(##%
l]ooskn`9namqaop*LKOP*cap$#l]ooskn`#(##%
qoan9]qpd*]qpdajpe_]pa$qoanj]ia9qoanj]ia(l]ooskn`9l]ooskn`%
ebqoaneojkpJkja]j`qoan*eo[]_pera6
?knna_pl]ooskn`(]j`pdaqoaneoi]nga`]_pera
]qpd*hkcej$namqaop(qoan%
Na`ena_ppk]oq__aool]ca*
napqnjDpplNaolkjoaNa`ena_p$+]__kqjp+hkcca`ej+%
ahoa6
Odks]jannknl]ca
napqnjDpplNaolkjoaNa`ena_p$+]__kqjp+ejr]he`+%
To log out a user, use `f]jck*_kjpne^*]qpd*hkckqp$% within your view. It takes an
DpplNamqaop object and has no return value:
bnki`f]jck*_kjpne^eilknp]qpd
`abhkckqp[reas$namqaop%6
]qpd*hkckqp$namqaop%
Na`ena_ppk]oq__aool]ca*
napqnjDpplNaolkjoaNa`ena_p$+]__kqjp+hkcca`kqp+%
Note that ]qpd*hkckqp$% doesn’t throw any errors if the user wasn’t logged in.
CHAPTER 14 N SESSIONS, USERS, AND REGISTRATION
268
In practice, you usually will not need to write your own login/logout functions; the
authentication system comes with a set of views for generically handling logging in and out.
The first step in using these authentication views is to wire them up in your URLconf. You’ll
need to add this snippet:
bnki`f]jck*_kjpne^*]qpd*reasoeilknphkcej(hkckqp
qnhl]ppanjo9l]ppanjo$##(
ateopejcl]ppanjodana***
$n#Z]__kqjpo+hkcej+ #(hkcej%(
$n#Z]__kqjpo+hkckqp+ #(hkckqp%(
%
+]__kqjpo+hkcej+ and +]__kqjpo+hkckqp+ are the default URLs that Django uses for these
views.
By default, the hkcej view renders a template at naceopn]pekj+hkcej*dpih (you can change
this template name by passing an extra view argument , pailh]pa[j]ia). This form needs to
contain a qoanj]ia and a l]ooskn` field. A simple template might look like this:
w!atpaj`o^]oa*dpih!y
w!^hk_g_kjpajp!y
w!ebbkni*annkno!y
8l_h]oo9annkn:Oknnu(pd]p#ojkp]r]he`qoanj]iaknl]ooskn`8+l:
w!aj`eb!y
8bkni]_pekj9iapdk`9lkop:
8h]^ahbkn9qoanj]ia:Qoanj]ia68+h]^ah:
8ejlqppula9patpj]ia9qoanj]iar]hqa9e`9qoanj]ia:
8h]^ahbkn9l]ooskn`:L]ooskn`68+h]^ah:
8ejlqppula9l]ooskn`j]ia9l]ooskn`r]hqa9e`9l]ooskn`:
8ejlqppula9oq^iepr]hqa9hkcej+:
8ejlqppula9de``ajj]ia9jatpr]hqa9wwjatpxao_]layy+:
8+bkni:
w!aj`^hk_g!y
If the user successfully logs in, he or she will be redirected to +]__kqjpo+lnkbeha+ by
default. You can override this by providing a hidden field called jatp with the URL to redirect
to after logging in. You can also pass this value as a CAP parameter to the login view and it will
be automatically added to the context as a variable called jatp that you can insert into that
hidden field.
The logout view works a little differently. By default it renders a template at naceopn]pekj+
hkcca`[kqp*dpih (which usually contains a “You’ve successfully logged out” message). How-
ever, you can call the view with an extra argument, jatp[l]ca, which will instruct the view to
redirect after a logout.
CHAPTER 14 N SESSIONS, USERS, AND REGISTRATION 269
Limiting Access to Logged-in Users
Of course, the reason we’re going through all this trouble is so we can limit access to parts of
our site.
The simple, raw way to limit access to pages is to check namqaop*qoan*eo[]qpdajpe_]pa`$%
and redirect to a login page:
bnki`f]jck*dppleilknpDpplNaolkjoaNa`ena_p
`abiu[reas$namqaop%6
ebjkpnamqaop*qoan*eo[]qpdajpe_]pa`$%6
napqnjDpplNaolkjoaNa`ena_p$#+]__kqjpo+hkcej+;jatp9!o#!namqaop*l]pd%
***
or perhaps display an error message:
`abiu[reas$namqaop%6
ebjkpnamqaop*qoan*eo[]qpdajpe_]pa`$%6
napqnjnaj`an[pk[naolkjoa$#iu]ll+hkcej[annkn*dpih#%
***
As a shortcut, you can use the convenient hkcej[namqena` decorator:
bnki`f]jck*_kjpne^*]qpd*`a_kn]pknoeilknphkcej[namqena`
<hkcej[namqena`
`abiu[reas$namqaop%6
***
hkcej[namqena` does the following:
Ê UÊ vÊÌiÊÕÃiÀÊÃ½ÌÊ}}i`Ê]ÊÀi`ÀiVÌÊÌÊ+]__kqjpo+hkcej+, passing the current URL path
in the query string as jatp, for example: +]__kqjpo+hkcej+;jatp9+lkhho+/+.
Ê UÊ vÊÌiÊÕÃiÀÊÃÊ}}i`Ê]ÊiÝiVÕÌiÊÌi view normally. The view code can then assume that
the user is logged in.
Limiting Access to Users Who Pass a Test
Limiting access based on certain permissions or some other test, or providing a different loca-
tion for the login view works essentially the same way.
The raw way is to run your test on namqaop*qoan in the view directly. For example, this
view checks to make sure the user is logged in and has the permission lkhho*_]j[rkpa (more
about how permissions work follows):
`abrkpa$namqaop%6
ebnamqaop*qoan*eo[]qpdajpe_]pa`$%]j`namqaop*qoan*d]o[lani$#lkhho*_]j[rkpa#%%6
rkpadana
ahoa6
napqnjDpplNaolkjoa$Ukq_]j#prkpaejpdeolkhh*%
CHAPTER 14 N SESSIONS, USERS, AND REGISTRATION
270
Again, Django provides a shortcut called qoan[l]ooao[paop. It takes arguments and gener-
ates a specialized decorator for your particular situation:
`abqoan[_]j[rkpa$qoan%6
napqnjqoan*eo[]qpdajpe_]pa`$%]j`qoan*d]o[lani$lkhho*_]j[rkpa%
<qoan[l]ooao[paop$qoan[_]j[rkpa(hkcej[qnh9+hkcej+%
`abrkpa$namqaop%6
?k`adana_]j]ooqia]hkcca`)ejqoansepdpda_knna_planieooekj*
***
qoan[l]ooao[paop takes one required argument: a callable that takes a Qoan object and
returns Pnqa if the user is allowed to view the page. Note that qoan[l]ooao[paop does not auto-
matically check that the Qoan is authenticated; you should do that yourself.
In this example we’re also showing the second (optional) argument, hkcej[qnh, which lets
you specify the URL for your login page (+]__kqjpo+hkcej+ by default). If the user doesn’t pass
the test, the qoan[l]ooao[paop decorator will redirect the user to the hkcej[qnh.
Because it’s a relatively common task to check whether a user has a particular permission,
Django provides a shortcut for that case: the lanieooekj[namqena`$% decorator. Using this
decorator, the earlier example can be written as follows:
bnki`f]jck*_kjpne^*]qpd*`a_kn]pknoeilknplanieooekj[namqena`
<lanieooekj[namqena`$#lkhho*_]j[rkpa#(hkcej[qnh9+hkcej+%
`abrkpa$namqaop%6
***
Note that lanieooekj[namqena`$% also takes an optional hkcej[qnh parameter, which also
defaults to #+]__kqjpo+hkcej+#.
LIMITING ACCESS TO GENERIC VIEWS
/NEOFTHEMOSTFREQUENTLYASKEDQUESTIONSONTHE$JANGOUSERSLISTDEALSWITHLIMITINGACCESSTOAGENERIC
VIEW4OPULLTHISOFFYOULLNEEDTOWRITEATHINWRAPPERAROUNDTHEVIEWANDPOINTYOUR52,CONFTOYOUR
WRAPPERINSTEADOFTHEGENERICVIEWITSELF
bnki`f]jck*_kjpne^*]qpd*`a_kn]pknoeilknphkcej[namqena`
bnki`f]jck*reaso*cajane_*`]pa[^]oa`eilknpk^fa_p[`ap]eh
<hkcej[namqena`
`abheiepa`[k^fa_p[`ap]eh$&]nco(&&gs]nco%6
napqnjk^fa_p[`ap]eh$&]nco(&&gs]nco%
You can, of course, replace hkcej[namqena` with any of the other limiting decorators.
CHAPTER 14 N SESSIONS, USERS, AND REGISTRATION 271
Managing Users, Permissions, and Groups
/iÊi>ÃiÃÌÊÜ>ÞÊLÞÊv>ÀÊÌÊ>>}iÊÌiÊ>ÕÌÊÃÞÃÌiÊÃÊÌÀÕ}ÊÌiÊ>`ÊÌiÀv>Vi°Ê>«ÌiÀÊÈÊ
discusses how to use Django’s admin site to edit users and control their permissions and
access, and most of the time you’ll just use that interface.
However, there are low-level APIs you can dive into when you need absolute control, and
we discuss these in the sections that follow.
Creating Users
Ài>ÌiÊÕÃiÀÃ with the _na]pa[qoan helper function:
:::bnki`f]jck*_kjpne^*]qpd*ik`ahoeilknpQoan
:::qoan9Qoan*k^fa_po*_na]pa[qoan$qoanj]ia9#fkdj#(
***ai]eh9#fhajjkj<^a]phao*_ki#(
***l]ooskn`9#ch]ookjekj#%
At this point, qoan is a Qoan instance ready to be saved to the database (_na]pa[qoan$%
doesn’t actually call o]ra$% itself). You can continue to change its attributes before saving, too:
:::qoan*eo[op]bb9Pnqa
:::qoan*o]ra$%
Changing Passwords
You can change a password with oap[l]ooskn`$%:
:::qoan9Qoan*k^fa_po*cap$qoanj]ia9#fkdj#%
:::qoan*oap[l]ooskn`$#ckkckkckkfkk^#%
:::qoan*o]ra$%
Don’t set the l]ooskn` attribute directly unless you know what you’re doing. The pass-
word is actually stored as a salted hash and thus can’t be edited directly.
ÀiÊvÀ>Þ]ÊÌiÊl]ooskn` attribute of a Qoan object is a string in this format:
d]odpula o]hp d]od
That’s a hash type, the salt, and the hash itself, separated by the dollar sign ($) character.
d]odpula is either od]- (default) or i`1, the algorithm used to perform a one-way hash
of the password. o]hp is a random string used to salt the raw password to create the hash, for
example:
od]- ]-532 ]/2__4_^b4-30.]4b^1.a..-]]a]^04a`3b14]^0
The Qoan*oap[l]ooskn`$% and Qoan*_da_g[l]ooskn`$% functions handle the setting and
checking of these values behind the scenes.
CHAPTER 14 N SESSIONS, USERS, AND REGISTRATION
272
SALTED HASHES
A hashISAONEWAYCRYPTOGRAPHICFUNCTIONTHATISYOUCANEASILYCOMPUTETHEHASHOFAGIVENVALUEBUT
ITSNEARLYIMPOSSIBLETOTAKEAHASHANDRECONSTRUCTTHEORIGINALVALUE
If we stored passwords as plain text, anyone who got their hands on the password database would
INSTANTLYKNOWEVERYONESPASSWORD3TORINGPASSWORDSASHASHESREDUCESTHEVALUEOFACOMPROMISED
database.
(OWEVERANATTACKERWITHTHEPASSWORDDATABASECOULDSTILLRUNAbrute-force attack, hashing millions
OFPASSWORDSANDCOMPARINGTHOSEHASHESAGAINSTTHESTOREDVALUES4HISTAKESSOMETIMEBUTLESSTHANYOU
might think.
7ORSETHEREAREPUBLICLYAVAILABLErainbow tables, or databases of pre-computed hashes of millions of
passwords. With a rainbow table, an experienced attacker could break most passwords in seconds.
Adding a saltBASICALLYANINITIALRANDOMVALUETOTHESTOREDHASHADDSANOTHERLAYEROFDIFFICULTYTO
BREAKINGPASSWORDS"ECAUSESALTSDIFFERFROMPASSWORDTOPASSWORDTHEYALSOPREVENTTHEUSEOFARAIN-
bow table, thus forcing attackers to fall back on a brute-force attack, itself made more difficult by the extra
entropy added to the hash by the salt.
While salted hashes aren’t absolutely the most secure way of storing passwords, they’re a good middle
GROUNDBETWEENSECURITYANDCONVENIENCE
Handling Registration
We can use these low-level tools to create views that allow users to sign up for new accounts.
Different developers implement registration differently, so Django leaves writing a registration
view up to you. Luckily, it’s pretty easy.
At its simplest, we could provide a small view that prompts for the required user informa-
tion and creates those users. Django provides a built-in form you can use for this purpose,
which we’ll use in this example:
bnki`f]jckeilknpbknio
bnki`f]jck*_kjpne^*]qpd*bknioeilknpQoan?na]pekjBkni
bnki`f]jck*dppleilknpDpplNaolkjoaNa`ena_p
bnki`f]jck*odknp_qpoeilknpnaj`an[pk[naolkjoa
`abnaceopan$namqaop%6
ebnamqaop*iapdk`99#LKOP#6
bkni9Qoan?na]pekjBkni$namqaop*LKOP%
ebbkni*eo[r]he`$%6
jas[qoan9bkni*o]ra$%
napqnjDpplNaolkjoaNa`ena_p$+^kkgo+%
ahoa6
bkni9Qoan?na]pekjBkni$%
napqnjnaj`an[pk[naolkjoa$naceopn]pekj+naceopan*dpih(w
#bkni#6bkni(
y%
CHAPTER 14 N SESSIONS, USERS, AND REGISTRATION 273
This form assumes a template named naceopn]pekj+naceopan*dpih. Here’s an example of
what that template might look like:
w!atpaj`o^]oa*dpih!y
w!^hk_gpepha!y?na]pa]j]__kqjpw!aj`^hk_g!y
w!^hk_g_kjpajp!y
8d-:?na]pa]j]__kqjp8+d-:
8bkni]_pekj9iapdk`9lkop:
wwbkni*]o[lyy
8ejlqppula9oq^iepr]hqa9?na]papda]__kqjp:
8+bkni:
w!aj`^hk_g!y
Using Authentication Data in Templates
The current logged-in user and his or her permissions are made available in the template con-
text when you use Namqaop?kjpatpÊÃiiÊ>«ÌiÀÊ®°
NNote 4ECHNICALLYTHESEVARIABLESAREONLYMADEAVAILABLEINTHETEMPLATECONTEXTIFYOUUSE
Namqaop?kjpatp and your PAILH=PA[?KJPATP[LNK?AOOKNO setting contains `f]jck*_kna*_kjpatp[
lnk_aookno*]qpd, which is the default. Again, see Chapter 9 for more information.
When using Namqaop?kjpatp, the current user (either a Qoan instance or an =jkjuikqoQoan
instance) is stored in the template variable wwqoanyy:
w!ebqoan*eo[]qpdajpe_]pa`!y
8l:Sah_kia(wwqoan*qoanj]iayy*Pd]jgobknhkccejcej*8+l:
w!ahoa!y
8l:Sah_kia(jasqoan*Lha]oahkcej*8+l:
w!aj`eb!y
This user’s permissions are stored in the template variable wwlanioyy. This is a template-
friendly proxy to a couple of permission methods described shortly.
There are two ways you can use this lanio object. You can use something like w!eb
lanio*lkhho!y to check whether the user has any permissions for some given application, or
you can use something like w!eblanio*lkhho*_]j[rkpa!y to check if the user has a specific
permission.
CHAPTER 14 N SESSIONS, USERS, AND REGISTRATION
274
Thus, you can check permissions in template w!eb!y statements:
w!eblanio*lkhho!y
8l:Ukqd]ralanieooekjpk`kokiapdejcejpdalkhho]ll*8+l:
w!eblanio*lkhho*_]j[rkpa!y
8l:Ukq_]jrkpa8+l:
w!aj`eb!y
w!ahoa!y
8l:Ukq`kj#pd]ralanieooekjpk`k]jupdejcejpdalkhho]ll*8+l:
w!aj`eb!y
Permissions, Groups, and Messages
There are a few other bits of the authentication framework that we’ve only dealt with in pass-
ing. We’ll take a closer look at them in the following sections.
Permissions
Permissions are a simple way to “mark” users and groups as being able to perform some
action. They are usually used by the Django admin site, but you can easily use them in your
own code.
The Django admin site uses permissions as follows:
Ê UÊ VViÃÃÊÌÊÛiÜÊÌiʺ>``»ÊvÀ]Ê>`Ê>``Ê>ÊLiVÌÊÃÊÌi`ÊÌÊÕÃiÀÃÊÜÌÊÌiÊadd per-
mission for that type of object.
Ê UÊ VViÃÃÊÌÊÛiÜÊÌiÊV>}iÊÃÌ]ÊÛiÜÊÌiʺV>}i»ÊvÀ]Ê>`ÊV>}iÊ>ÊLiVÌÊÃÊÌi`Ê
to users with the change permission for that type of object.
Ê UÊ VViÃÃÊÌÊ`iiÌiÊ>ÊLiVÌÊÃÊÌi`ÊÌÊÕÃiÀÃÊÜÌÊÌiÊdelete permission for that type
of object.
Permissions are set globally per type of object, not per specific object instance. For
iÝ>«i]Ê̽ÃÊ«ÃÃLiÊÌÊÃ>Þʺ>ÀÞÊ>ÞÊV>}iÊiÜÃÊÃÌÀiÃ]»ÊLÕÌÊ«iÀÃÃÃÊ`½ÌÊiÌÊÞÕÊ
Ã>Þʺ>ÀÞÊ>ÞÊV>}iÊiÜÃÊÃÌÀiÃ]ÊLÕÌÊÞÊÌiÊiÃÊÃiÊVÀi>Ìi`ÊiÀÃiv»ÊÀʺ>ÀÞÊ>ÞÊÞÊ
change news stories that have a certain status, publication date, or ID.”
These three basic permissions—add, change, and delete—are automatically created for
each Django model. Behind the scenes, these permissions are added to the ]qpd[lanieooekj
database table when you run i]j]ca*luouj_`^.
These permissions will be of the form 8]ll:*8]_pekj:[8k^fa_p[j]ia:. That is, if you
have a lkhho application with a ?dke_a model, you’ll get permissions named lkhho*]``[
_dke_a, lkhho*_d]jca[_dke_a, and lkhho*`ahapa[_dke_a.
CHAPTER 14 N SESSIONS, USERS, AND REGISTRATION 275
Just like users, permissions are implemented in a Django model that lives in `f]jck*
_kjpne^*]qpd*ik`aho. This means that you can use Django’s database API to interact directly
with permissions if you like.
Groups
Groups are a generic way of categorizing users so you can apply permissions, or some other
label, to those users. A user can belong to any number of groups.
A user in a group automatically has the permissions granted to that group. For example,
if the group Oepaa`epkno has the permission _]j[a`ep[dkia[l]ca, any user in that group will
have that permission.
Groups are also a convenient way to categorize users to give them some label, or extended
functionality. For example, you could create a group #Ola_e]hqoano#, and you could write
code that could, say, give those users access to a members-only portion of your site, or send
them members-only e-mail messages.
Like users, the easiest way to manage groups is through the admin interface. However,
groups are also just Django models that live in `f]jck*_kjpne^*]qpd*ik`aho, so once again you
can always use Django’s database APIs to deal with groups at a low level.
Messages
The message system is a lightweight way to queue messages for given users. A message is asso-
ciated with a Qoan. There’s no concept of expiration or timestamps.
iÃÃ>}iÃÊ>ÀiÊÕÃi`ÊLÞÊÌiÊ>}Ê>`ÊÌiÀv>ViÊ>vÌiÀÊÃÕVViÃÃvÕÊ>VÌðÊÀÊiÝ>«i]Ê
when you create an object, you’ll notice a “The object was created successfully” message at the
top of the admin page.
You can use the same API to queue and display messages in your own application. The
API is simple:
Ê UÊ /ÊVÀi>ÌiÊ>ÊiÜÊiÃÃ>}i]ÊÕÃiÊqoan*iaoo]ca[oap*_na]pa$iaoo]ca9#iaoo]ca[patp#%.
Ê UÊ /ÊÀiÌÀiÛiÉ`iiÌiÊiÃÃ>}iÃ]ÊÕÃiÊqoan*cap[]j`[`ahapa[iaoo]cao$%, which returns a list
of Iaoo]ca objects in the user’s queue (if any) and deletes the messages from the queue.
In this example view, the system saves a message for the user after creating a playlist:
`ab_na]pa[lh]uheop$namqaop(okjco%6
?na]papdalh]uheopsepdpdacerajokjco*
***
namqaop*qoan*iaoo]ca[oap*_na]pa$
iaoo]ca9Ukqnlh]uheops]o]``a`oq__aoobqhhu*
%
napqnjnaj`an[pk[naolkjoa$lh]uheopo+_na]pa*dpih(
_kjpatp[ejop]j_a9Namqaop?kjpatp$namqaop%%
CHAPTER 14 N SESSIONS, USERS, AND REGISTRATION
276
When you use Namqaop?kjpatp, the current logged-in user and his or her messages are
made available in the template context as the template variable wwiaoo]caoyy. Here’s an
example of template code that displays messages:
w!ebiaoo]cao!y
8qh:
w!bkniaoo]caejiaoo]cao!y
8he:wwiaoo]cayy8+he:
w!aj`bkn!y
8+qh:
w!aj`eb!y
Note that Namqaop?kjpatp calls cap[]j`[`ahapa[iaoo]cao behind the scenes, so any mes-
sages will be deleted even if you don’t display them.
Finally, note that this messages framework only works with users in the user database.
To send messages to anonymous users, use the session framework directly.
What’s Next?
/iÊÃiÃÃÊ>`Ê>ÕÌÀâ>ÌÊÃÞÃÌiÊÃÊ>ÊÌÊÌÊ>LÃÀL°ÊÃÌÊvÊÌiÊÌi]ÊÞÕÊÜ½ÌÊii`Ê
all the features described in this chapter, but when you need to allow complex interactions
between users, it’s good to have all that power available.
In the next chapter, we’ll take a look at Django’s caching infrastructure, which is a conve-
nient way to improve the performance of your application.
CHAPTER 15
Caching
A fundamental trade-off in dynamic Web sites is, well, they’re dynamic. Each time a user
requests a page, the Web server makes all sorts of calculations—from database queries to tem-
plate rendering to business logic—to create the page that your site’s visitor sees. This is a lot
more expensive, from a processing-overhead perspective, than your standard read-a-file-off-
the-filesystem-server arrangement.
For most Web applications, this overhead isn’t a big deal. Most Web applications aren’t
washingtonpost.com or slashdot.org; they’re simply small- to medium-sized sites with so-so
traffic. But for medium- to high-traffic sites, it’s essential to cut as much overhead as possible.
That’s where caching comes in.
To cache something is to save the result of an expensive calculation so that you don’t have
to perform the calculation next time. Here’s some pseudocode explaining how this would
work for a dynamically generated Web page:
ceraj]QNH(pnubej`ejcpd]pl]caejpda_]_da
ebpdal]caeoejpda_]_da6
napqnjpda_]_da`l]ca
ahoa6
cajan]papdal]ca
o]rapdacajan]pa`l]caejpda_]_da$bknjatppeia%
napqnjpdacajan]pa`l]ca
Django comes with a robust cache system that lets you save dynamic pages so they don’t
have to be calculated for each request. For convenience, Django offers different levels of cache
granularity: you can cache the output of specific views, you can cache only the pieces that are
difficult to produce, or you can cache your entire site.
Django also works well with “upstream” caches, such as Squid (dppl6++sss*omqe`)_]_da*
knc+) and browser-based caches. These are the types of caches that you don’t directly control
but to which you can provide hints (via HTTP headers) about which parts of your site should
be cached, and how.
277
CHAPTER 15 N CACHING
278
Setting Up the Cache
The cache system requires a small amount of setup. Namely, you have to tell it where your
cached data should live—whether in a database, on the filesystem, or directly in memory.
This is an important decision that affects your cache’s performance; yes, some cache types are
faster than others.
Your cache preference goes in the ?=?DA[>=?GAJ@ setting in your settings file. Here’s an
explanation of all available values for ?=?DA[>=?GAJ@.
Memcached
By far the fastest, most efficient type of cache available to Django, Memcached is an entirely
memory-based cache framework originally developed to handle high loads at LiveJournal.com
and subsequently open-sourced by Danga Interactive. It’s used by sites such as Facebook and
Wikipedia to reduce database access and dramatically increase site performance.
Memcached is available for free at dppl6++`]jc]*_ki+iai_]_da`+. It runs as a daemon and
is allotted a specified amount of RAM. All it does is provide a fast interface for adding, retriev-
ing, and deleting arbitrary data in the cache. All data is stored directly in memory, so there’s no
overhead of database or filesystem usage.
After installing Memcached itself, you’ll need to install the Memcached Python bindings,
which are not bundled with Django directly. Two versions are available. Choose and install one
of the following modules:
Ê UÊ /iÊv>ÃÌiÃÌÊ>Û>>LiÊ«ÌÊÃÊ>Ê`ÕiÊV>i`Ê_iai_]_da, available at dppl6++cefo^anp*
knc+_iai_]_da+.
Ê UÊ vÊÞÕÊV>½ÌÊÃÌ>Ê_iai_]_da, you can install lupdkj)iai_]_da`, available at bpl6++bpl*
pqiiu*_ki+lq^+lupdkj)iai_]_da`+. If that URL is no longer valid, just go to the Mem-
cached Web site (dppl6++sss*`]jc]*_ki+iai_]_da`+) and get the Python bindings from
the “Client APIs” section.
To use Memcached with Django, set ?=?DA[>=?GAJ@ to iai_]_da`6++el6lknp+, where el
is the IP address of the Memcached daemon and lknp is the port on which Memcached is
running.
In this example, Memcached is running on localhost (127.0.0.1) port 11211:
?=?DA[>=?GAJ@9#iai_]_da`6++-.3*,*,*-6--.--+#
One excellent feature of Memcached is its ability to share cache over multiple servers.
This means you can run Memcached daemons on multiple machines, and the program will
treat the group of machines as a single cache, without the need to duplicate cache values on
each machine. To take advantage of this feature, include all server addresses in ?=?DA[>=?GAJ@,
separated by semicolons.
In this example, the cache is shared over Memcached instances running on IP addresses
172.19.26.240 and 172.19.26.242, both on port 11211:
?=?DA[>=?GAJ@9#iai_]_da`6++-3.*-5*.2*.0,6--.--7-3.*-5*.2*.0.6--.--+#
In the following example, the cache is shared over Memcached instances running on the
IP addresses 172.19.26.240 (port 11211), 172.19.26.242 (port 11212), and 172.19.26.244 (port
11213):
CHAPTER 15 N CACHING 279
?=?DA[>=?GAJ@9#iai_]_da`6++£
-3.*-5*.2*.0,6--.--7-3.*-5*.2*.0.6--.-.7-3.*-5*.2*.006--.-/+#
A final point about Memcached is that memory-based caching has one disadvantage:
because the cached data is stored in memory, the data will be lost if your server crashes.
Clearly, memory isn’t intended for permanent data storage, so don’t rely on memory-based
caching as your only data storage. Without a doubt, none of the Django caching back-ends
should be used for permanent storage—they’re all intended to be solutions for caching, not
storage—but we point this out here because memory-based caching is particularly temporary.
Database Caching
To use a database table as your cache back-end, first create a cache table in your database by
running this command where W_]_da[p]^ha[j]iaY is the name of the database table to create:
lupdkji]j]ca*lu_na]pa_]_dap]^haW_]_da[p]^ha[j]iaY
This name can be whatever you want, as long as it’s a valid table name that’s not already being
used in your database. This command creates a single table in your database that is in the
proper format that Django’s database-cache system expects.
Once you’ve created that database table, set your ?=?DA[>=?GAJ@ setting to `^6++
p]^haj]ia, where p]^haj]ia is the name of the database table. In this example, the cache
table’s name is iu[_]_da[p]^ha:
?=?DA[>=?GAJ@9#`^6++iu[_]_da[p]^ha#
The database caching back-end uses the same database as specified in your settings file.
You can’t use a different database back-end for your cache table.
Database caching works best if you have a fast, well-indexed database server.
Filesystem Caching
To store cached items on a filesystem, use the beha6++ cache type for ?=?DA[>=?GAJ@. For
example, to store cached data in +r]n+pil+`f]jck[_]_da, use this setting:
?=?DA[>=?GAJ@9#beha6+++r]n+pil+`f]jck[_]_da#
Note that there are three forward slashes toward the beginning of that example. The first
two are for beha6++, and the third is the first character of the directory path, +r]n+pil+`f]jck[
_]_da. If you’re on Windows, put the drive letter after the beha6++, like this:
beha6++_6+bkk+^]n
The directory path should be absolute—that is, it should start at the root of your filesys-
tem. It doesn’t matter whether you put a slash at the end of the setting.
Make sure the directory pointed to by this setting exists and is readable and writable by
the system user under which your Web server runs. Continuing the preceding example, if your
server runs as the user ]l]_da, make sure the directory +r]n+pil+`f]jck[_]_da exists and is
readable and writable by the user ]l]_da.
Each cache value will be stored as a separate file whose contents are the cache data saved
in a serialized (“pickled”) format, using Python’s le_gha module. Each file’s name is the cache
key, escaped for safe filesystem use.
CHAPTER 15 N CACHING
280
Local-Memory Caching
If you want the speed advantages of in-memory caching but don’t have the capability of run-
ning Memcached, consider the local-memory cache back-end. This cache is multi-process and
thread-safe. To use it, set ?=?DA[>=?GAJ@ to hk_iai6+++. For example:
?=?DA[>=?GAJ@9#hk_iai6+++#
Note that each process will have its own private cache instance, which means no cross-
process caching is possible. This obviously also means the local memory cache isn’t particu-
larly memory efficient, so it’s probably not a good choice for production environments. It’s
nice for development.
Dummy Caching (for Development)
Finally, Django comes with a “dummy” cache that doesn’t actually cache; it just implements
the cache interface without doing anything.
This is useful if you have a production site that uses heavy-duty caching in various places
but a development/test environment in which you don’t want to cache and don’t want to have
to change your code to special-case the latter. To activate dummy caching, set ?=?DA[>=?GAJ@
like so:
?=?DA[>=?GAJ@9#`qiiu6+++#
Using a Custom Cache Back-End
Although Django includes support for a number of cache back-ends out of the box, sometimes
you might want to use a customized cache back-end. To use an external cache back-end with
Django, use a Python import path as the scheme portion (the part before the initial colon) of
the ?=?DA[>=?GAJ@ URI, like so:
?=?DA[>=?GAJ@9#l]pd*pk*^]_gaj`6++#
If you’re building your own back-end, you can use the standard cache back-ends as refer-
ence implementations. You’ll find the code in the `f]jck+_kna+_]_da+^]_gaj`o+ directory of
the Django source.
NNote Without a really compelling reason (for example, a host that doesn’t support back-ends), you should
stick to the cache back-ends included with Django. They’ve been well-tested and are easy to use.
CHAPTER 15 N CACHING 281
CACHE_BACKEND Arguments
Each cache back-end may take arguments. They’re given in query-string style on the ?=?DA[
>=?GAJ@ setting. Valid arguments are as follows:
ÊUÊpeiakqp: The default timeout, in seconds, to use for the cache. This argument defaults
to 300 seconds (5 minutes).
ÊUÊi]t[ajpneao: For the hk_iai, behaouopai, and `]p]^]oa back-ends, the maximum
number of entries allowed in the cache before old values are deleted. This argument
defaults to 300.
ÊUÊ_qhh[lan_ajp]ca: The percentage of entries that are culled when i]t[ajpneao is
reached. The actual ratio is -+_qhh[lan_ajp]ca, so set _qhh[lan_ajp]ca9. to cull half of
the entries when i]t[ajpneao is reached.
A value of , for _qhh[lan_ajp]ca means that the entire cache will be dumped when
i]t[ajpneao is reached. This makes culling much faster at the expense of more cache
misses.
In this example, peiakqp is set to 2,:
?=?DA[>=?GAJ@9iai_]_da`6++-.3*,*,*-6--.--+;peiakqp92,
In this example, peiakqp is /, and i]t[ajpneao is 0,,:
?=?DA[>=?GAJ@9hk_iai6+++;peiakqp9/,"i]t[ajpneao90,,
Invalid arguments are silently ignored, as are invalid values of known arguments.
The Per-Site Cache
After the cache is set up, the simplest way to use caching is to cache your entire site. You’ll
need to add #`f]jck*ie``has]na*_]_da*Ql`]pa?]_daIe``has]na# and #`f]jck*ie``has]na*
_]_da*Bap_dBnki?]_daIe``has]na# to your IE@@HAS=NA[?H=OOAO setting, as in this example:
IE@@HAS=NA[?H=OOAO9$
#`f]jck*ie``has]na*_]_da*Ql`]pa?]_daIe``has]na#(
#`f]jck*ie``has]na*_kiikj*?kiikjIe``has]na#(
#`f]jck*ie``has]na*_]_da*Bap_dBnki?]_daIe``has]na#(
%
NNote No, that’s not a typo: the “update” middleware must be first in the list, and the “fetch” middleware
must be last. The details are a bit obscure, but see “Order of MIDDLEWARE_CLASSES,” at the end of the
chapter, if you want the full story.
CHAPTER 15 N CACHING
282
Then, add the following required settings to your Django settings file:
ÊUÊ?=?DA[IE@@HAS=NA[OA?KJ@O: The number of seconds each page should be cached.
ÊUÊ?=?DA[IE@@HAS=NA[GAU[LNABET: If the cache is shared across multiple sites using the same
Django installation, set this to the name of the site, or some other string that is unique to
this Django instance, to prevent key collisions. Use an empty string if you don’t care.
The cache middleware caches every page that doesn’t have CAP or LKOP parameters.
Optionally, if the ?=?DA[IE@@HAS=NA[=JKJUIKQO[KJHU setting is Pnqa, only anonymous requests
(i.e., not those made by a logged-in user) will be cached. This is a simple and effective way of
disabling caching for any user-specific pages (include Django’s admin interface). Note that
if you use ?=?DA[IE@@HAS=NA[=JKJUIKQO[KJHU, you should make sure you’ve activated
=qpdajpe_]pekjIe``has]na.
Additionally, the cache middleware automatically sets a few headers in each
DpplNaolkjoa:
Ê UÊ -iÌÃÊÌiÊH]op)Ik`ebea` header to the current date/time when a fresh (uncached)
version of the page is requested.
Ê UÊ -iÌÃÊÌiÊAtlenao header to the current date/time plus the defined ?=?DA[IE@@HAS=NA[
OA?KJ@O.
Ê UÊ -iÌÃÊÌiÊ?]_da)?kjpnkh header to give a max age for the page—again, from the ?=?DA[
IE@@HAS=NA[OA?KJ@O setting.
NNote See Chapter 17 for more on middleware.
If a view sets its own cache expiry time (i.e., it has a i]t)]ca section in its ?]_da)?kjpnkh
header), the page will be cached until the expiry time instead of ?=?DA[IE@@HAS=NA[OA?KJ@O.
Using the decorators in `f]jck*reaso*`a_kn]pkno*_]_da, you can easily set a view’s expiry
time (using the _]_da[_kjpnkh decorator) or disable caching for a view (using the jaran[_]_da
decorator). See the following “Controlling Cache: Using Other Headers” section for more on
these decorators.
The Per-View Cache
A more granular way to use the caching framework is by caching the output of individual
views. `f]jck*reaso*`a_kn]pkno*_]_da defines a _]_da[l]ca decorator that will automatically
cache the view’s response for you. It’s easy to use:
bnki`f]jck*reaso*`a_kn]pkno*_]_daeilknp_]_da[l]ca
`abiu[reas$namqaop%6
***
iu[reas9_]_da[l]ca$iu[reas(2,&-1%
CHAPTER 15 N CACHING 283
Or, using Python 2.4’s decorator syntax:
<_]_da[l]ca$2,&-1%
`abiu[reas$namqaop%6
***
_]_da[l]ca takes a single argument: the cache timeout, in seconds. In the preceding
example, the result of the iu[reas$% view will be cached for 15 minutes. (Note that we’ve writ-
ten it as 2,&-1 for the purpose of readability. 2,&-1 will be evaluated to 5,,—that is, 15
minutes multiplied by 60 seconds per minute.)
The per-view cache, like the per-site cache, is keyed off of the URL. If multiple URLs point
at the same view, each URL will be cached separately. Continuing the iu[reas example, if your
URLconf looks like this:
qnhl]ppanjo9$##(
$n#Zbkk+$X`w-(.y%+ #(iu[reas%(
%
then requests to +bkk+-+ and +bkk+./+ will be cached separately, as you may expect. But once
a particular URL (e.g., +bkk+./+) has been requested, subsequent requests to that URL will use
the cache.
Specifying Per-View Cache in the URLconf
The examples in the previous section have hard-coded the fact that the view is cached,
because _]_da[l]ca alters the iu[reas function in place. This approach couples your view
to the cache system, which is not ideal for several reasons. For instance, you might want to
reuse the view functions on another, cache-less site, or you might want to distribute the views
to people who might want to use them without being cached. The solution to these prob-
lems is to specify the per-view cache in the URLconf rather than next to the view functions
themselves.
Doing so is easy: simply wrap the view function with _]_da[l]ca when you refer to it in the
URLconf. Here’s the old URLconf from earlier:
qnhl]ppanjo9$##(
$n#Zbkk+$X`w-(.y%+ #(iu[reas%(
%
Here’s the same thing, with iu[reas wrapped in _]_da[l]ca:
bnki`f]jck*reaso*`a_kn]pkno*_]_daeilknp_]_da[l]ca
qnhl]ppanjo9$##(
$n#Zbkk+$X`w-(.y%+ #(_]_da[l]ca$iu[reas(2,&-1%%(
%
If you take this approach, don’t forget to import _]_da[l]ca within your URLconf.
CHAPTER 15 N CACHING
284
Template Fragment Caching
If you’re after even more control, you can also cache template fragments using the _]_da tem-
plate tag. To give your template access to this tag, put w!hk]`_]_da!y near the top of your
template.
The w!_]_da!y template tag caches the contents of the block for a given amount of time.
It takes at least two arguments: the cache timeout in seconds and the name to give the cache
fragment. For example:
w!hk]`_]_da!y
w!_]_da1,,oe`a^]n!y
**oe`a^]n**
w!aj`_]_da!y
Sometimes you might want to cache multiple copies of a fragment, depending on some
dynamic data that appears inside the fragment. For example, you might want a separate cached
copy of the sidebar used in the previous example for every user of your site. Do this by passing
additional arguments to the w!_]_da!y template tag to uniquely identify the cache fragment:
w!hk]`_]_da!y
w!_]_da1,,oe`a^]nnamqaop*qoan*qoanj]ia!y
**oe`a^]nbknhkcca`ejqoan**
w!aj`_]_da!y
It’s perfectly fine to specify more than one argument to identify the fragment. Simply pass
as many arguments to w!_]_da!y as you need.
The cache timeout can be a template variable, as long as the template variable resolves to
an integer value. For example, if the template variable iu[peiakqp is set to the value 2,,, the
following two examples are equivalent:
w!_]_da2,,oe`a^]n!y***w!aj`_]_da!y
w!_]_daiu[peiakqpoe`a^]n!y***w!aj`_]_da!y
This feature is useful for avoiding repetition in templates. You can set the timeout in a
variable, in one place, and just reuse that value.
The Low-Level Cache API
Sometimes, caching an entire rendered page doesn’t gain you very much and is, in fact, incon-
venient overkill.
Perhaps, for instance, your site includes a view whose results depend on several expensive
queries, the results of which change at different intervals. In this case, it would not be ideal
to use the full-page caching that the per-site or per-view cache strategies offer, because you
wouldn’t want to cache the entire result (since some of the data changes often), but you’d still
want to cache the results that rarely change.
For cases like this, Django exposes a simple, low-level cache API. You can use this API
to store objects in the cache with any level of granularity you like. You can cache any Python
object that can be pickled safely: strings, dictionaries, lists of model objects, and so forth.
(Most common Python objects can be pickled; refer to the Python documentation for more
information about pickling.)
CHAPTER 15 N CACHING 285
The cache module, `f]jck*_kna*_]_da, has a _]_da object that’s automatically created
from the ?=?DA[>=?GAJ@ setting:
:::bnki`f]jck*_kna*_]_daeilknp_]_da
The basic interface is oap$gau(r]hqa(peiakqp[oa_kj`o% and cap$gau%:
:::_]_da*oap$#iu[gau#(#dahhk(sknh`#(/,%
:::_]_da*cap$#iu[gau#%
#dahhk(sknh`#
The peiakqp[oa_kj`o argument is optional and defaults to the peiakqp argument in the
?=?DA[>=?GAJ@ setting (explained earlier).
If the object doesn’t exist in the cache, _]_da*cap$% returns Jkja:
S]ep/,oa_kj`obkn#iu[gau#pkatlena***
:::_]_da*cap$#iu[gau#%
Jkja
We advise against storing the literal value Jkja in the cache, because you won’t be able
to distinguish between your stored Jkja value and a cache miss signified by a return value
of Jkja.
_]_da*cap$% can take a `ab]qhp argument. This specifies which value to return if the object
doesn’t exist in the cache:
:::_]_da*cap$#iu[gau#(#d]oatlena`#%
#d]oatlena`#
To add a key (only if it doesn’t already exist), use the ]``$% method. It takes the same
parameters as oap$%, but it will not attempt to update the cache if the key specified is already
present:
:::_]_da*oap$#]``[gau#(#Ejepe]hr]hqa#%
:::_]_da*]``$#]``[gau#(#Jasr]hqa#%
:::_]_da*cap$#]``[gau#%
#Ejepe]hr]hqa#
If you need to know whether ]``$% stored a value in the cache, you can check the return
value. It returns Pnqa if the value was stored; it returns B]hoa otherwise.
There’s also a cap[i]ju$% interface that hits the cache only once: cap[i]ju$% returns a dic-
tionary with all the keys you asked for that actually exist in the cache (and haven’t expired):
:::_]_da*oap$#]#(-%
:::_]_da*oap$#^#(.%
:::_]_da*oap$#_#(/%
:::_]_da*cap[i]ju$W#]#(#^#(#_#Y%
w#]#6-(#^#6.(#_#6/y
Finally, you can delete keys explicitly with `ahapa$%. This is an easy way of clearing the
cache for a particular object:
:::_]_da*`ahapa$#]#%
CHAPTER 15 N CACHING
286
You can also increment or decrement a key that already exists using the ej_n$% or `a_n$%
methods, respectively. By default, the existing cache value will be incremented or decre-
mented by 1. Other increment/decrement values can be specified by providing an argument
to the increment/decrement call. A R]hqaAnnkn will be raised if you attempt to increment or
decrement a nonexistent cache key:
:::_]_da*oap$#jqi#(-%
:::_]_da*ej_n$#jqi#%
.
:::_]_da*ej_n$#jqi#(-,%
-.
:::_]_da*`a_n$#jqi#%
--
:::_]_da*`a_n$#jqi#(1%
2
NNote ej_n$%/`a_n$% methods are not guaranteed to be atomic. On those back-ends that support atomic
increment/decrement (most notably, the Memcached back-end), increment and decrement operations will
be atomic. However, if the back-end doesn’t natively provide an increment/decrement operation, it will be
implemented using a two-step retrieve/update.
Upstream Caches
So far, this chapter has focused on caching your own data. But another type of caching is rel-
evant to Web development, too: caching performed by “upstream” caches. These are systems
that cache pages for users even before the request reaches your Web site.
Here are a few examples of upstream caches:
Ê UÊ 9ÕÀÊ-*Ê>ÞÊV>ViÊViÀÌ>Ê«>}iÃ]ÊÃÊvÊÞÕÊÀiµÕiÃÌi`Ê>Ê«>}iÊvÀÊdppl6++at]ilha*_ki+,
your ISP would send you the page without having to access example.com directly. The
maintainers of example.com have no knowledge of this caching; the ISP sits between
example.com and your Web browser, handling all of the caching transparently.
Ê UÊ 9ÕÀÊ>}Ê7iLÊÃÌiÊ>ÞÊÃÌÊLi`Ê>Êproxy cache, such as Squid Web Proxy Cache
(dppl6++sss*omqe`)_]_da*knc+), that caches pages for performance. In this case, each
request first would be handled by the proxy, and it would be passed to your application
only if needed.
Ê UÊ 9ÕÀÊ7iLÊLÀÜÃiÀÊV>ViÃÊ«>}iÃ]ÊÌ°ÊvÊ>Ê7iLÊ«>}iÊÃi`ÃÊÕÌÊÌiÊ>««À«À>ÌiÊi>`iÀÃ]Ê
your browser will use the local cached copy for subsequent requests to that page, with-
out even contacting the Web page again to see whether it has changed.
CHAPTER 15 N CACHING 287
Upstream caching is a nice efficiency boost, but there’s a danger to it: many Web pages’
contents differ based on authentication and a host of other variables, and cache systems that
blindly save pages based purely on URLs could expose incorrect or sensitive data to subse-
quent visitors to those pages.
For example, say you operate a Web e-mail system, and the contents of the “inbox” page
obviously depend on which user is logged in. If an ISP blindly cached your site, then the first
user who logged in through that ISP would have his user-specific inbox page cached for subse-
quent visitors to the site. That’s not cool.
Fortunately, HTTP provides a solution to this problem. A number of HTTP headers exist
to instruct upstream caches to differ their cache contents depending on designated variables,
and to tell caching mechanisms not to cache particular pages. We’ll look at some of these
headers in the sections that follow.
Using Vary Headers
The R]nu header defines which request headers a cache mechanism should take into account
when building its cache key. For example, if the contents of a Web page depend on a user’s
language preference, the page is said to “vary on language.”
By default, Django’s cache system creates its cache keys using the requested path (e.g.,
+opkneao+.,,1+fqj+./+^]jg[nk^^a`+). This means every request to that URL will use the
same cached version, regardless of user-agent differences such as cookies or language prefer-
ences. However, if this page produces different content based on some difference in request
headers—such as a cookie, or a language, or a user-agent—you’ll need to use the R]nu header
to tell caching mechanisms that the page output depends on those things.
To do this in Django, use the convenient r]nu[kj[da]`ano view decorator, like so:
bnki`f]jck*reaso*`a_kn]pkno*r]nueilknpr]nu[kj[da]`ano
Lupdkj.*/oujp]t*
`abiu[reas$namqaop%6
***
iu[reas9r]nu[kj[da]`ano$iu[reas(#Qoan)=cajp#%
Lupdkj.*0'`a_kn]pknoujp]t*
<r]nu[kj[da]`ano$#Qoan)=cajp#%
`abiu[reas$namqaop%6
***
In this case, a caching mechanism (such as Django’s own cache middleware) will cache a
separate version of the page for each unique user-agent.
The advantage to using the r]nu[kj[da]`ano decorator rather than manually setting the
R]nu header (using something like naolkjoaW#R]nu#Y9#qoan)]cajp#) is that the decorator
adds to the R]nu header (which may already exist), rather than setting it from scratch and
potentially overriding anything that was already in there.
CHAPTER 15 N CACHING
288
You can pass multiple headers to r]nu[kj[da]`ano$%:
<r]nu[kj[da]`ano$#Qoan)=cajp#(#?kkgea#%
`abiu[reas$namqaop%6
***
This tells upstream caches to vary on both, which means each combination of user-agent
and cookie will get its own cache value. For example, a request with the user-agent Ikvehh]
and the cookie value bkk9^]n will be considered different from a request with the user-agent
Ikvehh] and the cookie value bkk9d]i.
Because varying on cookie is so common, there’s a r]nu[kj[_kkgea decorator. These two
views are equivalent:
<r]nu[kj[_kkgea
`abiu[reas$namqaop%6
***
<r]nu[kj[da]`ano$#?kkgea#%
`abiu[reas$namqaop%6
***
The headers you pass to r]nu[kj[da]`ano are not case sensitive; Qoan)=cajp is the same
thing as qoan)]cajp.
You can also use a helper function, `f]jck*qpeho*_]_da*l]p_d[r]nu[da]`ano, directly.
This function sets, or adds to, the R]nu header. For example:
bnki`f]jck*qpeho*_]_daeilknpl]p_d[r]nu[da]`ano
`abiu[reas$namqaop%6
***
naolkjoa9naj`an[pk[naolkjoa$#pailh]pa[j]ia#(_kjpatp%
l]p_d[r]nu[da]`ano$naolkjoa(W#?kkgea#Y%
napqnjnaolkjoa
l]p_d[r]nu[da]`ano takes an DpplNaolkjoa instance as its first argument and a list/tuple of
case-insensitive header names as its second argument.
Controlling Cache: Using Other Headers
Other problems with caching are the privacy of data and the question of where data should be
stored in a cascade of caches.
A user usually faces two kinds of caches: his or her own browser cache (a private cache)
and his or her provider’s cache (a public cache). A public cache is used by multiple users and
controlled by someone else. This poses problems with sensitive data—you don’t want, say,
your bank account number stored in a public cache. So Web applications need a way to tell
caches which data is private and which is public.
The solution is to indicate a page’s cache should be “private.” To do this in Django, use
the _]_da[_kjpnkh view decorator. Here’s an example:
CHAPTER 15 N CACHING 289
bnki`f]jck*reaso*`a_kn]pkno*_]_daeilknp_]_da[_kjpnkh
<_]_da[_kjpnkh$lner]pa9Pnqa%
`abiu[reas$namqaop%6
***
This decorator takes care of sending out the appropriate HTTP header behind the scenes.
There are a few other ways to control cache parameters. For example, HTTP allows appli-
cations to do the following:
Ê UÊ iviÊÌiÊ>ÝÕÊÌiÊ>Ê«>}iÊÃÕ`ÊLiÊV>Vi`°
Ê UÊ -«iVvÞÊÜiÌiÀÊ>ÊV>ViÊÃÕ`Ê>Ü>ÞÃÊViVÊvÀÊiÜiÀÊÛiÀÃÃ]ÊÞÊ`iÛiÀ}ÊÌiÊ
cached content when there are no changes. (Some caches might deliver cached con-
tent even if the server page changes, simply because the cache copy isn’t yet expired.)
In Django, use the _]_da[_kjpnkh view decorator to specify these cache parameters. In
this example, _]_da[_kjpnkh tells caches to revalidate the cache on every access and to store
cached versions for, at most, 3,600 seconds:
bnki`f]jck*reaso*`a_kn]pkno*_]_daeilknp_]_da[_kjpnkh
<_]_da[_kjpnkh$iqop[nar]he`]pa9Pnqa(i]t[]ca9/2,,%
`abiu[reas$namqaop%6
***
Any valid ?]_da)?kjpnkh HTTP directive is valid in _]_da[_kjpnkh$%. Here’s a full list:
ÊUÊlq^he_9Pnqa
ÊUÊlner]pa9Pnqa
ÊUÊjk[_]_da9Pnqa
ÊUÊjk[pn]jobkni9Pnqa
ÊUÊiqop[nar]he`]pa9Pnqa
ÊUÊlnktu[nar]he`]pa9Pnqa
ÊUÊi]t[]ca9jqi[oa_kj`o
ÊUÊo[i]t]ca9jqi[oa_kj`o
(Note that the caching middleware already sets the cache header’s i]t)]ca with the value
of the ?=?DA[IE@@HAS=NA[OAPPEJCO setting. If you use a custom i]t[]ca in a _]_da[_kjpnkh deco-
rator, the decorator will take precedence, and the header values will be merged correctly.)
If you want to use headers to disable caching altogether, `f]jck*reaso*`a_kn]pkno*_]_da*
jaran[_]_da is a view decorator that adds headers to ensure that the response won’t be cached
by browsers or other caches. For example:
bnki`f]jck*reaso*`a_kn]pkno*_]_daeilknpjaran[_]_da
<jaran[_]_da
`abiureas$namqaop%6
***
CHAPTER 15 N CACHING
290
Other Optimizations
Django comes with a few other pieces of middleware that can help optimize your apps’
performance:
ÊUÊ`f]jck*ie``has]na*dppl*?kj`epekj]hCapIe``has]na adds support for modern
browsers to conditionally CAP responses based on the AP]c and H]op)Ik`ebea`
headers.
ÊUÊ`f]jck*ie``has]na*cvel*CVelIe``has]na compresses responses for all modern
browsers, saving bandwidth and transfer time.
Order of MIDDLEWARE_CLASSES
If you use caching middleware, it’s important to put each half in the right place within the
IE@@HAS=NA[?H=OOAO setting. That’s because the cache middleware needs to know which head-
ers should be used to vary the cache storage. Middleware always adds something to the R]nu
response header when it can.
Ql`]pa?]_daIe``has]na runs during the response phase (in which middleware is run in
reverse order), so an item at the top of the list runs last during the response phase. Thus, you
need to make sure that Ql`]pa?]_daIe``has]na appears before any other middleware that
might add something to the R]nu header. The following middleware modules do so:
ÊUÊOaooekjIe``has]na adds ?kkgea
ÊUÊCVelIe``has]na adds =__alp)Aj_k`ejc
ÊUÊHk_]haIe``has]na adds =__alp)H]jcq]ca
On the other hand, Bap_dBnki?]_daIe``has]na runs during the request phase, during
which middleware is applied first to last, so an item at the top of the list runs first during
the request phase. The Bap_dBnki?]_daIe``has]na also needs to run after other middleware
updates the R]nu header, so Bap_dBnki?]_daIe``has]na must be after any item that does so.
What’s Next?
Django ships with a number of “contrib” packages—optional features that can make your life
easier. We’ve already covered a few of these: the admin site (discussed in Chapter 6) and the
session/user framework (refer to Chapter 14). The next chapter covers more of the “contrib-
uted” subframeworks.
CHAPTER 16
django.contrib
One of the many strengths of Python is its “batteries included” philosophy: when you install
Python, it comes with a large standard library of packages that you can start using immedi-
ately, without having to download anything else. Django aims to follow this philosophy, and it
includes its own standard library of add-ons useful for common Web-development tasks. This
chapter covers that collection of add-ons.
The Django Standard Library
Django’s standard library lives in the package `f]jck*_kjpne^. Within each subpackage is a
separate piece of add-on functionality. These pieces are not necessarily related, but some
`f]jck*_kjpne^ subpackages may require other ones.
There’s no hard requirement for the types of functionality in `f]jck*_kjpne^. Some of
the packages include models (and hence require you to install their database tables into your
database), but others consist solely of middleware or template tags.
The single characteristic the `f]jck*_kjpne^ packages have in common is this: if you were
to remove the `f]jck*_kjpne^ package entirely, you could still use Django’s fundamental fea-
tures with no problems. When the Django developers add new functionality to the framework,
they use this rule of thumb in deciding whether the new functionality should live in `f]jck*
_kjpne^ or elsewhere.
`f]jck*_kjpne^ consists of these packages:
ÊUÊ]`iej: The Django admin site. See Chapter 6.
ÊUÊ]`iej`k_o: autodocumentation for the Django admin site. This book doesn’t cover this
feature; check the official Django documentation.
ÊUÊ]qpd: Django’s authentication framework. See Chapter 14.
ÊUÊ_kiiajpo: A comments application. This book doesn’t cover this feature; check the
official Django documentation.
291
CHAPTER 16 N DJANGO.CONTRIB
292
ÊUÊ_kjpajppulao: A framework for hooking into “types” of content, where each installed
Django model is a separate content type. This framework is used internally by other
“contrib” applications and is mostly intended for very advanced Django developers.
Those developers should find out more about this application by reading the source
code in `f]jck+_kjpne^+_kjpajppulao.
ÊUÊ_onb: Protection against cross-site request forgery (CSRF). See the later section titled
“CSRF Protection.”
ÊUÊ`]p]^nksoa: A Django application that lets you browse your data. This book doesn’t
cover this feature; check the official Django documentation.
ÊUÊbh]pl]cao: A framework for managing simple “flat” HTML content in a database.
See the later section titled “Flatpages.”
ÊUÊbknipkkho: A number of useful higher-level libraries for dealing with common patterns
in forms. This book doesn’t cover this feature; check the official Django documentation.
ÊUÊceo: Extensions to Django that provide for GIS (Geographic Information Systems)
support. These, for example, allow your Django models to store geographic data and
perform geographic queries. This is a large, complex library and isn’t covered in this
book. See dppl6++cak`f]jck*knc+ for documentation.
ÊUÊdqi]jeva: A set of Django template filters useful for adding a “human touch” to data.
See the later section titled “Humanizing Data.”
ÊUÊhk_]hbh]rkn: Assorted pieces of code that are useful for particular countries or cultures.
For example, this includes ways to validate US ZIP codes or Icelandic personal identifi-
cation numbers.
ÊUÊi]ngql: A set of Django template filters that implement a number of common markup
languages. See the later section titled “Markup Filters.”
ÊUÊna`ena_po: A framework for managing redirects. See the later section titled “Redirects.”
ÊUÊoaooekjo: Django’s session framework. See Chapter 14.
ÊUÊoepai]lo: A framework for generating sitemap XML files. See Chapter 13.
ÊUÊoepao: A framework that lets you operate multiple Web sites from the same database
and Django installation. See the next section, “Sites.”
ÊUÊouj`e_]pekj: A framework for generating syndication feeds in RSS and Atom. See
Chapter 13.
ÊUÊsa^`aoecj: Django add-ons that are particularly useful to Web designers (as opposed
to developers). As of this writing, this includes only a single template tag, w!hknai!y.
Check the Django documentation for more information.
The rest of this chapter goes into detail about a number of `f]jck*_kjpne^ packages that
we haven’t yet covered in this book.
CHAPTER 16 N DJANGO.CONTRIB 293
Sites
Django’s sites system is a generic framework that lets you operate multiple Web sites from the
same database and Django project. This is an abstract concept, and it can be tricky to under-
stand, so we’ll start with a couple of scenarios where it would be useful.
Scenario 1: Reusing Data on Multiple Sites
As we explained in Chapter 1, the Django-powered sites LJWorld.com and Lawrence.com
are operated by the same news organization: the Lawrence Journal-World newspaper in
Lawrence, Kansas. LJWorld.com focuses on news, while Lawrence.com focuses on local enter-
tainment. But sometimes editors want to publish an article on both sites.
The brain-dead way of solving the problem would be to use a separate database for each
site and to require site producers to publish the same story twice: once for LJWorld.com and
again for Lawrence.com. But that’s inefficient for site producers, and it’s redundant to store
multiple copies of the same story in the database.
The better solution? Both sites use the same article database, and an article is associated
with one or more sites via a many-to-many relationship. The Django sites framework provides
the database table to which articles can be related. It’s a hook for associating data with one or
more “sites.”
Scenario 2: Storing Your Site Name/Domain in One Place
LJWorld.com and Lawrence.com both have e-mail alert functionality, which lets readers sign
up to get notifications when news happens. It’s pretty basic: a reader signs up on a Web form,
and immediately gets an e-mail saying, “Thanks for your subscription.”
It would be inefficient and redundant to implement this signup-processing code twice,
so the sites use the same code behind the scenes. But the “Thank you for your subscription”
notice needs to be different for each site. By using Oepa objects, we can abstract the thank-
you notice to use the values of the current site’s j]ia (e.g., HFSknh`*_ki) and `ki]ej
(e.g., sss*hfsknh`*_ki).
The Django sites framework provides a place for you to store the j]ia and `ki]ej for each
site in your Django project, which means you can reuse those values in a generic way.
How to Use the Sites Framework
The sites framework is more a series of conventions than a framework. The whole thing is
based on two simple concepts:
Ê UÊ /iÊOepa model, found in `f]jck*_kjpne^*oepao, has `ki]ej and j]ia fields.
Ê UÊ /iÊOEPA[E@ setting specifies the database ID of the Oepa object associated with that
particular settings file.
How you use these two concepts is up to you, but Django uses them in a couple of ways
automatically via simple conventions.
CHAPTER 16 N DJANGO.CONTRIB
294
To install the sites application, follow these steps:
1. Add #`f]jck*_kjpne^*oepao# to your EJOP=HHA@[=LLO.
2. Run the command i]j]ca*luouj_`^ to install the `f]jck[oepa table into your data-
base. This will also create a default site object, with the domain at]ilha*_ki.
3. Change the at]ilha*_ki site to your own domain, and add any other Oepa objects,
either through the Django admin site or via the Python API. Create a Oepa object for each
site/domain that this Django project powers.
4. Define the OEPA[E@ setting in each of your settings files. This value should be the data-
base ID of the Oepa object for the site powered by that settings file.
The Sites Framework’s Capabilities
The sections that follow describe the various things you can do with the sites framework.
Reusing Data on Multiple Sites
To reuse data on multiple sites, as explained in the first scenario, just create a I]juPkI]juBeah`
to Oepa in your models, as in this example:
bnki`f]jck*`^eilknpik`aho
bnki`f]jck*_kjpne^*oepao*ik`ahoeilknpOepa
_h]oo=npe_ha$ik`aho*Ik`ah%6
da]`heja9ik`aho*?d]nBeah`$i]t[hajcpd9.,,%
***
oepao9ik`aho*I]juPkI]juBeah`$Oepa%
That’s the infrastructure you need to associate articles with multiple sites in your
database. With that in place, you can reuse the same Django view code for multiple sites.
Continuing the =npe_ha model example, here’s what an ]npe_ha[`ap]eh view might look like:
bnki`f]jck*_kjbeilknpoappejco
bnki`f]jck*odknp_qpoeilknpcap[k^fa_p[kn[0,0
bnkiiuoepa*]npe_hao*ik`ahoeilknp=npe_ha
`ab]npe_ha[`ap]eh$namqaop(]npe_ha[e`%6
]9cap[k^fa_p[kn[0,0$=npe_ha(e`9]npe_ha[e`(oepao[[e`9oappejco*OEPA[E@%
***
This view function is reusable because it checks the article’s site dynamically, according to
the value of the OEPA[E@ setting.
For example, say LJWorld.com’s settings file has a OEPA[E@ set to -, and Lawrence.
com’s settings file has a OEPA[E@ set to .. If this view is called when LJWorld.com’s settings
file is active, then it will limit the article lookup to articles in which the list of sites includes
LJWorld.com.
CHAPTER 16 N DJANGO.CONTRIB 295
Associating Content with a Single Site
Similarly, you can associate a model to the Oepa model in a many-to-one relationship using
BknaecjGau.
For example, if each article is associated with only a single site, you could use a model
like this:
bnki`f]jck*`^eilknpik`aho
bnki`f]jck*_kjpne^*oepao*ik`ahoeilknpOepa
_h]oo=npe_ha$ik`aho*Ik`ah%6
da]`heja9ik`aho*?d]nBeah`$i]t[hajcpd9.,,%
***
oepa9ik`aho*BknaecjGau$Oepa%
This has the same benefits as described in the preceding section.
Hooking into the Current Site from Views
On a lower level, you can use the sites framework in your Django views to do particular things
based on the site in which the view is being called, as in this example:
bnki`f]jck*_kjbeilknpoappejco
`abiu[reas$namqaop%6
eboappejco*OEPA[E@99/6
@kokiapdejc*
ahoa6
@kokiapdejcahoa*
Of course, it’s ugly to hard-code the site IDs like that. A slightly cleaner way of accom-
plishing the same thing is to check the current site’s domain:
bnki`f]jck*_kjbeilknpoappejco
bnki`f]jck*_kjpne^*oepao*ik`ahoeilknpOepa
`abiu[reas$namqaop%6
_qnnajp[oepa9Oepa*k^fa_po*cap$e`9oappejco*OEPA[E@%
eb_qnnajp[oepa*`ki]ej99#bkk*_ki#6
@kokiapdejc
ahoa6
@kokiapdejcahoa*
The idiom of retrieving the Oepa object for the value of oappejco*OEPA[E@ is quite common,
so the Oepa model’s manager (Oepa*k^fa_po) has a cap[_qnnajp$% method. This example is
equivalent to the previous one:
CHAPTER 16 N DJANGO.CONTRIB
296
bnki`f]jck*_kjpne^*oepao*ik`ahoeilknpOepa
`abiu[reas$namqaop%6
_qnnajp[oepa9Oepa*k^fa_po*cap[_qnnajp$%
eb_qnnajp[oepa*`ki]ej99#bkk*_ki#6
@kokiapdejc
ahoa6
@kokiapdejcahoa*
NNote In this final example, you don’t have to import `f]jck*_kjb*oappejco.
Getting the Current Domain for Display
For a DRY (Don’t Repeat Yourself) approach to storing your site’s name and domain name,
as explained in “Scenario 2: Storing Your Site Name/Domain in One Place,” just reference the
j]ia and `ki]ej of the current Oepa object. Here’s an example:
bnki`f]jck*_kjpne^*oepao*ik`ahoeilknpOepa
bnki`f]jck*_kna*i]eheilknpoaj`[i]eh
`abnaceopan[bkn[jasohappan$namqaop%6
?da_gbknir]hqao(ap_*(]j`oq^o_ne^apdaqoan*
***
_qnnajp[oepa9Oepa*k^fa_po*cap[_qnnajp$%
oaj`[i]eh$#Pd]jgobknoq^o_ne^ejcpk!o]hanpo#!_qnnajp[oepa*j]ia(
#Pd]jgobknukqnoq^o_nelpekj*Sa]llna_e]paep*XjXj)Pda!opa]i*#!X
_qnnajp[oepa*j]ia(
#a`epkn<!o#!_qnnajp[oepa*`ki]ej(
Wqoan[ai]ehY%
***
Continuing our ongoing example of LJWorld.com and Lawrence.com, on Lawrence.com
this e-mail has the subject line “Thanks for subscribing to Lawrence.com alerts.” On LJWorld.
com, the e-mail has the subject line “Thanks for subscribing to LJWorld.com alerts.” This same
site-specific behavior is applied to the e-mails’ message body.
An even more flexible (but more heavyweight) way of doing this would be to use Django’s
template system. Assuming Lawrence.com and LJWorld.com have different template directo-
ries (PAILH=PA[@ENO), you could simply delegate to the template system like so:
CHAPTER 16 N DJANGO.CONTRIB 297
bnki`f]jck*_kna*i]eheilknpoaj`[i]eh
bnki`f]jck*pailh]paeilknphk]`an(?kjpatp
`abnaceopan[bkn[jasohappan$namqaop%6
?da_gbknir]hqao(ap_*(]j`oq^o_ne^apdaqoan*
***
oq^fa_p9hk]`an*cap[pailh]pa$#]hanpo+oq^fa_p*ptp#%*naj`an$?kjpatp$wy%%
iaoo]ca9hk]`an*cap[pailh]pa$#]hanpo+iaoo]ca*ptp#%*naj`an$?kjpatp$wy%%
oaj`[i]eh$oq^fa_p(iaoo]ca(#`k)jkp)nalhu<at]ilha*_ki#(Wqoan[ai]ehY%
***
In this case, you have to create oq^fa_p*ptp and iaoo]ca*ptp templates in both the
LJWorld.com and Lawrence.com template directories. As mentioned previously, that gives you
more flexibility, but it’s also more complex.
It’s a good idea to exploit the Oepa objects as much as possible to remove unneeded com-
plexity and redundancy.
CurrentSiteManager
If Oepa objects play a key role in your application, consider using the ?qnnajpOepaI]j]can in
your model(s). It’s a model manager (see Chapter 10) that automatically filters its queries to
include only objects associated with the current Oepa.
Use ?qnnajpOepaI]j]can by adding it to your model explicitly, as in this example:
bnki`f]jck*`^eilknpik`aho
bnki`f]jck*_kjpne^*oepao*ik`ahoeilknpOepa
bnki`f]jck*_kjpne^*oepao*i]j]canoeilknp?qnnajpOepaI]j]can
_h]ooLdkpk$ik`aho*Ik`ah%6
ldkpk9ik`aho*BehaBeah`$qlhk]`[pk9#+dkia+ldkpko#%
ldkpkcn]ldan[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd9-,,%
lq^[`]pa9ik`aho*@]paBeah`$%
oepa9ik`aho*BknaecjGau$Oepa%
k^fa_po9ik`aho*I]j]can$%
kj[oepa9?qnnajpOepaI]j]can$%
With this model, Ldkpk*k^fa_po*]hh$% will return all Ldkpk objects in the database, but
Ldkpk*kj[oepa*]hh$% will return only the Ldkpk objects associated with the current site,
according to the OEPA[E@ setting.
In other words, these two statements are equivalent:
Ldkpk*k^fa_po*behpan$oepa9oappejco*OEPA[E@%
Ldkpk*kj[oepa*]hh$%
CHAPTER 16 N DJANGO.CONTRIB
298
How did ?qnnajpOepaI]j]can know which field of Ldkpk was the Oepa? It defaults to look-
ing for a field called oepa. If your model has a BknaecjGau or I]juPkI]juBeah` called something
other than oepa, you need to explicitly pass that as the parameter to ?qnnajpOepaI]j]can. The
following model, which has a field called lq^heod[kj, demonstrates this:
bnki`f]jck*`^eilknpik`aho
bnki`f]jck*_kjpne^*oepao*ik`ahoeilknpOepa
bnki`f]jck*_kjpne^*oepao*i]j]canoeilknp?qnnajpOepaI]j]can
_h]ooLdkpk$ik`aho*Ik`ah%6
ldkpk9ik`aho*BehaBeah`$qlhk]`[pk9#+dkia+ldkpko#%
ldkpkcn]ldan[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd9-,,%
lq^[`]pa9ik`aho*@]paBeah`$%
lq^heod[kj9ik`aho*BknaecjGau$Oepa%
k^fa_po9ik`aho*I]j]can$%
kj[oepa9?qnnajpOepaI]j]can$#lq^heod[kj#%
If you attempt to use ?qnnajpOepaI]j]can and pass a field name that doesn’t exist, Django
will raise a R]hqaAnnkn.
NNote You’ll probably want to keep a normal (non-site-specific) I]j]can on your model, even if you use
?qnnajpOepaI]j]can. As explained in Appendix B, if you define a manager manually, then Django won’t
create the automatic k^fa_po9ik`aho*I]j]can$% manager for you.
Also, certain parts of Django—namely, the Django admin site and generic views—use whichever
manager is defined first in the model, so if you want your admin site to have access to all objects (not just site-
specific ones), put k^fa_po9ik`aho*I]j]can$% in your model before you define ?qnnajpOepaI]j]can.
How Django Uses the Sites Framework
Although it’s not required that you use the sites framework, it’s encouraged because Django
takes advantage of it in a few places. Even if your Django installation is powering only a single
site, you should take a few seconds to create the site object with your `ki]ej and j]ia, and
point to its ID in your OEPA[E@ setting.
Here’s how Django uses the sites framework:
Ê UÊ ÊÌiÊÀi`ÀiVÌÃÊvÀ>iÜÀÊÃiiÊÌiÊ>ÌiÀÊÃiVÌʺ,i`ÀiVÌû®]Êi>VÊÀi`ÀiVÌÊLiVÌÊÃÊ
associated with a particular site. When Django searches for a redirect, it takes into
account the current OEPA[E@.
Ê UÊ ÊÌiÊViÌÃÊvÀ>iÜÀ]Êi>VÊViÌÊÃÊ>ÃÃV>Ìi`ÊÜÌÊ>Ê«>ÀÌVÕ>ÀÊÃÌi°Ê
When a comment is posted, its oepa is set to the current OEPA[E@, and when comments
are listed via the appropriate template tag, only the comments for the current site are
displayed.
CHAPTER 16 N DJANGO.CONTRIB 299
Ê UÊ ÊÌiÊv>Ì«>}iÃÊvÀ>iÜÀÊÃiiÊÌiÊ>ÌiÀÊÃiVÌʺ>Ì«>}iû®]Êi>VÊv>Ì«>}iÊÃÊ>ÃÃV-
ated with a particular site. When a flatpage is created, you specify its oepa, and the
flatpage middleware checks the current OEPA[E@ in retrieving flatpages to display.
Ê UÊ ÊÌiÊÃÞ`V>ÌÊvÀ>iÜÀÊÃiiÊ>«ÌiÀʣή]ÊÌiÊÌi«>ÌiÃÊvÀÊpepha and `ao_nelpekj
automatically have access to a variable wwoepayy, which is the Oepa object represent-
ing the current site. Also, the hook for providing item URLs will use the `ki]ej from the
current Oepa object if you don’t specify a fully qualified domain.
Ê UÊ ÊÌiÊ>ÕÌiÌV>ÌÊvÀ>iÜÀÊÃiiÊ>«ÌiÀÊ£{®]ÊÌiÊ`f]jck*_kjpne^*]qpd*reaso*
hkcej view passes the current Oepa name to the template as wwoepa[j]iayy and the
current Oepa object as wwoepayy.
Flatpages
Often you’ll have a database-driven Web application up and running, but you’ll need to add
a couple of one-off static pages, such as an About page or a Privacy Policy page. It would be
possible to use a standard Web server such as Apache to serve these files as flat HTML files,
but that introduces an extra level of complexity into your application, because then you have
to worry about configuring Apache, you have to set up access for your team to edit those files,
and you can’t take advantage of Django’s template system to style the pages.
The solution to this problem is Django’s flatpages application, which lives in the package
`f]jck*_kjpne^*bh]pl]cao. This application lets you manage such one-off pages via Django’s
admin site, and it lets you specify templates for them using Django’s template system. It uses
Django models behind the scenes, which means it stores the pages in a database, just like the
rest of your data, and you can access flatpages with the standard Django database API.
Flatpages are keyed by their URL and site. When you create a flatpage, you specify which
URL it’s associated with, along with which site(s) it’s on. (For more on sites, see the “Sites”
section.)
Using Flatpages
To install the flatpages application, follow these steps:
1. Add #`f]jck*_kjpne^*bh]pl]cao# to your EJOP=HHA@[=LLO. `f]jck*_kjpne^*bh]pl]cao
depends on `f]jck*_kjpne^*oepao, so make sure both packages are in EJOP=HHA@[=LLO.
2. Add #`f]jck*_kjpne^*bh]pl]cao*ie``has]na*Bh]pl]caB]hh^]_gIe``has]na# to your
IE@@HAS=NA[?H=OOAO setting.
3. Run the command i]j]ca*luouj_`^ to install the two required tables into your
database.
The flatpages application creates two tables in your database: `f]jck[bh]pl]ca and
`f]jck[bh]pl]ca[oepao. `f]jck[bh]pl]ca simply maps a URL to a title and bunch of text con-
tent. `f]jck[bh]pl]ca[oepao is a many-to-many table that associates a flatpage with one or
more sites.
CHAPTER 16 N DJANGO.CONTRIB
300
The application comes with a single Bh]pL]ca model, defined in `f]jck+_kjpne^+bh]pl]cao+
ik`aho*lu. It looks something like this:
bnki`f]jck*`^eilknpik`aho
bnki`f]jck*_kjpne^*oepao*ik`ahoeilknpOepa
_h]ooBh]pL]ca$ik`aho*Ik`ah%6
qnh9ik`aho*?d]nBeah`$i]t[hajcpd9-,,(`^[ej`at9Pnqa%
pepha9ik`aho*?d]nBeah`$i]t[hajcpd9.,,%
_kjpajp9ik`aho*PatpBeah`$^h]jg9Pnqa%
aj]^ha[_kiiajpo9ik`aho*>kkha]jBeah`$%
pailh]pa[j]ia9ik`aho*?d]nBeah`$i]t[hajcpd93,(^h]jg9Pnqa%
naceopn]pekj[namqena`9ik`aho*>kkha]jBeah`$%
oepao9ik`aho*I]juPkI]juBeah`$Oepa%
Let’s examine these fields one at a time:
ÊUÊqnh: The URL at which this flatpage lives, excluding the domain name but including the
leading slash (e.g., +]^kqp+_kjp]_p+).
ÊUÊpepha: The title of the flatpage. The framework doesn’t do anything special with this.
It’s your responsibility to display it in your template.
ÊUÊ_kjpajp: The content of the flatpage (i.e., the HTML of the page). The framework doesn’t
do anything special with this. It’s your responsibility to display it in the template.
ÊUÊaj]^ha[_kiiajpo: Whether to enable comments on this flatpage. The framework
doesn’t do anything special with this. You can check this value in your template and
display a comment form if needed.
ÊUÊpailh]pa[j]ia: The name of the template to use for rendering this flatpage. This is
optional; if it’s not given or if this template doesn’t exist, the framework will fall back to
the template bh]pl]cao+`ab]qhp*dpih.
ÊUÊnaceopn]pekj[namqena`: Whether registration is required for viewing this flatpage. This
integrates with Django’s authentication/user framework, which is explained further in
Chapter 14.
ÊUÊoepao: The sites that this flatpage lives on. This integrates with Django’s sites frame-
work, which is explained in the “Sites” section of this chapter.
You can create flatpages through either the Django admin interface or the Django data-
base API. For more information on this, see the section “Adding, Changing, and Deleting
Flatpages.”
Once you’ve created flatpages, Bh]pl]caB]hh^]_gIe``has]na does all of the work. Each
time any Django application raises a 404 error, this middleware checks the flatpages database
for the requested URL as a last resort. Specifically, it checks for a flatpage with the given URL
with a site ID that corresponds to the OEPA[E@ setting.
If it finds a match, it loads the flatpage’s template or bh]pl]cao+`ab]qhp*dpih if the flat-
page has not specified a custom template. It passes that template a single context variable,
bh]pl]ca, which is the Bh]pL]ca object. It uses Namqaop?kjpatp in rendering the template.
CHAPTER 16 N DJANGO.CONTRIB 301
If Bh]pl]caB]hh^]_gIe``has]na doesn’t find a match, the request continues to be pro-
cessed as usual.
NNote This middleware gets activated for only 404 (page not found) errors—not for 500 (server error) or
other error responses. Also note that the order of IE@@HAS=NA[?H=OOAO matters. Generally, you can put
Bh]pl]caB]hh^]_gIe``has]na at or near the end of the list, because it’s a last resort.
Adding, Changing, and Deleting Flatpages
You can add, change, and delete flatpages in two ways.
Via the Admin Interface
If you’ve activated the automatic Django admin interface, you should see a Flatpages section
on the admin index page. Edit flatpages as you would edit any other object in the system.
Via the Python API
As described previously, flatpages are represented by a standard Django model that lives in
`f]jck+_kjpne^+bh]pl]cao+ik`aho*lu. Hence, you can access flatpage objects via the Django
database API, as in this example:
:::bnki`f]jck*_kjpne^*bh]pl]cao*ik`ahoeilknpBh]pL]ca
:::bnki`f]jck*_kjpne^*oepao*ik`ahoeilknpOepa
:::bl9Bh]pL]ca*k^fa_po*_na]pa$
***qnh9#+]^kqp+#(
***pepha9#=^kqp#(
***_kjpajp9#8l:=^kqppdeooepa***8+l:#(
***aj]^ha[_kiiajpo9B]hoa(
***pailh]pa[j]ia9##(
***naceopn]pekj[namqena`9B]hoa(
***%
:::bl*oepao*]``$Oepa*k^fa_po*cap$e`9-%%
:::Bh]pL]ca*k^fa_po*cap$qnh9#+]^kqp+#%
8Bh]pL]ca6+]^kqp+Í=^kqp:
Using Flatpage Templates
By default, flatpages are rendered via the template bh]pl]cao+`ab]qhp*dpih, but you can over-
ride that for a particular flatpage with the pailh]pa[j]ia field on the Bh]pL]ca object.
Creating the bh]pl]cao+`ab]qhp*dpih template is your responsibility. In your template
directory, just create a bh]pl]cao directory containing a `ab]qhp*dpih file.
CHAPTER 16 N DJANGO.CONTRIB
302
Flatpage templates are passed a single context variable, bh]pl]ca, which is the flatpage
object.
Here’s a sample bh]pl]cao+`ab]qhp*dpih template:
8@K?PULADPIHLQ>HE?)++S/?++@P@DPIH0*,Pn]joepekj]h++AJ
dppl6++sss*s/*knc+PN+NA?)dpih0,+hkkoa*`p`:
8dpih:
8da]`:
8pepha:wwbh]pl]ca*pephayy8+pepha:
8+da]`:
8^k`u:
wwbh]pl]ca*_kjpajpxo]bayy
8+^k`u:
8+dpih:
Note that we’ve used the o]ba template filter to allow bh]pl]ca*_kjpajp to include raw
HTML and bypass autoescaping.
Redirects
Django’s redirects framework lets you manage redirects easily by storing them in a database
and treating them as any other Django model object. For example, you can use the redirects
framework to tell Django, “Redirect any request to +iqoe_+ to +oa_pekjo+]npo+iqoe_+.” This
comes in handy when you need to move things around on your site; Web developers should
do whatever is necessary to avoid broken links.
Using the Redirects Framework
To install the redirects application, follow these steps:
1. Add #`f]jck*_kjpne^*na`ena_po# to your EJOP=HHA@[=LLO.
2. Add #`f]jck*_kjpne^*na`ena_po*ie``has]na*Na`ena_pB]hh^]_gIe``has]na# to your
IE@@HAS=NA[?H=OOAO setting.
3. Run the command i]j]ca*luouj_`^ to install the single required table into your
database.
i]j]ca*luouj_`^ creates a `f]jck[na`ena_p table in your database. This is a simple
lookup table with oepa[e`, kh`[l]pd, and jas[l]pd fields.
You can create redirects through either the Django admin interface or the Django data-
base API. For more, see the section “Adding, Changing, and Deleting Redirects.”
Once you’ve created redirects, the Na`ena_pB]hh^]_gIe``has]na class does all of the
work. Each time any Django application raises a 404 error, this middleware checks the redi-
rects database for the requested URL as a last resort. Specifically, it checks for a redirect with
the given kh`[l]pd with a site ID that corresponds to the OEPA[E@ setting. (See the earlier
section “Sites” for more information on OEPA[E@ and the sites framework.) Then it follows
these steps:
CHAPTER 16 N DJANGO.CONTRIB 303
1. If it finds a match and jas[l]pd is not empty, it redirects to jas[l]pd.
2. If it finds a match and jas[l]pd is empty, it sends a 410 (“Gone”) HTTP header and an
empty (contentless) response.
3. If it doesn’t find a match, the request continues to be processed as usual.
NNote The middleware gets activated for only 404 errors—not for 500 errors or responses of any
other status code. Additionally, the order of IE@@HAS=NA[?H=OOAO matters. Generally, you can put
Na`ena_pB]hh^]_gIe``has]na toward the end of the list, because it’s a last resort.
NNote If you’re using both the redirect and flatpage fallback middleware, consider which one (redirect
or flatpage) you’d like checked first. We suggest flatpages before redirects (thus putting the flatpage middle-
ware before the redirect middleware), but you might feel differently.
Adding, Changing, and Deleting Redirects
You can add, change, and delete redirects in two ways.
Via the Admin Interface
If you’ve activated the automatic Django admin interface, you should see a Redirects section
on the admin index page. Edit redirects as you would edit any other object in the system.
Via the Python API
Redirects are represented by a standard Django model that lives in `f]jck+_kjpne^+na`ena_po+
ik`aho*lu. Hence, you can access redirect objects via the Django database API, as in this
example:
:::bnki`f]jck*_kjpne^*na`ena_po*ik`ahoeilknpNa`ena_p
:::bnki`f]jck*_kjpne^*oepao*ik`ahoeilknpOepa
:::na`9Na`ena_p*k^fa_po*_na]pa$
***oepa9Oepa*k^fa_po*cap$e`9-%(
***kh`[l]pd9#+iqoe_+#(
***jas[l]pd9#+oa_pekjo+]npo+iqoe_+#(
***%
:::Na`ena_p*k^fa_po*cap$kh`[l]pd9#+iqoe_+#%
8Na`ena_p6+iqoe_+))):+oa_pekjo+]npo+iqoe_+:
CHAPTER 16 N DJANGO.CONTRIB
304
CSRF Protection
The `f]jck*_kjpne^*_onb package protects against CSRF (also known as “session riding”),
which is a Web site security exploit. It happens when a malicious Web site tricks a user into
unknowingly loading a URL from a site at which that user is already authenticated, hence tak-
ing advantage of the user’s authenticated status. This can be a bit tricky to understand at first,
so we walk through two examples in this section.
A Simple CSRF Example
Suppose you’re logged in to a Webmail account at at]ilha*_ki. This Webmail site has a Log
Out button that points to the URL at]ilha*_ki+hkckqp—that is, the only action you need to
take in order to log out is to visit the page at]ilha*_ki+hkckqp.
A malicious site can coerce you to visit the URL at]ilha*_ki+hkckqp by including that URL
as a hidden 8ebn]ia: on its own (malicious) page. Thus, if you’re logged in to the at]ilha*_ki
Webmail account and visit the malicious page that has an 8ebn]ia: to at]ilha*_ki+hkckqp, the
act of visiting the malicious page will log you out from at]ilha*_ki.
Clearly, being logged out of a Webmail site against your will is not a terrifying breach
of security, but this same type of exploit can happen to any site that trusts users, such as an
online banking site or an e-commerce site, where the exploit could be used to initiate an order
or payment without the user’s knowledge.
A More Complex CSRF Example
In the previous example, at]ilha*_ki was partially at fault because it allowed a state change
(i.e., logging the user out) to be requested via the HTTP CAP method. It’s much better practice
to require an HTTP LKOP for any request that changes state on the server. But even Web sites
that require LKOP for state-changing actions are vulnerable to CSRF.
Suppose at]ilha*_ki has upgraded its Log Out functionality so that it’s a 8bkni: button
that is requested via LKOP to the URL at]ilha*_ki+hkckqp. Furthermore, the logout 8bkni:
includes this hidden field:
8ejlqppula9de``ajj]ia9_kjbenir]hqa9pnqa:
This ensures that a simple LKOP to the URL at]ilha*_ki+hkckqp won’t log out a user; in
order for a user to log out, the user must request at]ilha*_ki+hkckqp via LKOP and send the
_kjbeni LKOP variable with a value of pnqa.
Well, despite the extra security, this arrangement can still be exploited by CSRF—the mali-
cious page just needs to do a little more work. Attackers can create an entire form targeting
your site, hide it in an invisible 8ebn]ia:, and then use JavaScript to submit that form auto-
matically.
Preventing CSRF
How, then, can your site protect itself from this exploit? The first step is to make sure all CAP
requests are free of side effects. That way, if a malicious site includes one of your pages as an
8ebn]ia:, it won’t have a negative effect.
CHAPTER 16 N DJANGO.CONTRIB 305
That leaves LKOP requests. The second step is to give each LKOP 8bkni: a hidden field
whose value is secret and is generated from the user’s session ID. Then, when processing the
form on the server side, check for that secret field and raise an error if it doesn’t validate.
This is exactly what Django’s CSRF prevention layer does, as explained in the sections
that follow.
Using the CSRF Middleware
The `f]jck*_kjpne^*_onb package contains only one module: ie``has]na*lu. This module
contains a Django middleware class, ?onbIe``has]na, which implements the CSRF protection.
To activate this CSRF protection, add #`f]jck*_kjpne^*_onb*ie``has]na*?onbIe``has]na#
to the IE@@HAS=NA[?H=OOAO setting in your settings file. This middleware needs to process the
response after OaooekjIe``has]na, so ?onbIe``has]na must appear before OaooekjIe``has]na in
the list (because the response middleware is processed last-to-first). Also, it must process the
response before the response gets compressed or otherwise mangled, so ?onbIe``has]na must
come after CVelIe``has]na. Once you’ve added ?onbIe``has]na to your IE@@HAS=NA[?H=OOAO
setting, you’re done. See the section “Order of MIDDLEWARE_CLASSES” in Chapter 15 for
more explanation.
In case you’re interested, here’s how ?onbIe``has]na works:
Ê UÊ ÌÊ`viÃÊÕÌ}}ÊÀiµÕiÃÌÃÊLÞÊ>``}Ê>Ê``iÊvÀÊvi`ÊÌÊ>ÊLKOP forms, with the
name _onbie``has]napkgaj and a value that is a hash of the session ID plus a secret
key. The middleware does not modify the response if there’s no session ID set, so the
performance penalty is negligible for requests that don’t use sessions.
Ê UÊ "Ê>ÊV}ÊLKOP requests that have the session cookie set, it checks that
_onbie``has]napkgaj is present and correct. If it isn’t, the user will get a 403 HTTP
error. The content of the 403 error page is the message “Cross Site Request Forgery
detected. Request aborted.”
This ensures that only forms originating from your Web site can be used to LKOP data back.
This middleware deliberately targets only HTTP LKOP requests (and the correspond-
ing LKOP forms). As we explained, CAP requests ought never to have side effects; it’s your own
responsibility to ensure this.
LKOP requests not accompanied by a session cookie are not protected, but they don’t need
to be protected, because a malicious Web site could make these kind of requests anyway.
To avoid altering non-HTML requests, the middleware checks the response’s ?kjpajp)Pula
header before modifying it. Only pages that are served as patp+dpih or ]llhe_]pekj+tih'tdpih
are modified.
Limitations of the CSRF Middleware
?onbIe``has]na requires Django’s session framework to work. (See Chapter 14 for more on ses-
sions.) If you’re using a custom session or authentication framework that manually manages
session cookies, this middleware will not help you.
If your application creates HTML pages and forms in some unusual way (e.g., if it sends
fragments of HTML in JavaScript `k_qiajp*snepa statements), you might bypass the filter that
adds the hidden field to the form. In this case, the form submission will always fail. (This hap-
pens because ?onbIe``has]na uses a regular expression to add the _onbie``has]napkgaj field
CHAPTER 16 N DJANGO.CONTRIB
306
to your HTML before the page is sent to the client, and the regular expression sometimes can-
not handle wacky HTML.) If you suspect this might be happening, just view the source in your
Web browser to see whether _onbie``has]napkgaj was inserted into your 8bkni:.
For more CSRF information and examples, visit dppl6++aj*segela`e]*knc+sege+?ONB.
Humanizing Data
The package `f]jck*_kjpne^*dqi]jeva holds a set of Django template filters useful for add-
ing a “human touch” to data. To activate these filters, add #`f]jck*_kjpne^*dqi]jeva# to your
EJOP=HHA@[=LLO. Once you’ve done that, use w!hk]`dqi]jeva!y in a template, and you’ll
have access to the filters described in the following sections.
apnumber
For numbers 1 through 9, this filter returns the number spelled out. Otherwise, it returns the
numeral. This follows Associated Press style. Here are some examples:
Ê UÊ º£»ÊLiViÃʺi»°
Ê UÊ ºÓ»ÊLiViÃʺÌÜ»°
Ê UÊ º£ä»ÊÀi>Ãʺ£ä»°
You can pass in either an integer or a string representation of an integer.
intcomma
This filter converts an integer to a string containing commas every three digits. Here are some
examples:
Ê UÊ º{xää»ÊLiViÃʺ{]xää»°
Ê UÊ º{xäää»ÊLiViÃʺ{x]äää»°
Ê UÊ º{xääää»ÊLiViÃʺ{xä]äää»°
Ê UÊ º{xäääää»ÊLiViÃʺ{]xää]äää»°
You can pass in either an integer or a string representation of an integer.
intword
This filter converts a large integer to a friendly text representation. It works best for numbers
over 1 million. Values up to 1 quadrillion (1,000,000,000,000,000) are supported. Here are some
examples:
Ê UÊ º£ääääää»ÊLiViÃʺ£°äÊ»°
Ê UÊ º£Óäääää»ÊLiViÃʺ£°ÓÊ»°
Ê UÊ º£Óääääääää»ÊLiViÃʺ£°ÓÊL»°
You can pass in either an integer or a string representation of an integer.
CHAPTER 16 N DJANGO.CONTRIB 307
ordinal
This filter converts an integer to its ordinal as a string. Here are some examples:
Ê UÊ º£»ÊLiViÃʺ£ÃÌ»°
Ê UÊ ºÓ»ÊLiViÃʺÓ`»°
Ê UÊ ºÎ»ÊLiViÃʺÎÀ`»°
Ê UÊ ºÓx{»ÊLiViÃʺÓx{Ì»°
You can pass in either an integer or a string representation of an integer.
Markup Filters
The package `f]jck*_kjpne^*i]ngql includes a handful of Django template filters, each of
which implements a common markup language:
ÊUÊpatpeha: Implements Textile (dppl6++aj*segela`e]*knc+sege+Patpeha[!.4i]ngql[
h]jcq]ca!.5)
ÊUÊi]ng`ksj: Implements Markdown (dppl6++aj*segela`e]*knc+sege+I]ng`ksj)
ÊUÊnaopnq_pqna`patp: Implements reStructured Text (dppl6++aj*segela`e]*knc+sege+
NaOpnq_pqna`Patp)
In each case, the filter expects formatted markup as a string and returns a string repre-
senting the marked-up text. For example, the patpeha filter converts text that is marked up in
Textile format to HTML:
w!hk]`i]ngql!y
wwk^fa_p*_kjpajpxpatpehayy
To activate these filters, add #`f]jck*_kjpne^*i]ngql# to your EJOP=HHA@[=LLO setting.
Once you’ve done that, use w!hk]`i]ngql!y in a template, and you’ll have access to these
filters. For more documentation, read the source code in `f]jck+_kjpne^+i]ngql+pailh]pap]co+
i]ngql*lu.
What’s Next?
Many of these contributed frameworks (CSRF, the auth system, etc.) do their magic by provid-
ing a piece of middleware. Middleware is code that runs before and/or after every request and
can modify requests and responses at will to extend the framework. In the next chapter, we’ll
discuss Django’s built-in middleware and explain how you can write your own.
CHAPTER 17
Middleware
On occasion, you’ll need to run a piece of code on each and every request that Django
handles. This code might need to modify the request before the view handles it, it might
need to log information about the request for debugging purposes, and so forth.
You can do this with Django’s middleware framework, which is a set of hooks into
Django’s request/response processing. It’s a light, low-level “plug-in” system capable of
globally altering both Django’s input and output.
Each middleware component is responsible for doing some specific function. If you’re
reading this book straight through, you’ve seen middleware a number of times already:
Ê UÊ ÊvÊÌiÊÃiÃÃÊ>`ÊÕÃiÀÊÌÃÊÌ>ÌÊÜiÊi`Ê>ÌÊÊ>«ÌiÀÊ£{Ê>ÀiÊ>`iÊ«ÃÃLiÊLÞÊ
a few small pieces of middleware (more specifically, the middleware makes namqaop*
oaooekj and namqaop*qoan available to you in views).
Ê UÊ /iÊÃÌiÜ`iÊV>ViÊ`ÃVÕÃÃi`ÊÊ>«ÌiÀÊ£xÊÃÊ>VÌÕ>ÞÊÕÃÌÊ>Ê«iViÊvÊ``iÜ>ÀiÊÌ>ÌÊ
bypasses the call to your view function if the response for that view has already been
cached.
Ê UÊ /iÊv>Ì«>}iÃ, redirects, and csrfÊ>««V>ÌÃÊvÀÊ>«ÌiÀÊ£ÈÊ>Ê`ÊÌiÀÊ>}VÊ
through middleware components.
This chapter dives deeper into exactly what middleware is and how it works, and explains
how you can write your own middleware.
What’s Middleware?
Let’s start with a very simple example.
High-traffic sites often need to deploy Django behind a load-balancing proxy (see
>«ÌiÀÊ£Ó®°Ê/ÃÊV>ÊV>ÕÃiÊ>ÊviÜÊÃ>ÊV«V>ÌÃ]ÊiÊvÊÜVÊÃÊÌ>ÌÊiÛiÀÞÊÀiµÕiÃ̽ÃÊ
remote IP (namqaop*IAP=WNAIKPA[ELY) will be that of the load balancer, not the actual IP mak-
ing the request. Load balancers deal with this by setting a special header, T)Bkns]n`a`)Bkn, to
the actual requesting IP address.
309
CHAPTER 17 N MIDDLEWARE
310
So here’s a small bit of middleware that lets sites running behind a proxy still see the
correct IP address in namqaop*IAP=WNAIKPA[=@@NY:
_h]ooOapNaikpa=``nBnkiBkns]n`a`Bkn$k^fa_p%6
`ablnk_aoo[namqaop$oahb(namqaop%6
pnu6
na]h[el9namqaop*IAP=W#DPPL[T[BKNS=N@A@[BKN#Y
at_alpGauAnnkn6
l]oo
ahoa6
DPPL[T[BKNS=N@A@[BKN_]j^a]_kii])oal]n]pa`heopkbELo*
P]gafqoppdabenopkja*
na]h[el9na]h[el*olhep$(%W,Y
namqaop*IAP=W#NAIKPA[=@@N#Y9na]h[el
NNote Although the HTTP header is called T)Bkns]n`a`)Bkn, Django makes it available as namqaop*
IAP=W#DPPL[T[BKNS=N@A@[BKN#Y. With the exception of _kjpajp)hajcpd and _kjpajp)pula, any HTTP
headers in the request are converted to namqaop*IAP= keys by converting all characters to uppercase,
replacing any hyphens with underscores, and adding an DPPL[ prefix to the name.
If this middleware is installed (see the next section), every request’s T)Bkns]n`a`)Bkn value
will be automatically inserted into namqaop*IAP=W#NAIKPA[=@@N#Y. This means your Django
applications don’t need to be concerned with whether they’re behind a load-balancing proxy
or not; they can simply access namqaop*IAP=W#NAIKPA[=@@N#Y, and that will work whether or
not a proxy is being used.
In fact, this is a common enough need that this piece of middleware is a built-in part of
Django. It lives in `f]jck*ie``has]na*dppl, and you can read a bit more about it later in this
chapter.
Middleware Installation
If you’ve read this book straight through, you’ve already seen a number of examples of
middleware installation; many of the examples in previous chapters have required certain
middleware. For completeness, here’s how to install middleware.
To activate a middleware component, add it to the IE@@HAS=NA[?H=OOAO tuple in your
settings module. In IE@@HAS=NA[?H=OOAO, each middleware component is represented by a
string: the full Python path to the middleware’s class name. For example, here’s the default
IE@@HAS=NA[?H=OOAO created by `f]jck)]`iej*luop]nplnkfa_p:
IE@@HAS=NA[?H=OOAO9$
#`f]jck*ie``has]na*_kiikj*?kiikjIe``has]na#(
#`f]jck*_kjpne^*oaooekjo*ie``has]na*OaooekjIe``has]na#(
#`f]jck*_kjpne^*]qpd*ie``has]na*=qpdajpe_]pekjIe``has]na#(
%
CHAPTER 17 N MIDDLEWARE 311
Ê>}ÊÃÌ>>ÌÊ`iÃ½ÌÊÀiµÕÀiÊ>ÞÊ``iÜ>ÀipIE@@HAS=NA[?H=OOAO can be empty,
vÊÞÕ½`ÊipLÕÌÊÜiÊÀiVi`ÊÌ>ÌÊÞÕÊ>VÌÛ>ÌiÊ?kiikjIe``has]na, which we explain shortly.
The order is significant. On the request and view phases, Django applies middleware in
the order given in IE@@HAS=NA[?H=OOAO, and on the response and exception phases, Django
applies middleware in reverse order. That is, Django treats IE@@HAS=NA[?H=OOAO as a sort of
“wrapper” around the view function: on the request it walks down the list to the view, and on
the response it walks back up.
Middleware Methods
Now that you know what middleware is and how to install it, let’s take a look at all the avail-
able methods that middleware classes can define.
Initializer: __init__(self)
Use [[ejep[[$% to perform systemwide setup for a given middleware class.
For performance reasons, each activated middleware class is instantiated only once per
server process. This means that [[ejep[[$%ÊÃÊV>i`ÊÞÊVip>ÌÊÃiÀÛiÀÊÃÌ>ÀÌÕ«pÌÊvÀÊ`-
vidual requests.
ÊVÊÀi>ÃÊÌÊ«iiÌÊ>Ê[[ejep[[$% method is to check whether the middle-
ware is indeed needed. If [[ejep[[$% raises `f]jck*_kna*at_alpekjo*Ie``has]naJkpQoa`, then
Django will remove the middleware from the middleware stack. You might use this feature
to check for some piece of software that the middleware class requires, or check whether the
server is running in debug mode, or any other such environment situation.
If a middleware class defines an [[ejep[[$% method, the method should take no argu-
ments beyond the standard oahb.
Request Preprocessor: process_request(self, request)
This methodÊ}iÌÃÊV>i`Ê>ÃÊÃÊ>ÃÊÌiÊÀiµÕiÃÌÊ>ÃÊLiiÊÀiViÛi`pLivÀiÊ>}Ê>ÃÊ«>ÀÃi`Ê
the URL to determine which view to execute. It gets passed the DpplNamqaop object, which you
may modify at will.
lnk_aoo[namqaop$% should return either Jkja or an DpplNaolkjoa object.
Ê UÊ vÊÌÊÀiÌÕÀÃÊJkja, Django will continue processing this request, executing any other
middleware and then the appropriate view.
Ê UÊ vÊÌÊÀiÌÕÀÃÊ>ÊDpplNaolkjoa object, Django won’t bother calling any other middleware
(of any type) or the appropriate view. Django will immediately return that DpplNaolkjoa.
View Preprocessor: process_view(self, request, view,
args, kwargs)
This method gets called after the request preprocessor is called and Django has determined
which view to execute, but before that view has actually been executed.
CHAPTER 17 N MIDDLEWARE
312
/iÊ>À}ÕiÌÃÊ«>ÃÃi`ÊÌÊÌÃÊÛiÜÊ>ÀiÊÃÜÊÊ/>LiÊ£Ç£°
Table 17-1. Arguments Passed to process_view()
Argument Explanation
namqaop The DpplNamqaop object.
reas The Python function that Django will call to handle this request. This is the actual
function object itself, not the name of the function as a string.
]nco The list of positional arguments that will be passed to the view, not including the
namqaop argument (which is always the first argument to a view).
gs]nco The dictionary of keyword arguments that will be passed to the view.
Just like lnk_aoo[namqaop$%, lnk_aoo[reas$% should return either Jkja or an DpplNaolkjoa
object.
Ê UÊ vÊÌÊÀiÌÕÀÃÊJkja, Django will continue processing this request, executing any other
middleware and then the appropriate view.
Ê UÊ vÊÌÊÀiÌÕÀÃÊ>ÊDpplNaolkjoa object, Django won’t bother calling any other middleware
(of any type) or the appropriate view. Django will immediately return that DpplNaolkjoa.
Response Postprocessor: process_response(self, request,
response)
This method gets called after the view function is called and the response is generated. Here,
the processor can modify the content of a response. One obvious use case is content compres-
sion, such as gzipping of the request’s HTML.
The parameters should be pretty self-explanatory: namqaop is the request object, and
naolkjoa is the response object returned from the view.
Unlike the request and view preprocessors, which may return Jkja, lnk_aoo[naolkjoa$%
must return an DpplNaolkjoa object. That response could be the original one passed into the
function (possibly modified) or a brand-new one.
Exception Postprocessor: process_exception(self, request,
exception)
This method gets called only if something goes wrong and a view raises an uncaught excep-
tion. You can use this hook to send error notifications, dump postmortem information to a log,
or even try to recover from the error automatically.
The parameters to this function are the same namqaop object we’ve been dealing with all
along, and at_alpekj, which is the actual At_alpekj object raised by the view function.
lnk_aoo[at_alpekj$% should return either Jkja or an DpplNaolkjoa object.
Ê UÊ vÊÌÊÀiÌÕÀÃÊJkja, Django will continue processing this request with the framework’s
built-in exception handling.
Ê UÊ vÊÌÊÀiÌÕÀÃÊ>ÊDpplNaolkjoa object, Django will use that response instead of the frame-
work’s built-in exception handling.
CHAPTER 17 N MIDDLEWARE 313
NNote Django ships with a number of middleware classes (discussed in the following section) that make
good examples. Reading the code for them should give you a good feel for the power of middleware.
You can also find a number of community-contributed examples on Django’s wiki: dppl6++_k`a*
`f]jcklnkfa_p*_ki+sege+?kjpne^qpa`Ie``has]na.
Built-in Middleware
Django comes with some built-in middleware to deal with common problems, which we dis-
cuss in the sections that follow.
Authentication Support Middleware
Middleware class: `f]jck*_kjpne^*]qpd*ie``has]na*=qpdajpe_]pekjIe``has]na.
This middleware enables authentication support. It adds the namqaop*qoan attribute, rep-
resenting the currently logged-in user, to every incoming DpplNamqaop object.
-iiÊ>«ÌiÀÊ£{ÊvÀÊV«iÌi details.
“Common” Middleware
Middleware class: `f]jck*ie``has]na*_kiikj*?kiikjIe``has]na.
This middleware adds a few conveniences for perfectionists:
ÊUÊForbids access to user agents in the @EO=HHKSA@[QOAN[=CAJPO setting: If provided, this
setting should be a list of compiled regular expression objects that are matched against
the user-agent header for each incoming request. Here’s an example snippet from a
settings file:
eilknpna
@EO=HHKSA@[QOAN[=CAJPO9$
na*_kileha$n#ZKijeAtlhknan[>kp#%(
na*_kileha$n#ZCkkcha^kp#%
%
Note the eilknpna, because @EO=HHKSA@[QOAN[=CAJPO requires its values to be com-
piled regexes (i.e., the output of na*_kileha$%). The settings file is regular Python, so it’s
perfectly OK to include Python eilknp statements in it.
ÊUÊPerforms URL rewriting based on the =LLAJ@[OH=OD and LNALAJ@[SSS settings: If =LLAJ@[
OH=OD is Pnqa, URLs that lack a trailing slash will be redirected to the same URL with a
trailing slash, unless the last component in the path contains a period. So bkk*_ki+^]n
is redirected to bkk*_ki+^]n+, but bkk*_ki+^]n+beha*ptp is passed through unchanged.
If LNALAJ@[SSS is Pnqa, URLs that lack a leading “www.” will be redirected to the same
URL with a leading “www.”.
CHAPTER 17 N MIDDLEWARE
314
Both of these options are meant to normalize URLs. The philosophy is that each URL
ÃÕ`ÊiÝÃÌÊÊip>`ÊÞÊip«>Vi°Ê/iVV>ÞÊÌiÊ1,Êat]ilha*_ki+^]n is
distinct from at]ilha*_ki+^]n+, which in turn is distinct from sss*at]ilha*_ki+^]n+.
ÊÃi>ÀVi}iÊ`iÝiÀÊÜÕ`ÊÌÀi>ÌÊÌiÃiÊ>ÃÊÃi«>À>ÌiÊ1,Ã]ÊÜVÊÃÊ`iÌÀiÌ>ÊÌÊ
your site’s search-engine rankings, so it’s a best practice to normalize URLs.
ÊUÊHandles ETags based on the QOA[AP=CO setting: ETags are an HTTP-level optimization
for caching pages conditionally. If QOA[AP=CO is set to Pnqa, Django will calculate an
/>}ÊvÀÊi>VÊÀiµÕiÃÌÊLÞÊx>Ã}ÊÌiÊ«>}iÊVÌiÌ]Ê>`ÊÌÊÜÊÌ>iÊV>ÀiÊvÊÃi`-
ing JkpIk`ebea` responses, if appropriate.
Note that there is also a conditional CAP middleware, covered shortly, which handles
ETags and does a bit more.
Compression Middleware
Middleware class: `f]jck*ie``has]na*cvel*CVelIe``has]na.
This middleware automatically compresses content for browsers that understand gzip
compression (all modern browsers). This can greatly reduce the amount of bandwidth a Web
server consumes. The tradeoff is that it takes a bit of processing time to compress pages.
We usually prefer speed over bandwidth, but if you prefer the reverse, just enable this
middleware.
Conditional GET Middleware
Middleware class: `f]jck*ie``has]na*dppl*?kj`epekj]hCapIe``has]na.
This middleware provides support for conditional CAP operations. If the response has a
H]op)Ik`ebea`, an AP]c, and a header, and if the request has Eb)Jkja)I]p_d or Eb)Ik`ebea`)
Oej_a]ÊÌiÊÀiëÃiÊÃÊÀi«>Vi`ÊLÞÊ>ÊÎä{Êº ÌÊ`vi`»®ÊÀiëÃi°ÊAP]c support depends on
the use of the QOA[AP=CO setting and expects the AP]cÊÀiëÃiÊi>`iÀÊÌÊ>Ài>`ÞÊLiÊÃiÌ°ÊÃÊ`Ã-
cussed previously, the AP]c header is set by the common middleware.
It also removes the content from any response to a DA=@ request and sets the @]pa and
?kjpajp)Hajcpd response headers for all requests.
Reverse Proxy Support (X-Forwarded-For Middleware)
Middleware class: `f]jck*ie``has]na*dppl*OapNaikpa=``nBnkiBkns]n`a`Bkn.
This is the example we examined in the “What’s Middleware?” section earlier. It sets
namqaop*IAP=W#NAIKPA[=@@N#Y based on namqaop*IAP=W#DPPL[T[BKNS=N@A@[BKN#Y, if the latter
is set. This is useful if you’re sitting behind a reverse proxy that causes each request’s
NAIKPA[=@@N to be set to -.3*,*,*-.
CHAPTER 17 N MIDDLEWARE 315
NWarning This middleware does not validate DPPL[T[BKNS=N@A@[BKN.
If you’re not behind a reverse proxy that sets DPPL[T[BKNS=N@A@[BKN automatically, do not use this
middleware. Anybody can spoof the value of DPPL[T[BKNS=N@A@[BKN, and because this sets NAIKPA[=@@N
based on DPPL[T[BKNS=N@A@[BKN, that means anybody can fake his IP address.
Only use this middleware when you can absolutely trust the value of DPPL[T[BKNS=N@A@[BKN.
Session Support Middleware
Middleware class: `f]jck*_kjpne^*oaooekjo*ie``has]na*OaooekjIe``has]na.
This middleware enables sessionÊÃÕ««ÀÌ°Ê-iiÊ>«ÌiÀÊ£{ÊvÀÊ`iÌ>ð
Sitewide Cache Middleware
Middleware classes: `f]jck*ie``has]na*_]_da*Ql`]pa?]_daIe``has]na and `f]jck*ie``has]na*
_]_da*Bap_dBnki?]_daIe``has]na.
These classes of middleware work together to cache each Django-powered page. This was
discussed in detailÊÊ>«ÌiÀÊ£x°
Transaction Middleware
Middleware class: `f]jck*ie``has]na*pn]jo]_pekj*Pn]jo]_pekjIe``has]na.
This middleware binds a database ?KIIEP or NKHH>=?G to the request/response phase. If a
view function runs successfully, a ?KIIEP is issued. If the view raises an exception, a NKHH>=?G
is issued.
The order of this middleware in the stack is important. Middleware modules running
ÕÌÃ`iÊvÊÌÊÀÕÊÜÌÊVÌÃ>ÛipÌiÊ`iv>ÕÌÊ>}ÊLi>ÛÀ°Ê``iÜ>ÀiÊ`ÕiÃÊ
running inside it (coming later in the stack) will be under the same transaction control as the
view functions.
-iiÊ««i`Ý B for more about information about database transactions.
What’s Next?
Web developers and database-schema designers don’t always have the luxury of starting from
scratch. In the next chapter, we’ll cover how to integrate with legacy systems, such as database
schemas you’ve inheritedÊvÀÊÌiÊ£näð
CHAPTER 18
Integrating with Legacy
Databases and Applications
Django is best suited for so-called green-field development—that is, starting projects from
scratch, as if you were constructing a building on a fresh field of green grass. But despite the
fact that Django favors from-scratch projects, it’s possible to integrate the framework into
legacy databases and applications. This chapter explains a few integration strategies.
Integrating with a Legacy Database
Django’s database layer generates SQL schemas from Python code—but with a legacy data-
base, you already have the SQL schemas. In such a case, you’ll need to create models for your
existing database tables. For this purpose, Django comes with a tool that can generate model
code by reading your database table layouts. This tool is called ejola_p`^, and you can call it
by executing the command i]j]ca*luejola_p`^.
Using inspectdb
The ejola_p`^ utility inspects the database that your settings file points to, determines a
Django model representation for each of your tables, and prints the Python model code to
standard output.
The following is a walk-through of a typical legacy database–integration process from
scratch. The only assumptions are that Django is installed and that you have a legacy database.
1. Create a Django project by running `f]jck)]`iej*luop]nplnkfa_piuoepa (where
iuoepa is your project’s name).
2. Edit the settings file in that project, iuoepa+oappejco*lu, to tell Django your data-
base-connection parameters and the name of the database. Specifically, provide the
@=P=>=OA[J=IA, @=P=>=OA[AJCEJA, @=P=>=OA[QOAN, @=P=>=OA[L=OOSKN@, @=P=>=OA[DKOP,
and @=P=>=OA[LKNP settings. (Note that some of these settings are optional. Refer to
Chapter 5 for more information.)
317
CHAPTER 18 N INTEGRATING WITH LEGACY DATABASES AND APPLICATIONS
318
3. Create a Django application within your project by running lupdkjiuoepa+i]j]ca*lu
op]np]lliu]ll (where iu]ll is your application’s name).
4. Run the command lupdkjiuoepa+i]j]ca*luejola_p`^. This will examine the tables in
the @=P=>=OA[J=IA database and print the generated model class for each table. Take a
look at the output to get an idea of what ejola_p`^ can do.
5. Save the output to the ik`aho*lu file within your application by using standard shell
output redirection:
lupdkjiuoepa+i]j]ca*luejola_p`^:iuoepa+iu]ll+ik`aho*lu
6. Edit the iuoepa+iu]ll+ik`aho*lu file to clean up the generated models and make any
necessary customizations. We’ll give some hints for this in the next section.
Cleaning Up Generated Models
As you might expect, the database inspection isn’t perfect, and you’ll need to do some light
cleanup of the resulting model code. Here are a few pointers for dealing with the generated
models:
Ê UÊ >VÊ`>Ì>L>ÃiÊÌ>LiÊÃÊVÛiÀÌi`ÊÌÊ>Ê`iÊV>ÃÃÊ°i°]ÊÌiÀiÊÃÊ>ÊiÌiÊ>««}Ê
between database tables and model classes). This means that you’ll need to refactor
the models for any many-to-many join tables into I]juPkI]juBeah` objects.
Ê UÊ >VÊ}iiÀ>Ìi`Ê`iÊ>ÃÊ>Ê>ÌÌÀLÕÌiÊvÀÊiÛiÀÞÊvi`]ÊVÕ`}Êe` primary-key fields.
However, recall that Django automatically adds an e` primary-key field if a model
doesn’t have a primary key. Thus, you’ll want to remove any lines that look like this:
e`9ik`aho*EjpacanBeah`$lnei]nu[gau9Pnqa%
Not only are these lines redundant, but also they can cause problems if your applica-
tion will be adding new records to these tables.
Ê UÊ >VÊvi`½ÃÊÌÞ«iÊi°}°]Ê?d]nBeah`, @]paBeah`) is determined by looking at the database
column type (e.g., R=N?D=N, @=PA). If ejola_p`^ cannot map a column’s type to a model
field type, it will use PatpBeah` and will insert the Python comment #Pdeobeah`pula
eo]cqaoo*# next to the field in the generated model. Keep an eye out for that, and
change the field type accordingly if needed.
If a field in your database has no good Django equivalent, you can safely leave it off.
The Django model layer is not required to include every field in your table(s).
Ê UÊ vÊ>Ê`>Ì>L>ÃiÊVÕÊ>iÊÃÊ>Ê*ÞÌÊÀiÃiÀÛi`ÊÜÀ`ÊÃÕVÊ>ÃÊl]oo, _h]oo, or bkn),
ejola_p`^ will append [beah` to the attribute name and set the `^[_khqij attribute to
the real field name (e.g., l]oo, _h]oo, or bkn).
For example, if a table has an EJP column called bkn, the generated model will have a
field like this:
bkn[beah`9ik`aho*EjpacanBeah`$`^[_khqij9#bkn#%
 ejola_p`^ will insert the Python comment #Beah`naj]ia`^a_]qoaeps]o]Lupdkj
naoanra`skn`*# next to the field.
CHAPTER 18 N INTEGRATING WITH LEGACY DATABASES AND APPLICATIONS 319
Ê UÊ vÊÞÕÀÊ`>Ì>L>ÃiÊVÌ>ÃÊÌ>LiÃÊÌ>ÌÊÀiviÀÊÌÊÌiÀÊÌ>LiÃÊ>ÃÊÃÌÊ`>Ì>L>ÃiÃÊ`®]ÊÞÕÊ
might need to rearrange the order of the generated models so models that refer to
other models are ordered properly. For example, if model >kkg has a BknaecjGau to
model =qpdkn, model =qpdkn should be defined before model >kkg. If you need to create
a relationship on a model that has not yet been defined, you can use a string contain-
ing the name of the model, rather than the model object itself.
ÊUÊejola_p`^ detects primary keys for PostgreSQL, MySQL, and SQLite. That is, it inserts
lnei]nu[gau9Pnqa where appropriate. For other databases, you’ll need to insert lnei]nu[
gau9Pnqa for at least one field in each model, because Django models are required to
have a lnei]nu[gau9Pnqa field.
Ê UÊ Ài}iÞÊ`iÌiVÌÊÜÀÃÊÜÌÊÞÊ*ÃÌ}Ài-+Ê>`ÊViÀÌ>ÊÌÞ«iÃÊvÊÞ-+ÊÌ>LiðÊ
In other cases, foreign-key fields will be generated as EjpacanBeah`s, assuming the
foreign-key column was an EJP column.
Integrating with an Authentication System
It’s possible to integrate Django with an existing authentication system—another source of
usernames and passwords or authentication methods.
For example, your company may already have an LDAP setup that stores a username and
password for every employee. It would be a hassle for both the network administrator and the
users themselves if users had separate accounts in LDAP and the Django-based applications.
To handle situations like this, the Django authentication system lets you plug in other
authentication sources. You can override Django’s default database-based scheme, or you can
use the default system in tandem with other systems.
Specifying Authentication Back-Ends
Behind the scenes, Django maintains a list of authentication back-ends that it checks. When
somebody calls `f]jck*_kjpne^*]qpd*]qpdajpe_]pa$% (as described in Chapter 14), Django
tries authenticating across all of its authentication back-ends. If the first authentication
method fails, Django tries the second one, and so on, until all back-ends have been attempted.
The list of authentication back-ends to use is specified in the =QPDAJPE?=PEKJ[>=?GAJ@O
setting. This should be a tuple of Python path names that point to Python classes that know
how to authenticate. These classes can be anywhere on your Python path.
By default, =QPDAJPE?=PEKJ[>=?GAJ@O is set to the following:
$#`f]jck*_kjpne^*]qpd*^]_gaj`o*Ik`ah>]_gaj`#(%
That’s the basic authentication scheme that checks the Django users database.
The order of =QPDAJPE?=PEKJ[>=?GAJ@O matters, so if the same username and password are
valid in multiple back-ends, Django will stop processing at the first positive match.
Writing an Authentication Back-End
An authentication back-end is a class that implements two methods: cap[qoan$e`% and
]qpdajpe_]pa$&&_na`ajpe]ho%.
CHAPTER 18 N INTEGRATING WITH LEGACY DATABASES AND APPLICATIONS
320
The cap[qoan method takes an e`—which could be a username, database ID, or
whatever—and returns a Qoan object.
The ]qpdajpe_]pa method takes credentials as keyword arguments. Most of the time it
looks like this:
_h]ooIu>]_gaj`$k^fa_p%6
`ab]qpdajpe_]pa$oahb(qoanj]ia9Jkja(l]ooskn`9Jkja%6
?da_gpdaqoanj]ia+l]ooskn`]j`napqnj]Qoan*
But it could also authenticate a token, like so:
_h]ooIu>]_gaj`$k^fa_p%6
`ab]qpdajpe_]pa$oahb(pkgaj9Jkja%6
?da_gpdapkgaj]j`napqnj]Qoan*
Either way, ]qpdajpe_]pa should check the credentials it gets, and it should return a Qoan
object that matches those credentials, if the credentials are valid. If they’re not valid, it should
return Jkja.
The Django admin system is tightly coupled to Django’s own database-backed Qoan object
described in Chapter 14. The best way to deal with this is to create a Django Qoan object for
each user that exists for your back-end (e.g., in your LDAP directory, your external SQL data-
base, etc.). Either you can write a script to do this in advance, or your ]qpdajpe_]pa method
can do it the first time a user logs in.
Here’s an example back-end that authenticates against a username and password vari-
able defined in your oappejco*lu file and creates a Django Qoan object the first time a user
authenticates:
bnki`f]jck*_kjbeilknpoappejco
bnki`f]jck*_kjpne^*]qpd*ik`ahoeilknpQoan(_da_g[l]ooskn`
_h]ooOappejco>]_gaj`$k^fa_p%6

=qpdajpe_]pa]c]ejoppdaoappejco=@IEJ[HKCEJ]j`=@IEJ[L=OOSKN@*
Qoapdahkcejj]ia(]j`]d]odkbpdal]ooskn`*Bknat]ilha6
=@IEJ[HKCEJ9#]`iej#
=@IEJ[L=OOSKN@9#od]- 0a543 ]b^_b0.a.-^`0-3b^3-`^4_22^/.-a5b_//,1-`a#

`ab]qpdajpe_]pa$oahb(qoanj]ia9Jkja(l]ooskn`9Jkja%6
hkcej[r]he`9$oappejco*=@IEJ[HKCEJ99qoanj]ia%
ls`[r]he`9_da_g[l]ooskn`$l]ooskn`(oappejco*=@IEJ[L=OOSKN@%
ebhkcej[r]he`]j`ls`[r]he`6
pnu6
qoan9Qoan*k^fa_po*cap$qoanj]ia9qoanj]ia%
CHAPTER 18 N INTEGRATING WITH LEGACY DATABASES AND APPLICATIONS 321
at_alpQoan*@kaoJkpAteop6
?na]pa]jasqoan*Jkpapd]psa_]joapl]ooskn`
pk]jupdejc(^a_]qoaepskj#p^a_da_ga`7pdal]ooskn`
bnkioappejco*lusehh*
qoan9Qoan$qoanj]ia9qoanj]ia(l]ooskn`9#capbnkioappejco*lu#%
qoan*eo[op]bb9Pnqa
qoan*eo[oqlanqoan9Pnqa
qoan*o]ra$%
napqnjqoan
napqnjJkja
`abcap[qoan$oahb(qoan[e`%6
pnu6
napqnjQoan*k^fa_po*cap$lg9qoan[e`%
at_alpQoan*@kaoJkpAteop6
napqnjJkja
For more on authentication back-ends, see the official Django documentation.
Integrating with Legacy Web Applications
It’s possible to run a Django application on the same Web server as an application powered by
another technology. The most straightforward way of doing this is to use Apache’s configura-
tion file, dppl`*_kjb, to delegate different URL patterns to different technologies. (Note that
Chapter 12 covers Django deployment on Apache/mod_python, so it might be worth reading
that chapter before attempting this integration.)
The key is that Django will be activated for a particular URL pattern only if your dppl`*
_kjb file says so. The default deployment explained in Chapter 12 assumes you want Django to
power every page on a particular domain:
8Hk_]pekj+:
OapD]j`hanlupdkj)lnkcn]i
LupdkjD]j`han`f]jck*_kna*d]j`hano*ik`lupdkj
OapAjr@F=JCK[OAPPEJCO[IK@QHAiuoepa*oappejco
Lupdkj@a^qcKj
8+Hk_]pekj:
Here, the 8Hk_]pekj+: line means “handle every URL, starting at the root,” with
Django.
It’s perfectly fine to limit this 8Hk_]pekj: directive to a certain directory tree. For example,
say you have a legacy PHP application that powers most pages on a domain and you want to
install a Django admin site at +]`iej+ without disrupting the PHP code. To do this, just set the
8Hk_]pekj: directive to +]`iej+:
CHAPTER 18 N INTEGRATING WITH LEGACY DATABASES AND APPLICATIONS
322
8Hk_]pekj+]`iej+:
OapD]j`hanlupdkj)lnkcn]i
LupdkjD]j`han`f]jck*_kna*d]j`hano*ik`lupdkj
OapAjr@F=JCK[OAPPEJCO[IK@QHAiuoepa*oappejco
Lupdkj@a^qcKj
8+Hk_]pekj:
With this in place, only the URLs that start with +]`iej+ will activate Django. Any other
page will use whatever infrastructure already existed.
Note that attaching Django to a qualified URL (such as +]`iej+ in this section’s example)
does not affect the Django URL parsing. Django works with the absolute URL (e.g., +]`iej+
laklha+lanokj+]``+), not a “stripped” version of the URL (e.g., +laklha+lanokj+]``+). This
means that your root URLconf should include the leading +]`iej+.
What’s Next?
If you’re a native English speaker, you might not have noticed one of the coolest features of
Django’s admin site: it’s available in more than 50 languages! This is made possible by Djan-
go’s internationalization framework (and the hard work of Django’s volunteer translators). The
next chapter explains how to use this framework to provide localized Django sites.
CHAPTER 19
Internationalization
Django was originally developed right in the middle of the United States quite literally
because Lawrence, Kansas lies fewer than 40 miles from the geographic center of the conti-
nental United States. Like most open source projects, though, Django’s community grew to
include people from all over the globe. As Django’s community became increasingly diverse,
internationalization and localization became increasingly important. Because many develop-
ers have at best a fuzzy understanding of these terms, we’ll define them briefly.
Internationalization refers to the process of designing programs for the potential use of
any locale. This includes marking text such as user interface (UI) elements and error messages
for future translation, abstracting the display of dates and times so that different local stan-
dards can be observed, providing support for differing time zones, and generally making sure
that the code contains no assumptions about the location of its users. You’ll often see inter-
nationalization abbreviated as I18N (18 refers to the number of letters omitted between the
initial I and the terminal N.)
Localization refers to the process of actually translating an internationalized program for
use in a particular locale. You’ll sometimes see localization abbreviated as L10N.
Django itself is fully internationalized; all strings are marked for translation, and settings
control the display of locale-dependent values such as dates and times. Django also ships with
more than 50 different localization files. If you’re not a native English speaker, there’s a good
chance that Django is already translated into your primary language.
The same internationalization framework used for these localizations is available for you
to use in your own code and templates.
To use this framework, you’ll need to add a minimal number of hooks to your Python
code and templates. These hooks are called translation strings. They tell Django, “This text
should be translated into the end user’s language if a translation for this text is available in that
language.”
Django takes care of using these hooks to translate Web applications on the fly, according
to users’ language preferences.
323
CHAPTER 19 N INTERNATIONALIZATION
324
Django does two things:
Ê UÊ ÌÊiÌÃÊ`iÛi«iÀÃÊ>`ÊÌi«>ÌiÊ>ÕÌÀÃÊëiVvÞÊÜVÊ«>ÀÌÃÊvÊÌiÀÊ>««V>ÌÃÊÃÕ`Ê
be translatable.
Ê UÊ ÌÊÕÃiÃÊÌ>ÌÊvÀ>ÌÊÌÊÌÀ>Ã>ÌiÊ7iLÊ>««V>ÌÃÊvÀÊ«>ÀÌVÕ>ÀÊÕÃiÀÃÊ>VVÀ`}ÊÌÊ
their language preferences.
NNote Django’s translation machinery uses GNU cappatp (dppl6++sss*cjq*knc+okbps]na+cappatp+)
via the standard cappatp module that comes with Python.
IF YOU DON'T NEED INTERNATIONALIZATION
Django’s internationalization hooks are enabled by default, which incurs a small bit of overhead. If you don’t
use internationalization, you should set QOA[E-4J9B]hoa in your settings file. If QOA[E-4J is set to
B]hoa, Django will make some optimizations to avoid loading the internationalization machinery.
You’ll probably also want to remove #`f]jck*_kna*_kjpatp[lnk_aookno*e-4j# from your
PAILH=PA[?KJPATP[LNK?AOOKNO setting.
The three steps for internationalizing your Django application are as follows:
1. Embed translation strings in your Python code and templates.
2. Get translations for those strings, in whichever languages you want to support.
3. Activate the locale middleware in your Django settings.
We’ll cover each one of these steps in detail in the following sections.
How to Specify Translation Strings
Translation strings specify that “this text should be translated.” These strings can appear in
your Python code and templates. It’s your responsibility to mark translatable strings; the sys-
tem can translate only strings it knows about.
In Python Code
Standard Translation
Specify a translation string by using the function qcappatp$%. It’s convention to import this as a
shorter alias, [, to save typing.
CHAPTER 19 N INTERNATIONALIZATION 325
In this example, the text Sah_kiapkiuoepa* is marked as a translation string:
bnki`f]jck*qpeho*pn]joh]pekjeilknpqcappatp]o[
`abiu[reas$namqaop%6
kqplqp9[$Sah_kiapkiuoepa*%
napqnjDpplNaolkjoa$kqplqp%
Obviously, you could code this without using the alias. This example is identical to the
previous one:
bnki`f]jck*qpeho*pn]joh]pekjeilknpqcappatp
`abiu[reas$namqaop%6
kqplqp9qcappatp$Sah_kiapkiuoepa*%
napqnjDpplNaolkjoa$kqplqp%
Translation works on computed values. This example is identical to the previous two:
`abiu[reas$namqaop%6
skn`o9W#Sah_kia#(#pk#(#iu#(#oepa*#Y
kqplqp9[$##*fkej$skn`o%%
napqnjDpplNaolkjoa$kqplqp%
Translation works on variables. Again, here’s an identical example:
`abiu[reas$namqaop%6
oajpaj_a9#Sah_kiapkiuoepa*#
kqplqp9[$oajpaj_a%
napqnjDpplNaolkjoa$kqplqp%
NCaution The caveat when using variables or computed values, as in the previous two examples, is that
Django’s translation string–detecting utility, `f]jck)]`iej*lui]gaiaoo]cao, can’t find these strings.
More on i]gaiaoo]cao later.
The strings you pass to [$% or qcappatp$% can take placeholders specified with Python’s
standard named-string interpolation syntax. For example:
`abiu[reas$namqaop(i(`%6
kqplqp9[$#Pk`]ueo!$ikjpd%o!$`]u%o*#%!w#ikjpd#6i(#`]u#6`y
napqnjDpplNaolkjoa$kqplqp%
This technique lets language-specific translations reorder the placeholder text. For exam-
ple, an English translation may be Pk`]ueoJkrai^an.2*, whereas a Spanish translation
may be Dkuao.2`aJkreai^na* Only the placeholders (the month and the day) have their
positions swapped.
CHAPTER 19 N INTERNATIONALIZATION
326
For this reason, you should use named-string interpolation (e.g., !$`]u%o) instead of posi-
tional interpolation (e.g., !o or !`) whenever you have more than a single parameter. If you
used positional interpolation, translations couldn’t reorder placeholder text.
Marking Strings As No-Op
Use the function `f]jck*qpeho*pn]joh]pekj*qcappatp[jkkl$% to mark a string as a translation
string without translating it. The string is later translated from a variable.
Use it if you have constant strings that should be stored in the source language because
they are exchanged over systems or users such as strings in a database but should be trans-
lated at the last possible point in time, such as when the string is presented to the user.
Lazy Translation
Use the function `f]jck*qpeho*pn]joh]pekj*qcappatp[h]vu$% to translate strings lazily when
the value is accessed instead of when the qcappatp[h]vu$% function is called.
For example, to translate a model’s dahl[patp, do the following:
bnki`f]jck*qpeho*pn]joh]pekjeilknpqcappatp[h]vu
_h]ooIuPdejc$ik`aho*Ik`ah%6
j]ia9ik`aho*?d]nBeah`$dahl[patp9qcappatp[h]vu$#Pdeoeopdadahlpatp#%%
In this example, qcappatp[h]vu$% stores a lazy reference to the string, not the actual trans-
lation. The translation itself will be done when the string is used in a string context, such as
template rendering on the Django admin site.
The result of a qcappatp[h]vu$% call can be used wherever you would use a Unicode string
(an object with type qje_k`a) in Python. If you try to use it where a bytestring (a opn object)
is expected, things will not work as expected because a qcappatp[h]vu$% object doesn’t know
how to convert itself to a bytestring. You can’t use a Unicode string inside a bytestring, either,
so this is consistent with normal Python behavior. For example:
Pdeoeobeja6lqppejc]qje_k`alnktuejpk]qje_k`aopnejc*
qDahhk!o!qcappatp[h]vu$laklha%
Pdeosehhjkpskng(oej_aukq_]jjkpejoanp]qje_k`ak^fa_p
ejpk]^upaopnejc$jkn_]jukqejoanpkqnqje_k`alnktupdana%
Dahhk!o!qcappatp[h]vu$laklha%
If you ever see output that looks like dahhk8`f]jck*qpeho*bqj_pekj]h***:, you have
tried to insert the result of qcappatp[h]vu$% into a bytestring. That’s a bug in your code.
If you don’t like the verbose name qcappatp[h]vu, you can just alias it as [ (underscore),
like so:
bnki`f]jck*qpeho*pn]joh]pekjeilknpqcappatp[h]vu]o[
_h]ooIuPdejc$ik`aho*Ik`ah%6
j]ia9ik`aho*?d]nBeah`$dahl[patp9[$#Pdeoeopdadahlpatp#%%
CHAPTER 19 N INTERNATIONALIZATION 327
Always use lazy translations in Django models. Field names and table names should
be marked for translation (otherwise, they won’t be translated in the admin interface). This
means writing explicit ran^koa[j]ia and ran^koa[j]ia[lhqn]h options in the Iap] class,
though, instead of relying on Django’s default determination of ran^koa[j]ia and ran^koa[
j]ia[lhqn]h by looking at the model’s class name:
bnki`f]jck*qpeho*pn]joh]pekjeilknpqcappatp[h]vu]o[
_h]ooIuPdejc$ik`aho*Ik`ah%6
j]ia9ik`aho*?d]nBeah`$[$#j]ia#%(dahl[patp9[$#Pdeoeopdadahlpatp#%%
_h]ooIap]6
ran^koa[j]ia9[$#iupdejc#%
ran^koa[j]ia[lhqn]h9[$#iupdejco#%
Pluralization
Use the function `f]jck*qpeho*pn]joh]pekj*qjcappatp$% to specify pluralized messages. For
example:
bnki`f]jck*qpeho*pn]joh]pekjeilknpqjcappatp
`abdahhk[sknh`$namqaop(_kqjp%6
l]ca9qjcappatp$#pdanaeo!$_kqjp%`k^fa_p#(
#pdana]na!$_kqjp%`k^fa_po#(_kqjp%!w
#_kqjp#6_kqjp(
y
napqnjDpplNaolkjoa$l]ca%
qjcappatp takes three arguments: the singular translation string, the plural translation
string, and the number of objects (which is passed to the translation languages as the _kqjp
variable).
In Template Code
Translation in Django templates uses two template tags and a slightly different syntax than in
Python code. To give your template access to these tags, put w!hk]`e-4j!y toward the top
of your template.
The w!pn]jo!y template tag translates either a constant string (enclosed in single or
double quotes) or variable content:
8pepha:w!pn]joPdeoeopdapepha*!y8+pepha:
8pepha:w!pn]joiur]n!y8+pepha:
If the jkkl option is present, variable lookup still takes place, but the translation is
skipped. This is useful when “stubbing out” content that will require translation in the future:
8pepha:w!pn]joiur]njkkl!y8+pepha:
CHAPTER 19 N INTERNATIONALIZATION
328
It’s not possible to mix a template variable inside a string within w!pn]jo!y. If your
translations require strings with variables (placeholders), use w!^hk_gpn]jo!y:
w!^hk_gpn]jo!yPdeoopnejcsehhd]rawwr]hqayyejoe`a*w!aj`^hk_gpn]jo!y
To translate a template expression (using template filters, for instance), you need to bind
the expression to a local variable for use within the translation block:
w!^hk_gpn]josepdr]hqaxbehpan]oiur]n!y
Pdeosehhd]rawwiur]nyyejoe`a*
w!aj`^hk_gpn]jo!y
If you need to bind more than one expression inside a ^hk_gpn]jo tag, separate the pieces
with ]j`:
w!^hk_gpn]josepd^kkgxpepha]o^kkg[p]j`]qpdknxpepha]o]qpdkn[p!y
Pdeoeoww^kkg[pyy^uww]qpdkn[pyy
w!aj`^hk_gpn]jo!y
To pluralize, specify both the singular and plural forms with the w!lhqn]h!y tag, which
appears within w!^hk_gpn]jo!y and w!aj`^hk_gpn]jo!y. For example:
w!^hk_gpn]jo_kqjpheopxhajcpd]o_kqjpan!y
Pdanaeokjhukjawwj]iayyk^fa_p*
w!lhqn]h!y
Pdana]naww_kqjpanyywwj]iayyk^fa_po*
w!aj`^hk_gpn]jo!y
Internally, all block and inline translations use the appropriate qcappatp/qjcappatp call.
Each Namqaop?kjpatp has access to three translation-specific variables:
ÊUÊH=JCQ=CAO is a list of tuples in which the first element is the language code and the
second is the language name (translated into the currently active locale).
ÊUÊH=JCQ=CA[?K@A is the current user’s preferred language as a string. For example: aj)qo.
(See the following section, “How Django Discovers Language Preference.”)
ÊUÊH=JCQ=CA[>E@E is the current locale’s direction. If Pnqa, it’s a right-to-left language
(e.g., Hebrew and Arabic). If B]hoa, it’s a left-to-right language (e.g., English, French,
German, and so on).
If you don’t use the Namqaop?kjpatp extension, you can get those values with three tags:
w!cap[_qnnajp[h]jcq]ca]oH=JCQ=CA[?K@A!y
w!cap[]r]eh]^ha[h]jcq]cao]oH=JCQ=CAO!y
w!cap[_qnnajp[h]jcq]ca[^e`e]oH=JCQ=CA[>E@E!y
These tags also require a w!hk]`e-4j!y.
Translation hooks are also available within any template block tag that accepts constant
strings. In those cases, just use [$% syntax to specify a translation string:
w!okia[ola_e]h[p]c[$L]cajkpbkqj`%r]hqaxuaojk6[$uao(jk%!y
CHAPTER 19 N INTERNATIONALIZATION 329
In this case, both the tag and the filter will see the already-translated string, so they don’t
need to be aware of translations.
NNote In this example, the translation infrastructure will be passed the string uao(jk, not the individual
strings uao and jk. The translated string will need to contain the comma so that the filter parsing code
knows how to split up the arguments. For example, a German translator might translate the string uao(jk
as f](jaej (keeping the comma intact).
Working with Lazy Translation Objects
Using qcappatp[h]vu$% and qjcappatp[h]vu$% to mark strings in models and utility functions
is a common operation. When you’re working with these objects elsewhere in your code, you
should ensure that you don’t accidentally convert them to strings because they should be con-
verted as late as possible (so that the correct locale is in effect). This necessitates the use of a
couple of helper functions, discussed in the following sections.
Joining Strings: string_concat()
Standard Python string joins (##*fkej$W***Y%) will not work on lists containing lazy transla-
tion objects. Instead, you can use `f]jck*qpeho*pn]joh]pekj*opnejc[_kj_]p$%, which creates a
lazy object that concatenates its contents and converts them to strings only when the result is
included in a string. For example:
bnki`f]jck*qpeho*pn]joh]pekjeilknpopnejc[_kj_]p
***
j]ia9qcappatp[h]vu$q#FkdjHajjkj#%
ejopnqiajp9qcappatp[h]vu$q#cqep]n#%
naoqhp9opnejc[_kj_]p$Wj]ia(#6#(ejopnqiajpY%
In this case, the lazy translations in naoqhp will be converted to strings only when naoqhp
itself is used in a string (usually at template-rendering time).
The allow_lazy() Decorator
Django offers many utility functions (particularly in `f]jck*qpeho) that take a string as their
first argument and do something to that string. These functions are used by template filters as
well as directly in other code.
If you write your own similar functions and deal with translations, you’ll face the problem
of what to do when the first argument is a lazy translation object. You don’t want to convert it
to a string immediately because you might be using this function outside of a view (and hence
the current thread’s locale setting will not be correct).
CHAPTER 19 N INTERNATIONALIZATION
330
For cases like these, use the `f]jck*qpeho*bqj_pekj]h*]hhks[h]vu$% decorator. It modi-
fies the function so that if it’s called with a lazy translation as the first argument, the function
evaluation is delayed until it needs to be converted to a string. For example:
bnki`f]jck*qpeho*bqj_pekj]heilknp]hhks[h]vu
`abb]j_u[qpehepu[bqj_pekj$o(***%6
@kokia_kjranoekjkjopnejc#o#
***
b]j_u[qpehepu[bqj_pekj9]hhks[h]vu$b]j_u[qpehepu[bqj_pekj(qje_k`a%
In addition to the function to decorate, the ]hhks[h]vu$% decorator takes a number of
extra arguments (&]nco) specifying the type(s) that the original function can return. Usually, it’s
enough to include qje_k`a here and ensure that your function returns only Unicode strings.
Using this decorator means that you can write your function and assume that the input is
a proper string; then add support for lazy translation objects at the end.
How to Create Language Files
After you tag your strings for later translation, you need to write (or obtain) the language trans-
lations themselves. Here’s how that works.
LOCALE RESTRICTIONS
Django does not support localizing your application into a locale for which Django itself has not been
translated. In this case, it will ignore your translation files. If you were to try this, and Django supported it,
you would inevitably see a mixture of translated strings (from your application) and English strings (from
Django itself).
If you want to support a locale for your application that is not already part of Django, you’ll need to make
at least a minimal translation of the Django core.
Message Files
The first step is to create a message file for a new language. A message file is a plain-text file,
representing a single language, that contains all available translation strings and how they
should be represented in the given language. Message files have a *lk file extension.
Django comes with a tool, `f]jck)]`iej*lui]gaiaoo]cao, which automates the creation
and upkeep of these files. To create or update a message file, run this command, where `a is
the language code for the message file you want to create:
`f]jck)]`iej*lui]gaiaoo]cao)h`a
CHAPTER 19 N INTERNATIONALIZATION 331
The language code, in this case, is in locale format. For example, it’s lp[>N for Brazilian
Portuguese and `a[=P for Austrian German.
The script should be run from one of three places:
Ê UÊ /iÊÀÌÊ`ÀiVÌÀÞÊvÊÞÕÀÊ>}Ê«ÀiVÌ°
Ê UÊ /iÊÀÌÊ`ÀiVÌÀÞÊvÊÞÕÀÊ>}Ê>««°
Ê UÊ /iÊÀÌÊ`f]jck directory (not a Subversion checkout, but the one that is linked to via
LUPDKJL=PD or is located somewhere on that path). This is relevant only when you are
creating a translation for Django itself.
This script runs over your project source tree or your application source tree, and pulls
out all strings marked for translation. It creates (or updates) a message file in the directory
hk_]ha+H=JC+H?[IAOO=CAO. In the `a example, the file will be hk_]ha+`a+H?[IAOO=CAO+`f]jck*lk.
By default, `f]jck)]`iej*lui]gaiaoo]cao examines every file that has the *dpih file
extension. In case you want to override that default, use the ))atpajoekj or )a option to spec-
ify the file extensions to examine:
`f]jck)]`iej*lui]gaiaoo]cao)h`a)aptp
Separate multiple extensions with commas and/or use )a or ))atpajoekj multiple times:
`f]jck)]`iej*lui]gaiaoo]cao)h`a)adpih(ptp)atih
When creating JavaScript translation catalogs (covered later in this chapter), you need to
use the special `f]jckfo domain, not )afo.
NO GETTEXT?
If you don’t have the cappatp utilities installed, `f]jck)]`iej*lui]gaiaoo]cao will create empty files.
If that’s the case, either install the cappatp utilities or just copy the English message file (hk_]ha+aj+
H?[IAOO=CAO+`f]jck*lk), if available, and use it as a starting point; it’s just an empty translation file.
WORKING ON WINDOWS?
If you’re using Windows and need to install the GNU cappatp utilities so `f]jck)]`ieji]gaiaoo]cao
works, see the “gettext on Windows” section for more information.
The format of *lk files is straightforward. Each *lk file contains a small bit of metadata,
such as the translation maintainer’s contact information, but the bulk of the file is a list of
messages—simple mappings between translation strings and the actual translated text for the
particular language.
CHAPTER 19 N INTERNATIONALIZATION
332
For example, if your Django app contained a translation string for the text Sah_kiapkiu
oepa* like so:
[$Sah_kiapkiuoepa*%
`f]jck)]`iej*lui]gaiaoo]cao will have created a *lk file containing the following snippet
message:
6l]pd+pk+lupdkj+ik`qha*lu6./
ioce`Sah_kiapkiuoepa*
iocopn
Here’s a quick explanation:
ÊUÊioce` is the translation string that appears in the source. Don’t change it.
ÊUÊiocopn is where you put the language-specific translation. It starts out empty, so it’s
your responsibility to change it. Make sure to keep the quotes around your translation.
Ê UÊ ÃÊ>ÊVÛiiVi]Êi>VÊiÃÃ>}iÊVÕ`iÃ]ÊÊÌiÊvÀÊvÊ>ÊViÌÊiÊ«ÀivÝi`ÊÜÌÊ
and located above the ioce` line, the file name and line number from which the
translation string was gleaned.
Long messages are a special case. There, the first string directly after the iocopn (or ioce`)
is an empty string. Then the content itself will be written over the next few lines as one string
per line. Those strings are directly concatenated. Don’t forget trailing spaces within the strings;
otherwise, they’ll be tacked together without whitespace!
To reexamine all source code and templates for new translation strings and update all
message files for all languages, run this:
`f]jck)]`iej*lui]gaiaoo]cao)]
Compiling Message Files
After you create your message file and each time you make changes to it you’ll need to
compile it into a more efficient form for use by cappatp. Do this with the `f]jck)]`iej*lu
_kilehaiaoo]cao utility.
This tool runs over all available *lk files and creates *ik files, which are binary files
optimized for use by cappatp. In the same directory from which you ran `f]jck)]`iej*lu
i]gaiaoo]cao, run `f]jck)]`iej*lu_kilehaiaoo]cao like this:
`f]jck)]`iej*lu_kilehaiaoo]cao
That’s it. Your translations are ready for use.
CHAPTER 19 N INTERNATIONALIZATION 333
How Django Discovers Language Preference
After you prepare your translations (or if you just want to use the translations that come with
Django), you need to activate translation for your app.
Behind the scenes, Django has a very flexible model of deciding which language should be
used: installation-wide, for a particular user, or both.
To set an installation-wide language preference, set H=JCQ=CA[?K@A. Django uses this lan-
guage as the default translation—the final attempt if no other translator finds a translation.
If all you want to do is run Django with your native language, and a language file is avail-
able for your language, just set H=JCQ=CA[?K@A.
If you want to let each individual user specify which language he or she prefers, use
Hk_]haIe``has]na. Hk_]haIe``has]na enables language selection based on data from the
request. It customizes content for each user.
To use Hk_]haIe``has]na, add #`f]jck*ie``has]na*hk_]ha*Hk_]haIe``has]na# to your
IE@@HAS=NA[?H=OOAO setting. Because middleware order matters, you should follow these
guidelines:
Ê UÊ >iÊÃÕÀiÊÌ>ÌÊ̽ÃÊiÊvÊÌiÊvÀÃÌÊ``iÜ>ÀiÃÊÃÌ>i`°
Ê UÊ ÌÊÃÕ`ÊViÊ>vÌiÀÊOaooekjIe``has]na because Hk_]haIe``has]na makes use of
session data.
Ê UÊ vÊÞÕÊÕÃiÊ?]_daIe``has]na, put Hk_]haIe``has]na after it.
For example, your IE@@HAS=NA[?H=OOAO might look like this:
IE@@HAS=NA[?H=OOAO9$
#`f]jck*_kjpne^*oaooekjo*ie``has]na*OaooekjIe``has]na#(
#`f]jck*ie``has]na*hk_]ha*Hk_]haIe``has]na#(
#`f]jck*ie``has]na*_kiikj*?kiikjIe``has]na#(
%
(For more on middleware, see Chapter 17.)
Hk_]haIe``has]na tries to determine the user’s language preference by following this
algorithm:
1. First, it looks for a `f]jck[h]jcq]ca key in the current user’s session.
2. Failing that, it looks for a cookie.
3. Failing that, it looks at the =__alp)H]jcq]ca HTTP header. This header is sent by your
browser and tells the server which language(s) you prefer, in order by priority. Django
tries each language in the header until it finds one with available translations.
4. Failing that, it uses the global H=JCQ=CA[?K@A setting.
CHAPTER 19 N INTERNATIONALIZATION
334
Note the following:
Ê UÊ Êi>VÊvÊÌiÃiÊ«>ViÃ]ÊÌiÊ>}Õ>}iÊ«ÀiviÀiViÊÃÊiÝ«iVÌi`ÊÌÊLiÊÊÌiÊÃÌ>`>À`Ê>-
guage format as a string. For example, Brazilian Portuguese is lp)^n.
Ê UÊ vÊ>ÊL>ÃiÊ>}Õ>}iÊÃÊ>Û>>Li]ÊLÕÌÊÌiÊÃÕL>}Õ>}iÊëiVvi`ÊÃÊÌ]Ê>}ÊÕÃiÃÊÌiÊ
base language. For example, if a user specifies `a)]p (Austrian German) but Django has
only `a available, Django uses `a.
Ê UÊ "ÞÊ>}Õ>}iÃÊÃÌi`ÊÊÌiÊH=JCQ=CAO setting can be selected. If you want to restrict
the language selection to a subset of provided languages (because your application
doesn’t provide all those languages), set H=JCQ=CAO to a list of languages. For example:
H=JCQ=CAO9$
$#`a#([$#Cani]j#%%(
$#aj#([$#Ajcheod#%%(
%
This example restricts languages that are available for automatic selection to German
and English (and any sublanguage such as `a)_d or aj)qo).
Ê UÊ vÊÞÕÊ`iviÊ>ÊVÕÃÌÊH=JCQ=CAO setting, as explained in the previous bullet, it’s fine
to mark the languages as translation strings but use a “dummy” qcappatp$% function,
not the one in `f]jck*qpeho*pn]joh]pekj. You should never import `f]jck*qpeho*
pn]joh]pekj from within your settings file because that module in itself depends on the
settings, and that would cause a circular import.
The solution is to use a “dummy” qcappatp$% function. Here’s a sample settings file:
qcappatp9h]i^`]o6o
H=JCQ=CAO9$
$#`a#(qcappatp$#Cani]j#%%(
$#aj#(qcappatp$#Ajcheod#%%(
%
With this arrangement, `f]jck)]`iej*lui]gaiaoo]cao will still find and mark these
strings for translation, but the translation won’t happen at runtime. You’ll have to
remember to wrap the languages in the real qcappatp$% in any code that uses H=JCQ=CAO
at runtime.
Ê UÊ /iÊHk_]haIe``has]na can select only languages for which there is a Django-provided
base translation. If you want to provide translations for your application that aren’t
already in the set of translations in Django’s source tree, you’ll want to provide at least
basic translations for that language. For example, Django uses technical message IDs
to translate date formats and time formats, so you need at least those translations for
the system to work correctly.
A good starting point is to copy the English *lk file and to translate at least the techni-
cal messages (maybe the validation messages, too).
CHAPTER 19 N INTERNATIONALIZATION 335
Technical message IDs are easily recognized; they’re all uppercase. You don’t trans-
late the message ID as with other messages; you provide the correct local variant on
the provided English value. For example, with @=PAPEIA[BKNI=P (or @=PA[BKNI=P or
PEIA[BKNI=P) this would be the format string that you want to use in your language.
The format is identical to the format strings used by the jks template tag.
After Hk_]haIe``has]na determines the user’s preference, it makes this preference avail-
able as namqaop*H=JCQ=CA[?K@A for each DpplNamqaop. Feel free to read this value in your view
code. Here’s a simple example:
`abdahhk[sknh`$namqaop%6
ebnamqaop*H=JCQ=CA[?K@A99#`a)]p#6
napqnjDpplNaolkjoa$Ukqlnabanpkna]`=qopne]jCani]j*%
ahoa6
napqnjDpplNaolkjoa$Ukqlnabanpkna]`]jkpdanh]jcq]ca*%
Note that with static (middleware-less) translation the language is in oappejco*H=JCQ=CA[
?K@A, whereas with dynamic (middleware) translation, it’s in namqaop*H=JCQ=CA[?K@A.
Using Translations in Your Own Projects
Django looks for translations by following this algorithm:
1. First, it looks for a hk_]ha directory in the application directory of the view that’s being
called. If it finds a translation for the selected language, the translation will be installed.
2. Next, it looks for a hk_]ha directory in the project directory. If it finds a translation, the
translation will be installed.
3. Finally, it checks the Django-provided base translation in `f]jck+_kjb+hk_]ha.
This way, you can write applications that include their own translations, and you can
override base translations in your project path. Or you can just build a big project out of sev-
eral apps and put all translations into one big project message file. The choice is yours.
All message file repositories are structured in the same way:
ÊUÊ =LLL=PD+hk_]ha+8h]jcq]ca:+H?[IAOO=CAO+`f]jck*$lkxik%
ÊUÊ LNKFA?PL=PD+hk_]ha+8h]jcq]ca:+H?[IAOO=CAO+`f]jck*$lkxik%
Ê UÊ Ê«>ÌÃÊÃÌi`ÊÊHK?=HA[L=PDO in your settings file are searched in that order for
8h]jcq]ca:+H?[IAOO=CAO+`f]jck*$lkxik%
ÊUÊ LUPDKJL=PD+`f]jck+_kjb+hk_]ha+8h]jcq]ca:+H?[IAOO=CAO+`f]jck*$lkxik%
To create message files, use the same `f]jck)]`iej*lui]gaiaoo]cao tool as with the
Django message files. You only need to be in the right place: in the directory in which either
the _kjb+hk_]ha (in case of the source tree) or the hk_]ha+ (in case of app messages or project
messages) directory is located. And you use the same `f]jck)]`iej*lu_kilehaiaoo]cao to
produce the binary `f]jck*ik files that are used by cappatp.
You can also run `f]jck)]`iej*lu_kilehaiaoo]cao))oappejco9l]pd*pk*oappejco to
make the compiler process all the directories in your HK?=HA[L=PDO setting.
CHAPTER 19 N INTERNATIONALIZATION
336
Application message files are a bit complicated to discover they need the Hk_]haIe``has]na.
If you don’t use the middleware, only the Django message files and project message files will be
processed.
Finally, you should give some thought to the structure of your translation files. If your
applications need to be delivered to other users and will be used in other projects, you might
want to use app-specific translations. But using app-specific translations and project trans-
lations could produce weird problems with i]gaiaoo]cao: i]gaiaoo]cao will traverse all
directories below the current path and so might put message IDs into the project message files
that are already in application message files.
The easiest way out is to store applications that are not part of the project (and so carry
their own translations) outside the project tree. That way, `f]jck)]`iej*lui]gaiaoo]cao
on the project level will translate only strings that are connected to your explicit project, not
strings that are distributed independently.
The set_language Redirect View
As a convenience, Django comes with a view, `f]jck*reaso*e-4j*oap[h]jcq]ca, which sets a
user’s language preference and redirects back to the previous page.
Activate this view by adding the following line to your URLconf:
$n#Ze-4j+#(ej_hq`a$#`f]jck*_kjb*qnho*e-4j#%%(
NNote This example makes the view available at +e-4j+oaph]jc+.
The view expects to be called via the LKOP method with a h]jcq]ca parameter set in the
request. If session support is enabled, the view saves the language choice in the user’s session.
Otherwise, it saves the language choice in a cookie named `f]jck[h]jcq]ca by default. (The
name can be changed through the H=JCQ=CA[?KKGEA[J=IA setting.)
After setting the language choice, Django redirects the user, following this algorithm:
Ê UÊ >}ÊÃÊvÀÊ>Êjatp parameter in the LKOP data.
Ê UÊ vÊÌ>ÌÊ`iÃ½ÌÊiÝÃÌÊÀÊÃÊi«ÌÞ]Ê>}ÊÌÀiÃÊÌiÊ1,ÊÊÌiÊNabannan header.
Ê UÊ vÊÌ>̽ÃÊi«ÌÞÊvÀÊiÝ>«i]ÊvÊ>ÊÕÃiÀ½ÃÊLÀÜÃiÀÊÃÕ««ÀiÃÃiÃÊÌ>ÌÊi>`iÀ®]ÊÌiÊÕÃiÀÊÜÊ
be redirected to + (the site root) as a fallback.
Here’s an example of HTML template code:
8bkni]_pekj9+e-4j+oaph]jc+iapdk`9lkop:
8ejlqpj]ia9jatppula9de``ajr]hqa9+jatp+l]ca++:
8oaha_pj]ia9h]jcq]ca:
w!bknh]jcejH=JCQ=CAO!y
8klpekjr]hqa9wwh]jc*,yy:wwh]jc*-yy8+klpekj:
w!aj`bkn!y
8+oaha_p:
8ejlqppula9oq^iepr]hqa9Ck+:
8+bkni:
CHAPTER 19 N INTERNATIONALIZATION 337
Translations and JavaScript
Adding translations to JavaScript poses some problems:
Ê UÊ >Û>-VÀ«ÌÊV`iÊ`iÃ½ÌÊ>ÛiÊ>VViÃÃÊÌÊ>Êcappatp implementation.
Ê UÊ >Û>-VÀ«ÌÊV`iÊ`iÃ½ÌÊ>ÛiÊ>VViÃÃÊÌÊ*lk or *ik files; they need to be delivered by
the server.
Ê UÊ /iÊÌÀ>Ã>ÌÊV>Ì>}ÃÊvÀÊ>Û>-VÀ«ÌÊÃÕ`ÊLiÊi«ÌÊ>ÃÊÃ>Ê>ÃÊ«ÃÃLi°
Django provides an integrated solution for these problems: it passes the translations into
JavaScript, so you can call cappatp, and so on from within JavaScript.
The javascript_catalog View
The main solution to these problems is the f]r]o_nelp[_]p]hkc view, which sends out a
JavaScript code library with functions that mimic the cappatp interface, plus an array of trans-
lation strings. Those translation strings are taken from the application, project, or Django core,
according to what you specify in either the ejbk[`e_p or the URL.
You hook it up like this:
fo[ejbk[`e_p9w
#l]_g]cao#6$#ukqn*]ll*l]_g]ca#(%(
y
qnhl]ppanjo9l]ppanjo$##(
$n#Zfoe-4j+ #(#`f]jck*reaso*e-4j*f]r]o_nelp[_]p]hkc#(fo[ejbk[`e_p%(
%
Each string in l]_g]cao should be in Python dotted-package syntax (the same format as
the strings in EJOP=HHA@[=LLO) and should refer to a package that contains a hk_]ha directory. If
you specify multiple packages, all those catalogs are merged into one catalog. This is useful if
you have JavaScript that uses strings from different applications.
You can make the view dynamic by putting the packages into the URL pattern:
qnhl]ppanjo9l]ppanjo$##(
$n#Zfoe-4j+$;L8l]_g]cao:XO'%+ #(#`f]jck*reaso*e-4j*f]r]o_nelp[_]p]hkc#%(
%
With this, you specify the packages as a list of package names delimited by + signs in the
URL. This is especially useful if your pages use code from different apps and change often, and
you don’t want to pull in one big catalog file. As a security measure, these values can be only
`f]jck*_kjb or any package from the EJOP=HHA@[=LLO setting.
Using the JavaScript Translation Catalog
To use the catalog, just pull in the dynamically generated script like this:
8o_nelppula9patp+f]r]o_nelpon_9+l]pd+pk+foe-4j+:8+o_nelp:
CHAPTER 19 N INTERNATIONALIZATION
338
This is how the admin fetches the translation catalog from the server. When the catalog is
loaded, your JavaScript code can use the standard cappatp interface to access it:
`k_qiajp*snepa$cappatp$#pdeoeopk^apn]joh]pa`#%%7
There is also an jcappatp interface:
r]nk^fa_p[_jp9-++kn,(kn.(kn/(***
o9jcappatp$#hepan]hbknpdaoejcqh]n_]oa#(
#hepan]hbknpdalhqn]h_]oa#(k^fa_p[_jp%7
And even a string interpolation function:
bqj_pekjejpanlkh]pa$bip(k^f(j]ia`%7
The interpolation syntax is borrowed from Python, so the ejpanlkh]pa function supports
both positional and named interpolation:
ÊUÊPositional interpolation: k^f contains a JavaScript =nn]u object whose elements values
are then sequentially interpolated in their corresponding bip placeholders in the same
order they appear. For example:
bipo9jcappatp$#Pdanaeo!ok^fa_p*Nai]ejejc6!o#(
#Pdana]na!ok^fa_po*Nai]ejejc6!o#(--%7
o9ejpanlkh]pa$bipo(W--(.,Y%7
++oeo#Pdana]na--k^fa_po*Nai]ejejc6.,#
ÊUÊNamed interpolation: This mode is selected by passing the optional Boolean j]ia`
parameter as pnqa. k^f contains a JavaScript object or associative array. For example:
`9w
_kqjp6-,
pkp]h61,
y7
bipo9jcappatp$#Pkp]h6!$pkp]h%o(pdanaeo!$_kqjp%ok^fa_p#(
#pdana]na!$_kqjp%okb]pkp]hkb!$pkp]h%ok^fa_po#(`*_kqjp%7
o9ejpanlkh]pa$bipo(`(pnqa%7
You shouldn’t go over the top with string interpolation, though; this is still JavaScript,
so the code has to make repeated regular-expression substitutions. This isn’t as fast as string
interpolation in Python, so keep it to those cases where you really need it (for example, in con-
junction with jcappatp to produce proper pluralizations).
CHAPTER 19 N INTERNATIONALIZATION 339
Creating JavaScript Translation Catalogs
You create and update the translation catalogs the same way as with the other Django transla-
tion catalogs: with the `f]jck)]`iej*lui]gaiaoo]cao tool. The only difference is you need to
provide a )``f]jckfo parameter, like this:
`f]jck)]`iej*lui]gaiaoo]cao)``f]jckfo)h`a
This creates or updates the translation catalog for JavaScript for German. After updating
translation catalogs, just run `f]jck)]`iej*lu_kilehaiaoo]cao the same way as you do with
normal Django translation catalogs.
Notes for Users Familiar with gettext
If you know cappatp, you might note these specialties in the way Django does translation:
Ê UÊ /iÊÃÌÀ}Ê`>ÊÃÊ`f]jck or `f]jckfo. This string domain is used to differentiate
between different programs that store their data in a common message-file library
(usually +qon+od]na+hk_]ha+). The `f]jck domain is used for Python and template
translation strings, and is loaded into the global translation catalogs. The `f]jckfo
domain is used only for JavaScript translation catalogs to make sure that they are as
small as possible.
Ê UÊ >}Ê`iÃ½ÌÊÕÃiÊtcappatp alone. It uses Python wrappers around tcappatp and
iocbip. This is mostly for convenience.
gettext on Windows
This is needed only for people who either want to extract message IDs or compile message files
(*lk). Translation work itself just involves editing existing files of this type, but if you want to
create your own message files, or want to test or compile a changed message file, you need the
cappatp utilities:
1. Download the following ZIP files from dppl6++okqn_abknca*jap+lnkfa_po+cappatp:
ÊUÊcappatp)nqjpeia)T*^ej*ska/.*vel
ÊUÊcappatp)pkkho)T*^ej*ska/.*vel
ÊUÊhe^e_kjr)T*^ej*ska/.*vel
2. Extract the three files in the same folder (?6XLnkcn]iBehaoXcappatp)qpeho).
3. Update the system L=PD:
a. ?kjpnkhL]jah¢Ouopai¢=`r]j_a`¢AjrenkjiajpR]ne]^hao.
b. In the Ouopair]ne]^hao list, click L]pd; then click A`ep.
c. Add 7?6XLnkcn]iBehaoXcappatp)qpehoX^ej at the end of the R]ne]^har]hqa field.
CHAPTER 19 N INTERNATIONALIZATION
340
You can also use cappatp binaries you have obtained elsewhere as long as the tcappatp
))ranoekj command works properly. Some version 0.14.4 binaries have been found to not
support this command. Do not attempt to use Django translation utilities with a cappatp pack-
age if the command tcappatp))ranoekj entered at a Windows command prompt causes a
pop-up window saying “xgettext.exe has generated errors and will be closed by Windows.”
What’s Next?
The final chapter focuses on security: how you can help secure your sites and your users from
malicious attackers.
CHAPTER 20
Security
The Internet can be a scary place.
These days, high-profile security gaffes seem to crop up on a daily basis. We’ve seen
viruses spread with amazing speed; swarms of compromised computers wielded as weapons;
a never-ending arms race against spammers; and many, many reports of identity theft from
hacked Web sites.
As Web developers, we have a duty to do what we can to combat these forces of darkness.
Every Web developer needs to treat security as a fundamental aspect of Web programming.
Unfortunately, it turns out that implementing security is hard—attackers need to find only a
single vulnerability, but defenders have to protect every single one.
Django attempts to mitigate this difficulty. It’s designed to automatically protect you from
many of the common security mistakes that new (and even experienced) Web developers
make. Still, it’s important to understand what these problems are, how Django protects you,
and—most important—the steps you can take to make your code even more secure.
First, though, an important disclaimer: we do not intend to present a definitive guide
to every known Web security exploit, so we won’t try to explain each vulnerability in a com-
prehensive manner. Instead, we’ll give a short synopsis of security problems as they apply
to Django.
The Theme of Web Security
If you learn only one thing from this chapter, let it be this:
Never—under any circumstances—trust data from the browser.
You never know who’s on the other side of that HTTP connection. It might be one of your
users, but it just as easily could be a nefarious cracker looking for an opening.
Any data of any nature that comes from the browser needs to be treated with a healthy
dose of paranoia. This includes data that’s both “in band” (i.e., submitted from Web forms)
and “out of band” (i.e., HTTP headers, cookies, and other request information). It’s trivial to
spoof the request metadata that browsers usually add automatically.
341
CHAPTER 20 N SECURITY
342
Every one of the vulnerabilities discussed in this chapter stems directly from trusting data
that comes over the wire and then failing to sanitize that data before using it. You should make
it a general practice to continuously ask, “Where does this data come from?”
SQL Injection
SQL injection is a common exploit in which an attacker alters Web page parameters (such as
CAP/LKOP data or URLs) to insert arbitrary SQL snippets that a naive Web application executes
in its database directly. It’s probably the most dangerous—and unfortunately one of the most
common—vulnerabilities out there.
This vulnerability most commonly crops up when constructing SQL “by hand” from user
input. For example, imagine writing a function to gather a list of contact information from a
contact search page. To prevent spammers from reading every single e-mail in our system,
we’ll force the user to type in someone’s username before providing her e-mail address:
`abqoan[_kjp]_po$namqaop%6
qoan9namqaop*CAPW#qoanj]ia#Y
omh9OAHA?P&BNKIqoan[_kjp]_poSDANAqoanj]ia9#!o#7!qoanj]ia
ata_qpapdaOMHdana***
NNote In this example, and in all similar “don’t-do-this” examples that follow, we deliberately left out most
of the code needed to make the functions actually work. We don’t want this code to work if someone acci-
dentally takes it out of context.
Although at first this SQL construction doesn’t look dangerous, it really is.
First, our attempt at protecting our entire e-mail list will fail with a cleverly constructed
query. Think about what happens if an attacker types #KN#]#9#] into the query box. In that
case, the query that the string interpolation will construct will be the following:
OAHA?P&BNKIqoan[_kjp]_poSDANAqoanj]ia9##KN#]#9#]#7
Because we allowed unsecured SQL into the string, the attacker’s added KN clause ensures
that every single row is returned.
However, that’s the least scary attack. Imagine what will happen if the attacker submits
#7@AHAPABNKIqoan[_kjp]_poSDANA#]#9#]. We’ll end up with this complete query
(comprising two statements):
OAHA?P&BNKIqoan[_kjp]_poSDANAqoanj]ia9##7
@AHAPABNKIqoan[_kjp]_poSDANA#]#9#]#7
Yikes! Our entire contact list would be deleted instantly.
CHAPTER 20 N SECURITY 343
The Solution
Although this problem is insidious and sometimes hard to spot, the solution is simple: never
trust user-submitted data, and always escape it when passing it into SQL.
The Django database API does this for you. It automatically escapes all special SQL
parameters, according to the quoting conventions of the database server you’re using (e.g.,
PostgreSQL or MySQL).
For example, in this API call:
bkk*cap[heop$^]n[[at]_p9#KN-9-%
Django will escape the input accordingly, resulting in a statement like this:
OAHA?P&BNKIbkkoSDANA^]n9#X#KN-9-#
Completely harmless.
This applies to the entire Django database API, with a couple of exceptions:
Ê UÊ /iÊsdana argument to the atpn]$% method. That parameter accepts raw SQL by
design.
Ê UÊ +ÕiÀiÃÊ`iʺLÞÊ>`»ÊÕÃ}ÊÌiÊÜiÀiÛiÊ`>Ì>L>ÃiÊ*ÊÃiiÊ>«ÌiÀʣ䮰
In each of these cases, it’s easy to keep yourself protected. In each case, avoid string inter-
polation in favor of passing in bind parameters. That is, the example we started this section
with should be written as follows:
bnki`f]jck*`^eilknp_kjja_pekj
`abqoan[_kjp]_po$namqaop%6
qoan9namqaop*CAPW#qoanj]ia#Y
omh9OAHA?P&BNKIqoan[_kjp]_poSDANAqoanj]ia9!o
_qnokn9_kjja_pekj*_qnokn$%
_qnokn*ata_qpa$omh(WqoanY%
***`kokiapdejcsepdpdanaoqhpo
The low-level ata_qpa method takes a SQL string with !o placeholders and automati-
cally escapes and inserts parameters from the list passed as the second argument. You should
always construct custom SQL this way.
Unfortunately, you can’t use bind parameters everywhere in SQL; they’re not allowed as
identifiers (i.e., table or column names). Thus, if you need to dynamically construct a list of
tables from a LKOP variable, for example, you’ll need to escape that name in your code. Django
provides a function, `f]jck*`^*_kjja_pekj*klo*mqkpa[j]ia, which will escape the identifier
according to the current database’s quoting scheme.
Cross-Site Scripting (XSS)
Cross-site scripting (XSS) is found in Web applications that fail to escape user-submitted con-
tent properly before rendering it into HTML. This allows an attacker to insert arbitrary HTML
into your Web page, usually in the form of 8o_nelp: tags.
CHAPTER 20 N SECURITY
344
Attackers often use XSS attacks to steal cookie and session information, or to trick users
into giving private information to the wrong person (aka phishing).
This type of attack can take a number of different forms and has an almost infinite num-
ber of permutations, so we’ll just look at a typical example. Consider this extremely simple
“Hello, World” view:
bnki`f]jck*dppleilknpDpplNaolkjoa
`abo]u[dahhk$namqaop%6
j]ia9namqaop*CAP*cap$#j]ia#(#sknh`#%
napqnjDpplNaolkjoa$#8d-:Dahhk(!o8+d-:#!j]ia%
This view simply reads a name from a CAP parameter and passes that name into the
generated HTML. So if we accessed dppl6++at]ilha*_ki+dahhk+;j]ia9F]_k^, the page would
contain this:
8d-:Dahhk(F]_k^8+d-:
But wait—what happens if we access dppl6++at]ilha*_ki+dahhk+;j]ia98e:F]_k^8+e:?
We get this:
8d-:Dahhk(8e:F]_k^8+e:8+d-:
Of course, an attacker wouldn’t use something as benign as 8e: tags; he could include a
whole set of HTML that hijacked your page with arbitrary content. This type of attack has been
used to trick users into entering data into what looks like their bank’s Web site, but in fact is an
XSS-hijacked form that submits their back account information to an attacker.
The problem gets worse if you store this data in the database and later display it on your
site. For example, MySpace was once found to be vulnerable to an XSS attack of this nature. A
user inserted JavaScript into his profile that automatically added him as your friend when you
visited his profile page. Within a few days, he had millions of friends.
Now this may sound relatively benign, but keep in mind that this attacker managed to get
his code—not MySpace’s—running on your computer. This violates the assumed trust that all
the code on MySpace is actually written by MySpace.
MySpace was extremely lucky that this malicious code didn’t automatically delete view-
ers’ accounts, change their passwords, flood the site with spam, or create any of the other
nightmare scenarios this vulnerability unleashes.
The Solution
The solution is simple: always escape any content that might have come from a user before
inserting it into HTML.
To guard against this, Django’s template system automatically escapes all variable values.
Let’s see what happens if we rewrite our example using the template system:
reaso*lu
bnki`f]jck*odknp_qpoeilknpnaj`an[pk[naolkjoa
CHAPTER 20 N SECURITY 345
`abo]u[dahhk$namqaop%6
j]ia9namqaop*CAP*cap$#j]ia#(#sknh`#%
napqnjnaj`an[pk[naolkjoa$#dahhk*dpih#(w#j]ia#6j]iay%
dahhk*dpih
8d-:Dahhk(wwj]iayy8+d-:
With this in place, a request to dppl6++at]ilha*_ki+dahhk+j]ia98e:F]_k^8+e: will result in
the following page:
8d-:Dahhk("hp7e"cp7F]_k^"hp7+e"cp78+d-:
We covered Django’s auto-escaping back in Chapter 4, along with ways to turn it off. But
even if you’re using this feature, you should still get in the habit of asking yourself at all times,
“Where does this data come from?” No automatic solution will ever protect your site from XSS
>ÌÌ>VÃÊ£ää¯Êv the time.
Cross-Site Request Forgery
Cross-site request forgery (CSRF) happens when a malicious Web site tricks users into
unknowingly loading a URL from a site at which they’re already authenticated—hence taking
advantage of their authenticated status.
Django has built-in tools to protect from this kind of attack. (The attack itself and those
tools are covered in great detailÊÊ>«ÌiÀʣȰ®
Session Forging/Hijacking
This isn’t a specific attack; it’s a general class of attacks on a user’s session data. It can take a
number of different forms:
ÊUÊÊman-in-the-middle attack, in which an attacker snoops on session data as it travels
over the wire (or wireless) network.
ÊUÊSession forging, in which an attacker uses a session ID (perhaps obtained through a
man-in-the-middle attack) to pretend to be another user.
An example of these first two is an attacker in a coffee shop using the shop’s wireless
network to capture a session cookie. She could then use that cookie to impersonate the
original user.
ÊUÊÊcookie-forging attack, in which an attacker overrides the supposedly read-only data
ÃÌÀi`ÊÊ>ÊVi°Ê>«ÌiÀÊ£{ÊiÝ«>ÃÊÊ`iÌ>ÊÜÊViÃÊÜÀÆÊiÊvÊÌiÊÃ>iÌÊ
points is that it’s trivial for browsers and malicious users to change cookies without
your knowledge.
There’s a long history of Web sites that have stored a cookie such as EoHkcca`Ej9- or
even Hkcca`Ej=oQoan9f]_k^. It’s dead simple to exploit these types of cookies.
On a more subtle level, though, it’s never a good idea to trust anything stored in cook-
ies. You never know who’s been poking at them.
CHAPTER 20 N SECURITY
346
ÊUÊSession fixation, in which an attacker tricks a user into setting or resetting the user’s
session ID.
For example, PHP allows session identifiers to be passed in the URL (e.g., dppl6++
at]ilha*_ki+;LDLOAOOE@9b]5,-53_].1b2]^0,^^-/30_1-,`3]/.). An attacker who tricks a
user into clicking a link with a hard-coded session ID will cause the user to pick up that
session.
Session fixation has been used in phishing attacks to trick users into entering personal
information into an account the attacker owns. He can later log into that account and
retrieve the data.
ÊUÊSession poisoning, in which an attacker injects potentially dangerous data into a user’s
session—usually through a Web form that the user submits to set session data.
A canonical example is a site that stores a simple user preference (such as a page’s
background color) in a cookie. An attacker could trick a user into clicking a link to sub-
mit a “color” that actually contains an XSS attack. If that color isn’t escaped, the user
could again inject malicious code into the user’s environment.
The Solution
There are a number of general principles that can protect you from these attacks:
Ê iÛiÀÊ>ÜÊÃiÃÃÊvÀ>ÌÊÌÊLiÊVÌ>i`ÊÊÌiÊ1,°
Ê Ê >}½ÃÊÃiÃÃÊvÀ>iÜÀÊÃiiÊ>«ÌiÀÊ£{®ÊÃ«ÞÊ`iÃ½ÌÊ>ÜÊÃiÃÃÃÊÌÊLiÊV-
tained in the URL.
Ê UÊ ½ÌÊÃÌÀiÊ`>Ì>ÊÊViÃÊ`ÀiVÌÞ°ÊÃÌi>`]ÊÃÌÀiÊ>ÊÃiÃÃÊÊÌ>ÌÊ>«ÃÊÌÊÃiÃÃÊ
data stored on the back-end.
If you use Django’s built-in session framework (i.e., namqaop*oaooekj), this is handled
automatically for you. The only cookie that the session framework uses is a single ses-
sion ID; all the session data is stored in the database.
Ê UÊ ,iiLiÀÊÌÊiÃV>«iÊÃiÃÃÊ`>Ì>ÊvÊÞÕÊ`ë>ÞÊÌÊÊÌiÊÌi«>Ìi°Ê-iiÊÌiÊi>ÀiÀÊ8--Ê
section, and remember that it applies to any user-created content as well as any data
from the browser. You should treat session information as being user created.
Ê UÊ *ÀiÛiÌÊ>ÌÌ>ViÀÃÊvÀÊëv}ÊÃiÃÃÊÃÊÜiiÛiÀÊ«ÃÃLi°
Although it’s nearly impossible to detect someone who’s hijacked a session ID, Django
does have built-in protection against a brute-force session attack. Session IDs are
stored as hashes (instead of sequential numbers), which prevents a brute-force attack,
and a user will always get a new session ID if she tries a nonexistent one, which pre-
vents session fixation.
Notice that none of those principles and tools prevents man-in-the-middle attacks, which
are nearly impossible to detect. If your site allows logged-in users to see any sort of sensitive
data, you should always serve that site over HTTPS. Additionally, if you have an SSL-enabled
site, you should set the OAOOEKJ[?KKGEA[OA?QNA setting to Pnqa; this will make Django only send
session cookies over HTTPS.
CHAPTER 20 N SECURITY 347
E-mail Header Injection
SQL injection’s less well-known sibling, e-mail header injection, hijacks Web forms that send
e-mail. An attacker can use this technique to send spam via your mail server. Any form that
constructs e-mail headers from Web form data is vulnerable to this kind of attack.
Let’s look at the canonical contact form found on many sites. Usually this sends a message
to a hard-coded e-mail address, so it doesn’t appear vulnerable to spam abuse at first glance.
However, most of these forms also allow the user to type in his own subject for the e-mail
(along with a “from” address, a body, and sometimes a few other fields). This subject field is
used to construct the “subject” header of the e-mail message.
If that header is unescaped when building the e-mail message, an attacker could submit
something like dahhkXj__6ol]ire_pei<at]ilha*_ki (where Xj” is a newline character). That
would make the constructed e-mail headers turn into this:
Pk6d]n`_k`a`<at]ilha*_ki
Oq^fa_p6dahhk
__6ol]ire_pei<at]ilha*_ki
Like SQL injection, if we trust the subject line given by the user, we’ll allow him to con-
struct a malicious set of headers, and he can use our contact form to send spam.
The Solution
We can prevent this attack in the same way we prevent SQL injection: always escape or vali-
date user-submitted content.
Django’s built-in mail functions (in `f]jck*_kna*i]eh) simply do not allow newlines in
any fields used to construct headers (the “from” and “to” addresses, plus the subject). If you
try to use `f]jck*_kna*i]eh*oaj`[i]eh with a subject that contains newlines, Django will raise
a >]`Da]`anAnnkn exception.
If you do not use Django’s built-in mail functions to send e-mail, you’ll need to make sure
that newlines in headers either cause an error or are stripped. You may want to examine the
O]baIEIAPatp class in `f]jck*_kna*i]eh to see how Django does this.
Directory Traversal
Directory traversal is another injection-style attack, in which a malicious user tricks filesystem
code into reading and/or writing files that the Web server shouldn’t have access to.
An example might be a view that reads files from the disk without carefully sanitizing the
file name:
`ab`qil[beha$namqaop%6
behaj]ia9namqaop*CAPWbehaj]iaY
behaj]ia9ko*l]pd*fkej$>=OA[L=PD(behaj]ia%
_kjpajp9klaj$behaj]ia%*na]`$%
***
Though it looks like that view restricts file access to files beneath >=OA[L=PD (by using
ko*l]pd*fkej), if the attacker passes in a behaj]ia containing ** (two periods, a shorthand for
CHAPTER 20 N SECURITY
348
“the parent directory”), she can access files “above” >=OA[L=PD. It’s only a matter of time before
she can discover the correct number of dots to successfully access **+**+**+**+**+ap_+l]oos`,
for example.
Anything that reads files without proper escaping is vulnerable to this problem. Views that
write files are just as vulnerable, but the consequences are doubly dire.
Another permutation of this problem lies in code that dynamically loads modules based
on the URL or other request information. A well-publicized example came from the world of
,ÕLÞÊÊ,>ðÊ*ÀÀÊÌÊ`ÓääÈ]Ê,>ÃÊÕÃi`Ê1,ÃÊÃÕVÊ>ÃÊdppl6++at]ilha*_ki+lanokj+lkga+-
directly to load modules and call methods. The result was that a carefully constructed URL
could automatically load arbitrary code, including a database reset script!
The Solution
If your code ever needs to read or write files based on user input, you need to sanitize the
requested path very carefully to ensure that an attacker can’t escape from the base directory
you’re restricting access to.
NNote Needless to say, you should never write code that can read from any area of the disk!
A good example of how to do this escaping lies in Django’s built-in static content-serving
view (in `f]jck*reaso*op]pe_). Here’s the relevant code:
eilknpko
eilknplkoetl]pd
***
l]pd9lkoetl]pd*jknil]pd$qnhhe^*qjmqkpa$l]pd%%
jasl]pd9##
bknl]npejl]pd*olhep$#+#%6
ebjkpl]np6
opnelailpul]pd_kilkjajpo
_kjpejqa
`nera(l]np9ko*l]pd*olhep`nera$l]np%
da]`(l]np9ko*l]pd*olhep$l]np%
ebl]npej$ko*_qn`en(ko*l]n`en%6
opnel#*#]j`#**#ejl]pd
_kjpejqa
jasl]pd9ko*l]pd*fkej$jasl]pd(l]np%*nalh]_a$#XX#(#+#%
Django doesn’t read files (unless you use the op]pe_*oanra function, but that’s protected
with the code just shown), so this vulnerability doesn’t affect the core code much.
CHAPTER 20 N SECURITY 349
In addition, the use of the URLconf abstraction means that Django will never load code
you’ve not explicitly told it to load. There’s no way to create a URL that causes Django to load
something not mentioned in a URLconf.
Exposed Error Messages
During development, being able to see tracebacks and errors live in your browser is extremely
useful. Django has “pretty” and informative debug messages specifically to make debugging
easier.
However, if these errors get displayed after the site goes live, they can reveal aspects of
your code or configuration that could aid an attacker.
Furthermore, errors and tracebacks aren’t at all useful to end users. Django’s philosophy
is that site visitors should never see application-related error messages. If your code raises
an unhandled exception, a site visitor should not see the full traceback—or any hint of code
snippets or Python (programmer-oriented) error messages. Instead, the visitor should see a
friendly “This page is unavailable” message.
Naturally, of course, developers need to see tracebacks to debug problems in their code.
So the framework should hide all error messages from the public, but it should display them to
the trusted site developers.
The Solution
As we coveredÊÊ>«ÌiÀÊ£Ó]Ê>}½ÃÊ@A>QC setting controls the display of these error mes-
sages. Make sure to set this to B]hoa when you’re ready to deploy.
1ÃiÀÃÊ`i«Þ}Ê«>ViÊ>`Ê`Ú«ÞÌÊ>ÃÊÊ>«ÌiÀÊ£Ó®ÊÃÕ`Ê>ÃÊ>iÊÃÕÀiÊÌiÞÊ
have Lupdkj@a^qcKbb in their Apache conf files; this will suppress any errors that occur before
Django has had a chance to load.
A Final Word on Security
We hope all this talk of security problems isn’t too intimidating. It’s true that the Web can be a
wild world, but with a little bit of foresight, you can have a secure Web site.
Keep in mind that Web security is a constantly changing field; if you’re reading the dead-
tree version of this book, be sure to check more up-to-date security resources for any new
vulnerabilities that have been discovered. In fact, it’s always a good idea to spend some time
each week or month researching and keeping current on the state of Web application security.
It’s a small investment to make, but the protection you’ll get for your site and your users is
priceless.
What’s Next?
You’ve reached the end of our regularly scheduled program. The following appendixes all con-
tain reference material that you might need as you work on your Django projects.
We wish you the best of luck in running your Django site, whether it’s a little toy for you
and a few friends, or the next Google.
PART 4
Appendixes
353
APPENDIX A
Model Definition Reference
Chapter 5 explains the basics of defining models, and we use them throughout the rest of the
book. There is, however, a huge range of model options available not covered elsewhere. This
appendix explains each model definition option.
Note that although these APIs are considered stable, the Django developers consistently
add new shortcuts and conveniences to the model definition. It’s a good idea to always check
the latest documentation online at dppl6++`k_o*`f]jcklnkfa_p*_ki+.
Fields
The most important part of a model—and the only required part of a model—is the list of
database fields it defines.
FIELD NAME RESTRICTIONS
Django places only two restrictions on model field names:
s !FIELDNAMECANNOTBEA0YTHONRESERVEDWORDBECAUSETHATWOULDRESULTINA0YTHONSYNTAXERROR&OR
EXAMPLE
_h]ooAt]ilha$ik`aho*Ik`ah%6
l]oo9ik`aho*EjpacanBeah`$%#l]oo#eo]naoanra`skn`
s !FIELDNAMECANNOTCONTAINMORETHANONEUNDERSCOREINAROWBECAUSEOFTHEWAY$JANGOSQUERY
LOOKUPSYNTAXWORKS&OREXAMPLE
_h]ooAt]ilha$ik`aho*Ik`ah%6
bkk[[^]n9ik`aho*EjpacanBeah`$%#bkk[[^]n#d]opskqj`ano_knao
4HESELIMITATIONSCANBEWORKEDAROUNDTHOUGHBECAUSEYOURFIELDNAMEDOESNTNECESSARILYHAVETO
MATCHYOURDATABASECOLUMNNAME3EETHEhDB?COLUMNvSECTIONLATERINTHISAPPENDIX
31,RESERVEDWORDSSUCHASfkejsdanaORoaha_pareALLOWEDASMODELFIELDNAMESBECAUSE
$JANGOESCAPESALLDATABASETABLENAMESANDCOLUMNNAMESINEVERYUNDERLYING31,QUERY)TUSESTHEQUOT-
INGSYNTAXOFYOURPARTICULARDATABASEENGINE
APPENDIX A N MODEL DEFINITION REFERENCE
354
Each field in your model should be an instance of the appropriate Beah` class. Django uses
the field class types to determine a few things:
Ê UÊ /iÊ`>Ì>L>ÃiÊVÕÊÌÞ«iÊi°}°]ÊEJPACAN, R=N?D=N)
Ê UÊ /iÊÜ`}iÌÊÌÊÕÃiÊÊ>}½ÃÊvÀÃÊ>`Ê>`ÊÃÌiÊvÊÞÕÊV>ÀiÊÌÊÕÃiÊÌÊi°}°]Ê8ejlqp
pula9patp:, 8oaha_p:)
Ê UÊ /iÊ>ÊÛ>`>ÌÊÀiµÕÀiiÌÃ]ÊÜVÊ>ÀiÊÕÃi`ÊÊ>}½ÃÊ>`ÊÌiÀv>ViÊ>`Ê
by forms
A complete list of field classes follows, sorted alphabetically. Note that relationship fields
BknaecjGau, etc.) are handled in the next section.
AutoField
An EjpacanBeah` that automatically increments according to available IDs. You usually won’t
need to use this directly; a primary key field will automatically be added to your model if you
don’t specify otherwise.
BooleanField
A true/false field.
MYSQL USERS...
!"OOLEANFIELDIN-Y31,ISSTOREDASAPEJUEJPCOLUMNWITHAVALUEOFEITHERORMOSTDATABASESHAVE
a proper >KKHA=JTYPEINSTEAD3OFOR-Y31,ONLYWHENA>kkha]jBeah`ISRETRIEVEDFROMTHEDATABASE
ANDSTOREDONAMODELATTRIBUTEITWILLHAVETHEVALUESOF- or , instead of Pnqa or B]hoa
.ORMALLYTHISSHOULDNTBEAPROBLEMBECAUSE0YTHONGUARANTEESTHAT-99Pnqa and ,99B]hoa
AREBOTHTRUE*USTBECAREFULIFYOUREWRITINGSOMETHINGk^feoPnqaWHENk^fISAVALUEFROMA"OOLEAN
ATTRIBUTEONAMODEL)FTHATMODELWASCONSTRUCTEDUSINGTHEiuomhBACKENDTHEeoTESTWILLFAIL0REFERAN
EQUALITYTESTUSING99INCASESLIKETHIS
CharField
A string fieldÊvÀÊÃ>ÊÌÊ>À}iÃâi`ÊÃÌÀ}ðÊÀÊÛiÀÞÊ>À}iÊ>ÕÌÃÊvÊÌiÝÌ]ÊÕÃiÊPatpBeah`.)
?d]nBeah` has one extra required argument: i]t[hajcpd. This is the maximum length
ÊV>À>VÌiÀîÊvÊÌiÊvi`°Ê/iÊi]t[hajcpd is enforced at the database level and in Django’s
validation.
CommaSeparatedIntegerField
A field of integers separated by commas. As in ?d]nBeah`, the i]t[hajcpd argument is required.
APPENDIX A N MODEL DEFINITION REFERENCE 355
DateField
A date represented in Python by a `]papeia*`]pa instance.
DateTimeField
A date and time represented in Python by a `]papeia*`]papeia instance.
DecimalField
A fixed-precision decimal number represented in Python by a `a_ei]h*@a_ei]h instance. It has
two required arguments:
ÊUÊi]t[`ecepo is the maximum number of digits allowed in the number.
ÊUÊ`a_ei]h[lh]_a is the number of decimal places to store with the number.
ÀÊiÝ>«i]ÊÌÊÃÌÀiÊÕLiÀÃÊÕ«ÊÌÊÊÜÌÊ>ÊÀiÃÕÌÊvÊÓÊ`iV>Ê«>ViÃ]ÊÞÕ½`Ê
use this:
ik`aho*@a_ei]hBeah`$***(i]t[`ecepo91(`a_ei]h[lh]_ao9.%
And to store numbers up to approximately one billion with a resolution of ten decimal
places, use this:
ik`aho*@a_ei]hBeah`$***(i]t[`ecepo9-5(`a_ei]h[lh]_ao9-,%
When assigning to a @a_ei]hBeah`, use either a `a_ei]h*@a_ei]h object or a string, not a
Python float.
EmailField
A ?d]nBeah` that checks that the value is a valid e-mail address.
FileField
A file-upload field.
NNote 4HElnei]nu[gau and qjemqaARGUMENTSARENOTSUPPORTEDTHEYCREATEAPulaAnnknIFUSED
Has one required argument:
qlhk]`[pk
A local filesystem path that will be appended to your IA@E=[NKKP setting to determine the
value of the `f]jck*_kna*behao*Beha*qnh attribute.
This path may contain strftime formattingÊÃiiÊÌiÊ*ÞÌÊ`VÃÊvÀÊÌiÊpeia standard
LÀ>ÀÞÊ`Õi®]ÊÜVÊÜÊLiÊÀi«>Vi`ÊÕÃ}ÊÌiÊ`>ÌiÉÌiÊvÊÌiÊviÊÕ«>`ÊÃÊÌ>ÌÊ
uploaded files don’t fill up the given directory).
APPENDIX A N MODEL DEFINITION REFERENCE
356
It can also be a callable, such as a function, which will be called to obtain the upload path,
including the file name. This callable must be able to accept two arguments and return a
1ÝÃÌÞiÊ«>ÌÊÜÌÊvÀÜ>À`ÊÃ>ÃiîÊÌÊLiÊ«>ÃÃi`Ê>}ÊÌÊÌiÊÃÌÀ>}iÊÃÞÃÌi°Ê/iÊÌÜÊ
arguments that will be passed are shown in Table A-1.
Table A-1. Arguments Passed to Callable upload_to argument
Argument Description
ejop]j_a An instance of the model where the BehaBeah` is defined. More specifically, this is
the particular instance where the current file is being attached.
In most cases, this object will not have been saved to the database yet, so if it uses the
default =qpkBeah`, it might not yet have a value for its primary key field.
behaj]ia The file name that was originally given to the file. It may or may not be taken into
account when determining the final destination path.
It also has one optional argument:
opkn]ca
Optional: a storage object that handles the storage and retrieval of your files.
Using a BehaBeah` or an Ei]caBeah`ÊÃiiÊÌiÊEi]caBeah` section) in a model takes a few steps:
1. In your settings file, you’ll need to define IA@E=[NKKP as the full path to a directory in
ÜVÊÞÕÊÜ>ÌÊ>}ÊÌÊÃÌÀiÊÕ«>`i`ÊviðÊÀÊ«iÀvÀ>Vi]ÊÌiÃiÊviÃÊ>ÀiÊÌÊ
stored in the database.) Define IA@E=[QNH as the base public URL of that directory.
Make sure that this directory is writable by the Web server’s user account.
2. Add the BehaBeah` or Ei]caBeah` to your model, making sure to define the qlhk]`[pk
option to tell Django to which subdirectory of IA@E=[NKKP it should upload files.
3. ÊÌ>ÌÊÜÊLiÊÃÌÀi`ÊÊÞÕÀÊ`>Ì>L>ÃiÊÃÊ>Ê«>ÌÊÌÊÌiÊviÊÀi>ÌÛiÊÌÊIA@E=[NKKP).
You’ll most likely want to use the convenience qnhÊvÕVÌÊ«ÀÛ`i`ÊLÞÊ>}°ÊÀÊ
example, if your Ei]caBeah` is called iqc[odkp, you can get the absolute URL to your
image in a template with wwk^fa_p*iqc[odkp*qnhyy.
ÀÊiÝ>«i]ÊÃ>ÞÊÞÕÀÊIA@E=[NKKP is set to #+dkia+ia`e]#, and qlhk]`[pk is set to
#ldkpko+!U+!i+!`#. The #!U+!i+!`# part of qlhk]`[pk is strftime formatting; #!U# is the four-
digit year, #!i# is the two-digit month, and #!`# is the two-digit day. If you upload a file on
>Õ>ÀÞÊ£x]ÊÓääÇ]ÊÌÊÜÊLiÊÃ>Ûi`ÊÊÌiÊ`ÀiVÌÀÞÊ+dkia+ia`e]+ldkpko+.,,3+,-+-1.
If you want to retrieve the upload file’s on-disk file name, a URL that refers to that file,
or the file’s size, you can use the j]ia, qnh, and oeva attributes, respectively.
Note that whenever you deal with uploaded files, you should pay close attention to where
you’re uploading them, and what type of files they are, to avoid security holes. Be sure to vali-
`>ÌiÊ>ÊÕ«>`i`ÊviÃÊÃÊÌ>ÌÊÞÕ½ÀiÊÃÕÀiÊÌiÊviÃÊ>ÀiÊÜ>ÌÊÞÕÊÌÊÌiÞÊ>Ài°ÊÀÊiÝ>«i]ÊvÊ
you blindly let somebody upload files without validation to a directory that’s within your Web
server’s document root, somebody could upload a CGI or PHP script and execute that script by
visiting its URL on your site. Don’t allow that to happen.
By default, BehaBeah` instances are created as r]n_d]n$-,,% columns in your database.
As with other fields, you can change the maximum length using the i]t[hajcpd argument.
APPENDIX A N MODEL DEFINITION REFERENCE 357
FilePathField
A ?d]nBeah` whose choices are limited to the file names in a certain directory on the filesys-
tem. It has three special arguments, of which the first is required:
l]pd
Required. The absolute filesystem path to a directory from which this BehaL]pdBeah`
ÃÕ`Ê}iÌÊÌÃÊVViðÊÀÊiÝ>«i\Ê+dkia+ei]cao.
i]p_d
Optional. A regular expression, as a string, that BehaL]pdBeah` will use to filter file names.
ÌiÊÌ>ÌÊÌiÊÀi}iÝÊÜÊLiÊ>««i`ÊÌÊÌiÊL>ÃiÊviÊ>i]ÊÌÊÌiÊvÕÊ«>Ì°ÊÀÊiÝ>«i\Ê
bkk*&X*ptp , which will match a file called bkk./*ptp but not ^]n*ptp or bkk./*ceb.
na_qnoera
Optional. Either Pnqa or B]hoa. Default is B]hoa. Specifies whether all subdirectories of
l]pd should be included.
Of course, these arguments can be used together.
The one potential gotcha is that i]p_d applies to the base file name, not the full path.
So this example will match +dkia+ei]cao+^]n+bkk*ceb, but not +dkia+ei]cao+bkk+^]n*ceb
because the i]p_dÊ>««iÃÊÌÊÌiÊL>ÃiÊviÊ>iÊbkk*ceb and ^]n*ceb):
BehaL]pdBeah`$l]pd9+dkia+ei]cao(i]p_d9bkk*&(na_qnoera9Pnqa%
By default, BehaL]pdBeah` instances are created as r]n_d]n$-,,% columns in your
database. As with other fields, you can change the maximum length using the i]t[hajcpd
argument.
FloatField
A floating-point number represented in Python by a bhk]p instance.
ImageField
Similar to BehaBeah`, but validates that the uploaded object is a valid image. It has two extra
optional arguments:
daecdp[beah`
The name of a model field that will be autopopulated with the height of the image each
time the model instance is saved.
se`pd[beah`
The name of a model field that will be autopopulated with the width of the image each
time the model instance is saved.
In addition to the special attributes that are available for BehaBeah`, an Ei]caBeah` also
has daecdp and se`pd attributes, both of which correspond to the image’s height and width in
pixels.
APPENDIX A N MODEL DEFINITION REFERENCE
358
It requires the Python Imaging Library, available at dppl6++sss*lupdkjs]na*_ki+
lnk`q_po+leh+.
By default, Ei]caBeah` instances are created as r]n_d]n$-,,% columns in your database.
As with other fields, you can change the maximum length using the i]t[hajcpd argument.
IntegerField
An integer.
IPAddressField
An IP address in stringÊvÀ>ÌÊi°}°]Ê#-5.*,*.*/,#).
NullBooleanField
Similar to a >kkha]jBeah`, but allows JQHH as one of the options. Use this instead of a
>kkha]jBeah` with jqhh9Pnqa.
PositiveIntegerField
Similar to an EjpacanBeah`, but must be positive.
PositiveSmallIntegerField
Similar to a LkoeperaEjpacanBeah`, but allows only values under aÊViÀÌ>Ê`>Ì>L>Ãi
dependent) point.
SlugField
Slug, which is a newspaper term, is a short label for something, containing only letters,
numbers, underscores, or hyphens. Slugs are generally used in URLs.
Like a ?d]nBeah`, you can specify i]t[hajcpd. If i]t[hajcpd is not specified, Django will
ÕÃiÊ>Ê`iv>ÕÌÊi}ÌÊvÊxä°
It implies setting `^[ej`at to Pnqa.
SmallIntegerField
Similar to an EjpacanBeah`, but allows only values under aÊViÀÌ>Ê`>Ì>L>Ãi`i«i`i̮ʫÌ°
TextField
A large text field.
Also see ?d]nBeah` for storing smaller bits of text.
TimeField
A time represented in Python by a `]papeia*peia instance. Accepts the same autopopulation
options as @]paBeah`.
APPENDIX A N MODEL DEFINITION REFERENCE 359
URLField
A ?d]nBeah` for a URL; it has one extra optional argument:
ranebu[ateopo
If PnqaÊÌiÊ`iv>ÕÌ®]ÊÌiÊ1,Ê}ÛiÊÜÊLiÊViVi`ÊvÀÊiÝÃÌiViÊ°i°]ÊÌiÊ1,Ê>VÌÕ>ÞÊ
>`ÃÊ>`Ê`iÃ½ÌÊ}ÛiÊ>Ê{ä{ÊÀiëÃi®°ÊÌÊÃÕ`ÊLiÊÌi`ÊÌ>ÌÊÜiÊÕÃ}ÊÌiÊÃ}i
threaded development server, validating a URL being served by the same server will hang.
This should not be a problem for multithreaded servers.
Like all ?d]nBeah` subclasses, QNHBeah` takes the optional i]t[hajcpd argument. If you
don’t specify i]t[hajcpd, a default of .,, is used.
XMLField
A PatpBeah` that checks whether the value is valid XML that matches a given schema. Takes
one required argument:
o_dai][l]pd
The filesystem path to a RelaxNG schema against which to validateÊÌiÊvi`°ÊÀÊÀiÊÊ
RelaxNG, see dppl6++sss*nah]tjc*knc+.
Universal Field Options
The following arguments are available to all field types. All are optional.
null
If Pnqa, Django will store empty values as JQHH in the database. If B]hoa, saving empty values
will likely result in a database error. The default is B]hoa.
Note that empty string values will always get stored as empty strings, not as JQHH. Use
jqhh9PnqaÊÞÊvÀÊÃÌÀ}Êvi`ÃÊÃÕVÊ>ÃÊÌi}iÀÃ]Êi>Ã]Ê>`Ê`>ÌiðÊÀÊLÌÊÌÞ«iÃÊvÊ
fields, you will also need to set ^h]jg9Pnqa if you want to permit empty values in forms because
the jqhhÊ«>À>iÌiÀÊ>vviVÌÃÊÞÊ`>Ì>L>ÃiÊÃÌÀ>}iÊÃiiÊ^h]jg).
Avoid using jqhh on string-based fields such as ?d]nBeah` and PatpBeah` unless you have
an excellent reason. If a string-based field has jqhh9Pnqa, that means it has two possible values
for “no data”: JQHH and the empty string. In most cases, it’s redundant to have two possible
values for “no data”; Django’s convention is to use the empty string, not JQHH.
NNote 7HENUSINGTHE/RACLEDATABASEBACKENDTHEjqhh9Pnqa optionWILLBECOERCEDFORSTRING
BASEDFIELDSTHATHAVETHEEMPTYSTRINGASAPOSSIBLEVALUEANDTHEVALUEJQHHWILLBESTOREDTODENOTE
THEEMPTYSTRING
ÀÊÀiÊÊÌÃ]ÊÀiviÀÊÌÊÌiÊÃiVÌʺ>}Ê>ÌiÊ>`Ê ÕiÀVÊi`ÃÊ"«Ì>»ÊÊ
Chapter 6.
APPENDIX A N MODEL DEFINITION REFERENCE
360
blank
If Pnqa, the field is allowed to be blank. The default is B]hoa.
Note that this is different from jqhh. jqhh is purely database-related, whereas ^h]jg is
validation-related. If a field has ^h]jg9Pnqa, validation on Django’s admin site will allow entry
of an empty value. If a field has ^h]jg9B]hoa, the field will be required.
choices
AnÊÌiÀ>LiÊi°}°]Ê>ÊÃÌÊÀÊÌÕ«i®ÊvÊÌÜÌÕ«iÃÊÌÊÕÃiÊ>ÃÊVViÃÊvÀÊÌÃÊvi`°
A _dke_ao list looks like this:
UA=N[EJ[O?DKKH[?DKE?AO9$
$#BN#(#Bnaodi]j#%(
$#OK#(#Okldkikna#%(
$#FN#(#Fqjekn#%(
$#ON#(#Oajekn#%(
$#CN#(#Cn]`q]pa#%(
%
The first element in each tuple is the actual value to be stored. The second element is the
human-readable name for the option.
The _dke_ao list can be defined as part of your model class:
_h]ooBkk$ik`aho*Ik`ah%6
CAJ@AN[?DKE?AO9$
$#I#(#I]ha#%(
$#B#(#Bai]ha#%(
%
caj`an9ik`aho*?d]nBeah`$i]t[hajcpd9-(_dke_ao9CAJ@AN[?DKE?AO%
It can also be defined outside your model class altogether:
CAJ@AN[?DKE?AO9$
$#I#(#I]ha#%(
$#B#(#Bai]ha#%(
%
_h]ooBkk$ik`aho*Ik`ah%6
caj`an9ik`aho*?d]nBeah`$i]t[hajcpd9-(_dke_ao9CAJ@AN[?DKE?AO%
You can also collect your available choices into named groups that can be used for organi-
zational purposes in a form:
IA@E=[?DKE?AO9$
$#=q`ek#($
$#rejuh#(#Rejuh#%(
$#_`#(#?@#%(
%
%(
APPENDIX A N MODEL DEFINITION REFERENCE 361
$#Re`ak#($
$#rdo#(#RDOP]la#%(
$#`r`#(#@R@#%(
%
%(
$#qjgjksj#(#Qjgjksj#%(
%
The first element in each tuple is the name to apply to the group. The second element is
an iterable of two-tuples, with each two-tuple containing a value and a human-readable name
for an option. Grouped options can be combined with ungrouped options within a single list
ÃÕVÊ>ÃÊÌiÊunknown option in this example).
>Þ]ÊÌiÊÌ>ÌÊVViÃÊV>ÊLiÊ>ÞÊÌiÀ>LiÊLiVÌpÌÊiViÃÃ>ÀÞÊ>ÊÃÌÊÀÊÌÕ«i°Ê/ÃÊ
lets you construct choices dynamically. But if you find yourself hacking _dke_ao to be dynamic,
you’re probably better off using a proper database table with a BknaecjGau. _dke_ao is meant
for static data that doesn’t change much, if ever.
db_column
The name of the database column to use for this field. If it isn’t given, Django will use the
field’s name.
If your database column name is an SQL-reserved word or contains characters that aren’t
allowed in Python variable names—notably, the hyphen—that’s okay. Django quotes column
and table names behind the scenes.
db_index
If Pnqa, `f]jck)]`iej*luomhej`atao will output a ?NA=PAEJ@AT statement for this field.
db_tablespace
The name of the database tablespace to use for this field’s index if this field is indexed. The
default is the project’s @AB=QHP[EJ@AT[P=>HAOL=?A setting, if set; or the `^[p]^haol]_a of the
model, if any. If the back-end doesn’t support tablespaces, this option is ignored.
default
The default value for the field; it can be a value or a callable object. If callable, it will be called
every time a new object is created.
editable
If B]hoa, the field will not be editable in the admin or via forms automatically generated from
the model class. Default is Pnqa.
help_text
Extra “help” text to be displayed under the field on the object’s admin form. It’s useful for
documentation even if your object doesn’t have an admin form.
APPENDIX A N MODEL DEFINITION REFERENCE
362
Note that this value is not HTML-escaped when it’s displayed in the admin interface. This
lets you include HTML in dahl[patpÊvÊÞÕÊÃÊ`iÃÀi°ÊÀÊiÝ>«i\
dahl[patp9Lha]oaqoapdabkhhksejcbkni]p68ai:UUUU)II)@@8+ai:*
Alternatively, you can use plain text and `f]jck*qpeho*dpih*ao_]la$% to escape any
HTML special characters.
primary_key
If Pnqa, this field is the primary key for the model.
If you don’t specify lnei]nu[gau9Pnqa for any fields in your model, Django will automati-
cally add an =qpkBeah` to hold the primary key, so you don’t need to set lnei]nu[gau9Pnqa on
any of your fields unless you want to override the default primary key behavior.
lnei]nu[gau9Pnqa implies jqhh9B]hoa and qjemqa9Pnqa. Only one primary key is allowed
on an object.
unique
If Pnqa, this field must be unique throughout the table.
This is enforced at the database level and at the level of forms created with Ik`ahBkni
VÕ`}ÊvÀÃÊÊÌiÊ>}Ê>`ÊÃÌi®°ÊvÊÞÕÊÌÀÞÊÌÊÃ>ÛiÊ>Ê`iÊÜÌÊ>Ê`Õ«V>ÌiÊÛ>ÕiÊÊ
a qjemqa field, an EjpacnepuAnnkn will be raised by the model’s o]ra method.
This option is valid on all field types except I]juPkI]juBeah`, BehaBeah`, and Ei]caBeah`.
unique_for_date
Set this to the name of a @]paBeah` or @]paPeiaBeah` to require that this field be unique for the
value of the date field.
ÀÊiÝ>«i]ÊvÊÞÕÊ>ÛiÊ>Êvi`Êpepha that has qjemqa[bkn[`]pa9lq^[`]pa, Django
wouldn’t allow the entry of two records with the same pepha and lq^[`]pa.
This is enforced at the level of forms created with Ik`ahBkniÊVÕ`}ÊvÀÃÊÊÌiÊ
Django admin site), but not at the database level.
unique_for_month
Similar to qjemqa[bkn[`]pa, but requires the field to be unique with respect to the month.
unique_for_year
Similar to qjemqa[bkn[`]pa and qjemqa[bkn[ikjpd.
verbose_name
A human-readable name for the field. If the verbose name isn’t given, Django will automati-
cally create it using the field’s attribute name, converting underscores to spaces.
APPENDIX A N MODEL DEFINITION REFERENCE 363
Relationships
Clearly, the power of relational databases lies in relating tables to each other. Django offers
ways to define the three most common types of database relationships: many-to-one, many-
to-many, and one-to-one.
ForeignKey
A many-to-one relationship. Requires a positional argument: the class to which the model is
related.
To create a recursive relationship—an object that has a many-to-one relationship with
itself—use ik`aho*BknaecjGau$#oahb#%.
If you need to create a relationship on a model that has not yet been defined, you can use
the name of the model instead of the model object itself:
_h]oo?]n$ik`aho*Ik`ah%6
i]jqb]_pqnan9ik`aho*BknaecjGau$#I]jqb]_pqnan#%
***
_h]ooI]jqb]_pqnan$ik`aho*Ik`ah%6
***
Note, however, that this refers only to models in the same ik`aho*lu file. To refer to mod-
els defined in another application, you must instead explicitly specify the application label.
ÀÊiÝ>«i]ÊvÊÌiÊI]jqb]_pqnan model is defined in another application called lnk`q_pekj,
you’d need to use the following:
_h]oo?]n$ik`aho*Ik`ah%6
i]jqb]_pqnan9ik`aho*BknaecjGau$#lnk`q_pekj*I]jqb]_pqnan#%
Behind the scenes, Django appends [e` to the field name to create its database column
name. In the preceding example, the database table for the ?]n model will have a i]jqb]_pqnan[
e`ÊVÕ°Ê9ÕÊV>ÊV>}iÊÌÊiÝ«VÌÞÊLÞÊëiVvÞ}Ê`^[_khqij.) However, your code should
never have to deal with the database column name unless you write custom SQL. You’ll always
deal with the field names of your model object.
BknaecjGau accepts an extra set of arguments—all optional—which define the details of
how the relation works.
heiep[_dke_ao[pk
A dictionary of lookup arguments and values that limit the available admin choices for
this object. Use this with functions from the Python `]papeia module to limit choices of
LiVÌÃÊLÞÊ`>Ìi°ÊÀÊiÝ>«i]ÊÌiÊvÜ}Ê>ÜÃÊÞÊÌiÊVViÊvÊÀi>Ìi`ÊLiVÌÃÊÜÌÊ>Ê
lq^[`]pa before the current date/time to be chosen:
heiep[_dke_ao[pk9w#lq^[`]pa[[hpa#6`]papeia*jksy
heiep[_dke_ao[pkÊ>ÃÊÊivviVÌÊÊÌiÊiÊÀ-iÌÃÊÌ>ÌÊ>ÀiÊVÀi>Ìi`ÊÌÊ`ë>ÞÊÀi>Ìi`Ê
objects in the admin.
APPENDIX A N MODEL DEFINITION REFERENCE
364
nah]pa`[j]ia
The name to use for the relation from the related object back to this one.
pk[beah`
The field on the related object that the relation is to. By default, Django uses the primary
key of the related object.
ManyToManyField
A many-to-many relationship. Requires a positional argument: the class to which the model is
related. This works exactly the same as it does for BknaecjGau, including all the options regard-
ing recursive relationships and lazy relationships.
Behind the scenes, Django creates an intermediary join table to represent the many-to-
many relationship. By default, this table name is generated using the names of the two tables
being joined. Because some databases don’t support table names above a certain length, these
table names will be automatically truncated to 64 characters, and a uniqueness hash will be
used. This means you might see table names such as ]qpdkn[^kkgo[5_`b0; this is perfectly nor-
mal. You can manually provide the name of the join table using the `^[p]^ha option.
I]juPkI]juBeah` accepts an extra set of arguments—all optional—that control how the
relationship functions:
nah]pa`[j]ia
Same as nah]pa`[j]ia in BknaecjGau.
heiep[_dke_ao[pk
Same as heiep[_dke_ao[pk in BknaecjGau.
heiep[_dke_ao[pk has no effect when used on a I]juPkI]juBeah` with a custom intermedi-
ate table specified using the pdnkqcd parameter.
ouiiapne_]h
Only used in the definition of I]juPkI]juBeah` on oahb. Consider the following model:
_h]ooLanokj$ik`aho*Ik`ah%6
bneaj`o9ik`aho*I]juPkI]juBeah`$oahb%
When Django processes this model, it identifies that it has a I]juPkI]juBeah` on itself, so
it doesn’t add a lanokj[oap attribute to the Lanokj class. Instead, the I]juPkI]juBeah` is
>ÃÃÕi`ÊÌÊLiÊÃÞiÌÀV>ÊvÊÊ>ÊÞÕÀÊvÀi`]ÊÞÕÊ>ÀiÊÞÊvÀi`®°
If you do not want symmetry in many-to-many relationships with oahb, set ouiiapne_]h
to B]hoa. This will force Django to add the descriptor for the reverse relationship, allowing
I]juPkI]juBeah` relationships to be nonsymmetrical.
pdnkqcd
Django will automatically generate a table to manage many-to-many relationships.
However, if you want to manually specify the intermediary table, you can use the pdnkqcd
option to specify the Django model that represents the intermediate table that you want
to use.
APPENDIX A N MODEL DEFINITION REFERENCE 365
The most common use for this option is when you want to associate extra data with a
many-to-many relationship.
`^[p]^ha
The name of the table to create for storing the many-to-many data. If it is not provided,
Django will assume a default name based on the names of the two tables being joined.
OneToOneField
A one-to-one relationship. Conceptually, this is similar to a BknaecjGau with qjemqa9Pnqa, but
the “reverse” side of the relation will directly return a single object.
This is most useful as the primary key of a model that “extends” another model in some
way; multitable inheritance is implemented by adding an implicit one-to-one relationship
from the child model to the parent model, for example.
One positional argument is required: the class to which the model will be related. This
works exactly the same as it does for BknaecjGau, including all the options regarding recursive
relationships and lazy relationships.
Additionally, KjaPkKjaBeah` accepts all the extra arguments accepted by BknaecjGau, plus
one extra argument:
l]najp[hejg
When PnqaÊ>`ÊÕÃi`ÊÊ>Ê`iÊÌ>ÌÊiÀÌÃÊvÀÊ>ÌiÀÊVVÀiÌi®Ê`i]Ê`V>ÌiÃÊ
that this field should be used as the link back to the parent class instead of the extra
KjaPkKjaBeah`, which would normally be implicitly created by subclassing.
Model Metadata Options
Model-specific metadata lives in a _h]ooIap] defined in the body of your model class:
_h]oo>kkg$ik`aho*Ik`ah%6
pepha9ik`aho*?d]nBeah`$i]thajcpd9-,,%
_h]ooIap]6
ik`ahiap]`]p]klpekjockdana
***
Model metadata is “anything that’s not a field,” such as ordering options and so forth.
The sections that follow present a list of all possible Iap] options. No options are required.
Adding _h]ooIap] to a model is completely optional.
abstract
If Pnqa, this model will be an abstract base class. See the Django documentation for more on
abstract base classes.
APPENDIX A N MODEL DEFINITION REFERENCE
366
db_table
The name of the database table to use for the model:
`^[p]^ha9#iqoe_[]h^qi#
Table names
To save time, Django automatically derives the name of the database table from the name of
the model class and the app that contains it. A model’s database table name is constructed
by joining the model’s app label—the name you used in i]j]ca*luop]np]ll—to the model’s
class name, with an underscore between them.
ÀÊiÝ>«i]ÊvÊÞÕÊ>ÛiÊ>Ê>««Ê^kkgopknaÊ>ÃÊVÀi>Ìi`ÊLÞÊi]j]ca*luop]np]ll^kkgopkna),
a model defined as _h]oo>kkg will have a database table named ^kkgopkna[^kkg.
To override the database table name, use the `^[p]^ha parameter in _h]ooIap].
If your database table name is an SQL-reserved word or contains characters that aren’t
allowed in Python variable names—notably, the hyphen—that’s okay. Django quotes column
and table names behind the scenes.
db_tablespace
The name of the database tablespace to use for the model. If the back-end doesn’t support
tablespaces, this option is ignored.
get_latest_by
The name of a @]paBeah` or @]paPeiaBeah` in the model. This specifies the default field to use
in the model I]j]can h]paop method.
À example:
cap[h]paop[^u9kn`an[`]pa
managed
Defaults to Pnqa, meaning that Django will create the appropriate database tables in
`f]jck)]`iej*luouj_`^ and remove them as part of a naoap management command. That
is, Django manages the database tables’ life cycles.
If B]hoa, no database table creation or deletion operations will be performed for this
model. This is useful if the model represents an existing table or a database view that has
been created by some other means. This is the only difference when i]j]ca` is B]hoa. All other
aspects of model handling are exactly the same as normal, including the following:
APPENDIX A N MODEL DEFINITION REFERENCE 367
Ê UÊ ``}Ê>Ê>ÕÌ>ÌVÊ«À>ÀÞÊiÞÊvi`ÊÌÊÌiÊ`iÊvÊÞÕÊ`½ÌÊ`iV>ÀiÊÌ°Ê/Ê>Û`Ê
confusion for later code readers, it’s recommended that you specify all the columns
from the database table you are modeling when using unmanaged models.
Ê UÊ vÊ>Ê`iÊÜÌÊi]j]ca`9B]hoa contains a I]juPkI]juBeah` that points to another
unmanaged model, the intermediary table for the many-to-many join will also not be
created. However, the intermediary table between one managed and one unmanaged
model will be created.
If you need to change this default behavior, create the intermediary table as an explicit
`iÊÜÌÊi]j]ca` set as needed) and use the pdnkqcd attribute to make the relation
use your custom model.
ÀÊÌiÃÌÃÊÛÛ}Ê`iÃÊÜÌÊi]j]ca`9B]hoa, it’s up to you to ensure the correct tables
are created as part of the test setup.
If you’re interested in changing the Python-level behavior of a model class, you could use
i]j]ca`9B]hoa and create a copy of an existing model. However, there’s a better approach for
that situation: proxy models.
ordering
The default ordering for the object, for use when obtaining lists of objects:
kn`anejc9W#)kn`an[`]pa#Y
This is a tuple or list of strings. Each string is a field name with an optional ) prefix, which
`V>ÌiÃÊ`iÃVi`}ÊÀ`iÀ°Êi`ÃÊÜÌÕÌÊ>Êi>`}Ê) will be ordered ascending. Use the
string ; to order randomly.
NNote 2EGARDLESSOFHOWMANYFIELDSAREINkn`anejcTHEADMINSITEUSESONLYTHEFIRSTFIELD
ÀÊiÝ>«i]ÊÌÊÀ`iÀÊLÞÊ>Êlq^[`]pa field ascending, use this:
kn`anejc9W#lq^[`]pa#Y
To order by lq^[`]pa descending, use this:
kn`anejc9W#)lq^[`]pa#Y
To order by lq^[`]pa descending and then by ]qpdkn ascending, use this:
kn`anejc9W#)lq^[`]pa#(#]qpdkn#Y
APPENDIX A N MODEL DEFINITION REFERENCE
368
proxy
If set to Pnqa, aÊ`iÊÌ>ÌÊÃÕLV>ÃÃiÃÊ>ÌiÀÊ`iÊÜÊLiÊÌÀi>Ìi`Ê>ÃÊ>Ê«ÀÝÞÊ`i°ÊÀÊ
more on proxy models, see the Django documentation.
unique_together
Sets of field names that, when taken together, must be unique:
qjemqa[pkcapdan9$$`neran(naop]qn]jp%(%
This is a list of lists of fields that must be unique when considered together. It’s used by
Ik`ahBkniÊvÀÃÊVÕ`}ÊvÀÃÊÊÌiÊ>}Ê>`ÊÃÌi®Ê>`ÊÃÊivÀVi`Ê>ÌÊÌiÊ`>Ì>L>ÃiÊ
iÛiÊ°i°]ÊÌiÊ>««À«À>ÌiÊQJEMQA statements are included in the ?NA=PAP=>HA statement).
ÀÊVÛiiVi]Êqjemqa[pkcapdan can be a single sequence when dealing with a single set
of fields:
qjemqa[pkcapdan9$`neran(naop]qn]jp%
verbose_name
A human-readable name for the object, singular:
ran^koa[j]ia9levv]
If this isn’t given, Django will use a munged version of the class name: ?]iah?]oa becomes
_]iah_]oa.
verbose_name_plural
The plural name for the object:
ran^koa[j]ia[lhqn]h9opkneao
If this isn’t given, Django will use ran^koa[j]ia + o.
APPENDIX B
Database API Reference
Django’s database API is the other half of the model API discussed in Appendix A. Once
you’ve defined a model, you’ll use this API any time you need to access the database. You’ve
seen examples of this API in use throughout the book; this appendix explains all the various
options in detail.
Like the model APIs discussed in Appendix A, although these APIs are considered very sta-
ble, the Django developers consistently add new shortcuts and conveniences. It’s a good idea to
always check the latest documentation online, available at dppl6++`k_o*`f]jcklnkfa_p*_ki+.
Throughout this reference, we’ll refer to the following models, which might form a simple
blog application:
bnki`f]jck*`^eilknpik`aho
_h]oo>hkc$ik`aho*Ik`ah%6
j]ia9ik`aho*?d]nBeah`$i]t[hajcpd9-,,%
p]cheja9ik`aho*PatpBeah`$%
`ab[[qje_k`a[[$oahb%6
napqnjoahb*j]ia
_h]oo=qpdkn$ik`aho*Ik`ah%6
j]ia9ik`aho*?d]nBeah`$i]t[hajcpd91,%
ai]eh9ik`aho*Ai]ehBeah`$%
`ab[[qje_k`a[[$oahb%6
napqnjoahb*j]ia
_h]ooAjpnu$ik`aho*Ik`ah%6
^hkc9ik`aho*BknaecjGau$>hkc%
da]`heja9ik`aho*?d]nBeah`$i]t[hajcpd9.11%
^k`u[patp9ik`aho*PatpBeah`$%
lq^[`]pa9ik`aho*@]paPeiaBeah`$%
]qpdkno9ik`aho*I]juPkI]juBeah`$=qpdkn%
`ab[[qje_k`a[[$oahb%6
napqnjoahb*da]`heja
369
APPENDIX B N DATABASE API REFERENCE
370
Creating Objects
To create an object, instantiate it using keyword arguments to the model class, and then call
o]ra$% to save it to the database:
:::bnkiiuoepa*^hkc*ik`ahoeilknp>hkc
:::^9>hkc$j]ia9#>a]phao>hkc#(p]cheja9#=hhpdah]paop>a]phaojaso*#%
:::^*o]ra$%
This performs an EJOANP SQL statement behind the scenes. Django doesn’t hit the data-
base until you explicitly call o]ra$%. The o]ra$% method has no return value.
To create an object and save it all in one step, see the _na]pa manager method.
What Happens When You Save?
When you save an object, Django performs the following steps:
1. Emit a lna[o]ra signal: This provides a notification that an object is about to be saved.
You can register a listener that will be invoked whenever this signal is emitted. Check
the online documentation for more on signals.
2. Preprocess the data: Each field on the object is asked to perform any automated data
modification that the field may need to perform.
Most fields do no preprocessing—the field data is kept as is. Preprocessing is used only
on fields that have special behavior, like file fields.
3. Prepare the data for the database: Each field is asked to provide its current value in a
data type that can be written to the database.
Most fields require no data preparation. Simple data types, such as integers and
strings, are “ready to write” as a Python object. However, more-complex data types
often require some modification. For example, @]paBeah`o use a Python `]papeia
object to store data. Databases don’t store `]papeia objects, so the field value must be
converted into an ISO-compliant date string for insertion into the database.
4. Insert the data into the database: The preprocessed, prepared data is composed into an
SQL statement for insertion into the database.
5. Emit a lkop[o]ra signal: As with the lna[o]ra signal, this is used to provide notification
that an object has been saved successfully.
Autoincrementing Primary Keys
For convenience, each model is given an autoincrementing primary-key field named e`
unless you explicitly specify lnei]nu[gau9Pnqa on a field (see the section titled “AutoField”
in Appendix A).
APPENDIX B N DATABASE API REFERENCE 371
If your model has an =qpkBeah`, that autoincremented value will be calculated and saved
as an attribute on your object the first time you call o]ra$%:
:::^.9>hkc$j]ia9#?da``]nP]hg#(p]cheja9#Pdkqcdpokj_daaoa*#%
:::^.*e`NapqnjoJkja(^a_]qoa^`kaoj#pd]ra]jE@uap*
Jkja
:::^.*o]ra$%
:::^.*e`NapqnjopdaE@kbukqnjask^fa_p*
-0
There’s no way to tell what the value of an ID will be before you call o]ra$%, because that
value is calculated by your database, not by Django.
If a model has an =qpkBeah` but you want to define a new object’s ID explicitly when sav-
ing, define it explicitly before saving, rather than relying on the autoassignment of the ID:
:::^/9>hkc$e`9/(j]ia9#?da``]nP]hg#(p]cheja9#Pdkqcdpokj_daaoa*#%
:::^/*e`
/
:::^/*o]ra$%
:::^/*e`
/
If you assign auto–primary-key values manually, make sure not to use an existing primary-
key value! If you create a new object with an explicit primary-key value that already exists in the
database, Django will assume you’re changing the existing record rather than creating a new one.
Given the preceding #?da``]nP]hg# blog example, this example would override the previ-
ous record in the database:
:::^09>hkc$e`9/(j]ia9#Jkp?da``]n#(p]cheja9#=jupdejc^qp_daaoa*#%
:::^0*o]ra$%Kranne`aopdalnarekqo^hkcsepdE@9/
Explicitly specifying auto–primary-key values is mostly useful for bulk-saving objects,
when you’re confident you won’t have primary-key collision.
Saving Changes to Objects
To save changes to an object that’s already in the database, use o]ra$%.
Given a >hkc instance ^1 that has already been saved to the database, this example
changes its name and updates its record in the database:
:::^1*j]ia9#Jasj]ia#
:::^1*o]ra$%
This performs an QL@=PA SQL statement behind the scenes. Again, Django doesn’t hit the
database until you explicitly call o]ra$%.
APPENDIX B N DATABASE API REFERENCE
372
HOW DJANGO KNOWS WHEN TO UPDATE AND WHEN TO INSERT
You may have noticed that Django database objects use the same o]ra$% method for creating and changing
objects. Django abstracts the need to use EJOANP or QL@=PA SQL statements. Specifically, when you call
o]ra$%, Django follows this algorithm:
s )FTHEOBJECTSPRIMARYKEYATTRIBUTEISSETTOAVALUETHATEVALUATESTOPnqa (i.e., a value other than
Jkja or the empty string), Django executes a OAHA?P query to determine whether a record with the
GIVENPRIMARYKEYALREADYEXISTS
s )FTHERECORDWITHTHEGIVENPRIMARYKEYDOESALREADYEXIST$JANGOEXECUTESANQL@=PA query.
s )FTHEOBJECTSPRIMARYKEYATTRIBUTEISnotSETORIFITSSETBUTARECORDDOESNTEXIST$JANGOEXECUTES
an EJOANP.
9OUSHOULDBECAREFULNOTTOSPECIFYAPRIMARYKEYVALUEEXPLICITLYWHENSAVINGNEWOBJECTSIFYOU
CANNOTGUARANTEETHEPRIMARYKEYVALUEISUNUSED
Updating BknaecjGau fields works exactly the same way; simply assign an object of the
right type to the field in question:
:::fka9=qpdkn*k^fa_po*_na]pa$j]ia9Fka%
:::ajpnu*]qpdkn9fka
:::ajpnu*o]ra$%
Django will complain if you try to assign an object of the wrong type.
Retrieving Objects
Throughout this book you’ve seen objects retrieved using code like the following:
:::^hkco9>hkc*k^fa_po*behpan$]qpdkn[[j]ia[[_kjp]ejo9Fka%
There are quite a few “moving parts” behind the scenes here: when you retrieve objects
from the database, you’re actually constructing a MqanuOap using the model’s I]j]can. This
MqanuOap knows how to execute SQL and return the requested objects.
Appendix A looked at both MqanuOap and I]j]can from a model-definition point of view;
now we’ll look at how they operate.
A MqanuOap represents a collection of objects from your database. It can have zero, one,
or many filters—criteria that narrow down the collection based on given parameters. In SQL
terms, a MqanuOap equates to a OAHA?P statement, and a filter is a SDANA.
You get a MqanuOap by using your model’s I]j]can. Each model has at least one I]j]can,
and it’s called k^fa_po by default. Access it directly via the model class, like so:
:::>hkc*k^fa_po
8`f]jck*`^*ik`aho*i]j]can*I]j]cank^fa_p]p,t-/3`,,`:
APPENDIX B N DATABASE API REFERENCE 373
I]j]cans are accessible only via model classes, rather than from model instances, to
enforce a separation between table-level operations and record-level operations:
:::^9>hkc$j]ia9#Bkk#(p]cheja9#>]n#%
:::^*k^fa_po
Pn]_a^]_g$ikopna_ajp_]hhh]op%6
Beha8op`ej:(heja-(ej8ik`qha:
=ppne^qpaAnnkn6I]j]caneoj#p]__aooe^hare]>hkcejop]j_ao*
The I]j]can is the main source of MqanuOaps for a model. It acts as a “root” MqanuOap that
describes all objects in the model’s database table. For example, >hkc*k^fa_po is the initial
MqanuOap that contains all >hkc objects in the database.
Caching and QuerySets
Each MqanuOap contains a cache to minimize database access. To write the most efficient code,
it’s important to understand how MqanuOap caching works.
In a newly created MqanuOap, the cache is empty. The first time a MqanuOap is evaluated—
and, hence, a database query happens—Django saves the query results in the MqanuOap’s
cache and returns the results that have been explicitly requested (e.g., the next element,
if the MqanuOap is being iterated over). Subsequent evaluations of the MqanuOap reuse the
cached results.
Keep this caching behavior in mind, because it may bite you if you don’t use your
MqanuOaps correctly. For example, the following will create two MqanuOaps, evaluate them,
and throw them away:
lnejpWa*da]`hejabknaejAjpnu*k^fa_po*]hh$%Y
lnejpWa*lq^[`]pabknaejAjpnu*k^fa_po*]hh$%Y
That means the same database query will be executed twice, effectively doubling your
database load. Also, there’s a possibility the two lists may not include the same database
records, because an Ajpnu may have been added or deleted in the split second between the
two requests.
To avoid this problem, simply save the MqanuOap and reuse it:
mqanuoap9Lkhh*k^fa_po*]hh$%
lnejpWl*da]`hejabknlejmqanuoapYAr]hq]papdamqanuoap*
lnejpWl*lq^[`]pabknlejmqanuoapYNaqoapda_]_dabnkipdaar]hq]pekj*
Filtering Objects
The simplest way to retrieve objects from a table is to get all of them. To do this, use the ]hh$%
method on a I]j]can:
:::Ajpnu*k^fa_po*]hh$%
The ]hh$% method returns a MqanuOap of all the objects in the database.
APPENDIX B N DATABASE API REFERENCE
374
Usually, though, you’ll need to select only a subset of the complete set of objects. To cre-
ate such a subset, you refine the initial MqanuOap, adding filter conditions. You’ll usually do this
using the behpan$% and/or at_hq`a$% methods:
:::u.,,29Ajpnu*k^fa_po*behpan$lq^[`]pa[[ua]n9.,,2%
:::jkp.,,29Ajpnu*k^fa_po*at_hq`a$lq^[`]pa[[ua]n9.,,2%
behpan$% and at_hq`a$% both take field lookup arguments, which are discussed in detail in
the “Field Lookups” section of this appendix.
Chaining Filters
The result of refining a MqanuOap is itself a MqanuOap, so it’s possible to chain refinements
together, as in this example:
:::mo9Ajpnu*k^fa_po*behpan$da]`heja[[op]nposepd9#Sd]p#%
:::mo9mo*at_hq`a$lq^[`]pa[[cpa9`]papeia*`]papeia*jks$%%
:::mo9mo*behpan$lq^[`]pa[[cpa9`]papeia*`]papeia$.,,1(-(-%%
This takes the initial MqanuOap of all entries in the database, adds a filter, then an exclusion,
and then another filter. The final result is a MqanuOap containing all entries with a headline that
starts with “What” that were published between January 1, 2005, and the current day.
It’s important to point out here that MqanuOapo are lazy—the act of creating a MqanuOap
doesn’t involve any database activity. In fact, the three preceding lines don’t make any data-
base calls; you can chain filters together all day long and Django won’t actually run the query
until the MqanuOap is evaluated.
You can evaluate a MqanuOap in any of the following ways:
ÊUÊIterating: A MqanuOap is iterable, and it executes its database query the first time you
iterate over it. For example, the following MqanuOap isn’t evaluated until it’s iterated
over in the bkn loop:
mo9Ajpnu*k^fa_po*behpan$lq^[`]pa[[ua]n9.,,2%
mo9mo*behpan$da]`heja[[e_kjp]ejo9^ehh%
bknaejmo6
lnejpa*da]`heja
This prints all headlines from 2006 that contain “bill” but causes only one database hit.
ÊUÊPrinting: A MqanuOap is evaluated when you call naln$% on it. This is for convenience in
the Python interactive interpreter, so you can immediately see your results when using
the API interactively.
ÊUÊSlicing: As explained in the upcoming “Limiting QuerySets” section, a MqanuOap can be
sliced using Python’s array-slicing syntax. Usually slicing a MqanuOap returns another
(unevaluated) MqanuOap, but Django will execute the database query if you use the opal
parameter of Python’s slice syntax.
ÊUÊConverting to a list: You can force evaluation of a MqanuOap by calling heop$% on it, as in
this example:
:::ajpnu[heop9heop$Ajpnu*k^fa_po*]hh$%%
APPENDIX B N DATABASE API REFERENCE 375
Be warned, though, that this could have a large memory overhead, because Django will
load each element of the list into memory. In contrast, iterating over a MqanuOap will take
advantage of your database to load data and instantiate objects only as you need them.
FILTERED QUERYSETS ARE UNIQUE
Each time you refine a MqanuOapYOUGETABRANDNEWMqanuOap that is in no way bound to the previous
one. Each refinement creates a separate and distinct MqanuOap that can be stored, used, and reused:
m-9Ajpnu*k^fa_po*behpan$da]`heja[[op]nposepd9Sd]p%
m.9m-*at_hq`a$lq^[`]pa[[cpa9`]papeia*jks$%%
m/9m-*behpan$lq^[`]pa[[cpa9`]papeia*jks$%%
These three MqanuOaps are separate. The first is a base MqanuOap containing all entries that have a
headline starting with “What.” The second is a subset of the first, with an additional criterion that excludes
records whose lq^[`]pa is later than the current date. The third is a subset of the first, with an additional
criterion that selects only the records whose lq^[`]pa is later than the current date. The initial MqanuOap
(m-) is unaffected by the refinement process.
Limiting QuerySets
Use Python’s array-slicing syntax to limit your MqanuOap to a certain number of results. This is
the equivalent of SQL’s HEIEP and KBBOAP clauses.
For example, this returns the first five entries (HEIEP1):
:::Ajpnu*k^fa_po*]hh$%W61Y
This returns the sixth through tenth entries (KBBOAP1HEIEP1):
:::Ajpnu*k^fa_po*]hh$%W16-,Y
Generally, slicing a MqanuOap returns a new MqanuOap—it doesn’t evaluate the query. An
exception is if you use the opal parameter of Python’s slice syntax. For example, this would
execute the query to return a list of every second object of the first ten:
:::Ajpnu*k^fa_po*]hh$%W6-,6.Y
To retrieve a single object rather than a list (e.g., OAHA?PbkkBNKI^]nHEIEP-), use a
simple index instead of a slice. For example, the following code returns the first Ajpnu in the
database, after ordering Ajpnu objects alphabetically by headline:
:::Ajpnu*k^fa_po*kn`an[^u$#da]`heja#%W,Y
This is roughly equivalent to the following:
:::Ajpnu*k^fa_po*kn`an[^u$#da]`heja#%W,6-Y*cap$%
APPENDIX B N DATABASE API REFERENCE
376
Note, however, that the first of these will raise Ej`atAnnkn while the second will raise
@kaoJkpAteop if no objects match the given criteria.
Query Methods That Return New QuerySets
Django provides a range of MqanuOap refinement methods that modify either the types of
results returned by the MqanuOap or the way its SQL query is executed. These methods are
described in the sections that follow. Some of the methods take field-lookup arguments, which
are discussed in detail in the “Field Lookups” section a bit later on.
filter(**lookup)
This method returns a new MqanuOap containing objects that match the given lookup
parameters.
exclude(**lookup)
The at_hq`a$&&hkkgql% method returns a new MqanuOap containing objects that do not match
the given lookup parameters.
order_by(*fields)
By default, results returned by a MqanuOap are ordered by the ordering tuple given by the
kn`anejc option in the model’s metadata (see Appendix A). You can override this for a particu-
lar query using the kn`an[^u$% method:
::Ajpnu*k^fa_po*behpan$lq^[`]pa[[ua]n9.,,1%*kn`an[^u$#)lq^[`]pa#(#da]`heja#%
This result will be ordered by descending lq^[`]pa, then by ascending da]`heja. The
minus sign in )lq^[`]pa indicates descending order. Ascending order is assumed if the ) is
absent. To order randomly, use ;, like so:
:::Ajpnu*k^fa_po*kn`an[^u$#;#%
Ordering randomly incurs a performance penalty, though, so you shouldn’t use it for anything
with heavy load.
If no ordering is specified in a model’s _h]ooIap] and a MqanuOap from that model doesn’t
include kn`an[^u$%, then ordering will be undefined and may differ from query to query.
distinct()
This returns a new MqanuOap that uses OAHA?P@EOPEJ?P in its SQL query, eliminating duplicate
rows from the query results.
By default, a MqanuOap will not eliminate duplicate rows. In practice this is rarely a prob-
lem, because simple queries such as >hkc*k^fa_po*]hh$% don’t introduce the possibility of
duplicate result rows. However, if your query spans multiple tables, it’s possible to get dupli-
cate results when a MqanuOap is evaluated. That’s when you’d use `eopej_p$%.
APPENDIX B N DATABASE API REFERENCE 377
values(*fields)
The r]hqao$&beah`o% method returns a special MqanuOap that evaluates to a list of dictionaries
instead of model-instance objects. Each of those dictionaries represents an object, with the
keys corresponding to the attribute names of model objects:
Pdeoheop_kjp]ejo]>hkck^fa_p*
:::>hkc*k^fa_po*behpan$j]ia[[op]nposepd9#>a]phao#%
W>a]phao>hkcY
Pdeoheop_kjp]ejo]`e_pekj]nu*
:::>hkc*k^fa_po*behpan$j]ia[[op]nposepd9#>a]phao#%*r]hqao$%
Ww#e`#6-(#j]ia#6#>a]phao>hkc#(#p]cheja#6#=hhpdah]paop>a]phaojaso*#yY
r]hqao$% takes optional positional arguments, &beah`o, which specify field names to
which the OAHA?P should be limited. If you specify the fields, each dictionary will contain only
the field keys/values for the fields you specify. If you don’t specify the fields, each dictionary
will contain a key and value for every field in the database table:
:::>hkc*k^fa_po*r]hqao$%
Ww#e`#6-(#j]ia#6#>a]phao>hkc#(#p]cheja#6#=hhpdah]paop>a]phaojaso*#yY(
:::>hkc*k^fa_po*r]hqao$#e`#(#j]ia#%
Ww#e`#6-(#j]ia#6#>a]phao>hkc#yY
This method is useful when you know you’re going to need values from only a small num-
ber of the available fields and you won’t need the functionality of a model-instance object. It’s
more efficient to select only the fields you need to use.
dates(field, kind, order)
This method returns a special MqanuOap that evaluates to a list of `]papeia*`]papeia objects
representing all available dates of a particular kind within the contents of the MqanuOap.
The beah` argument must be the name of a @]paBeah` or @]paPeiaBeah` of your model.
The gej` argument must be ua]n, ikjpd, or `]u. Each `]papeia*`]papeia object in the
result list is truncated to the given pula:
ÊUÊua]n returns a list of all distinct year values for the field.
ÊUÊikjpd returns a list of all distinct year/month values for the field.
ÊUÊ`]u returns a list of all distinct year/month/day values for the field.
kn`an, which defaults to #=O?#, should be either #=O?# or #@AO?#. This specifies how to
order the results—ascending or descending. Here are a few examples:
:::Ajpnu*k^fa_po*`]pao$#lq^[`]pa#(#ua]n#%
W`]papeia*`]papeia$.,,1(-(-%Y
:::Ajpnu*k^fa_po*`]pao$#lq^[`]pa#(#ikjpd#%
W`]papeia*`]papeia$.,,1(.(-%(`]papeia*`]papeia$.,,1(/(-%Y
APPENDIX B N DATABASE API REFERENCE
378
:::Ajpnu*k^fa_po*`]pao$#lq^[`]pa#(#`]u#%
W`]papeia*`]papeia$.,,1(.(.,%(`]papeia*`]papeia$.,,1(/(.,%Y
:::Ajpnu*k^fa_po*`]pao$#lq^[`]pa#(#`]u#(kn`an9#@AO?#%
W`]papeia*`]papeia$.,,1(/(.,%(`]papeia*`]papeia$.,,1(.(.,%Y
:::Ajpnu*k^fa_po*behpan$da]`heja[[_kjp]ejo9#Hajjkj#%*`]pao$#lq^[`]pa#(#`]u#%
W`]papeia*`]papeia$.,,1(/(.,%Y
select_related()
The oaha_p[nah]pa`$% method returns a MqanuOap that will automatically “follow” foreign-key
relationships, selecting that additional related-object data when it executes its query. This is
a performance booster that results in (sometimes much) larger queries but means later use of
foreign-key relationships won’t require database queries.
The following examples illustrate the difference between plain lookups and oaha_p[
nah]pa`$% lookups. Here’s a standard lookup:
Depopda`]p]^]oa*
:::a9Ajpnu*k^fa_po*cap$e`91%
Depopda`]p]^]oa]c]ejpkcappdanah]pa`>hkck^fa_p*
:::^9a*^hkc
And here’s a oaha_p[nah]pa` lookup:
Depopda`]p]^]oa*
:::a9Ajpnu*k^fa_po*oaha_p[nah]pa`$%*cap$e`91%
@kaoj#pdeppda`]p]^]oa(^a_]qoaa*^hkcd]o^aajlnalklqh]pa`
ejpdalnarekqomqanu*
:::^9a*^hkc
oaha_p[nah]pa`$% follows foreign keys as far as possible. If you have the following models
_h]oo?epu$ik`aho*Ik`ah%6
***
_h]ooLanokj$ik`aho*Ik`ah%6
***
dkiapksj9ik`aho*BknaecjGau$?epu%
_h]oo>kkg$ik`aho*Ik`ah%6
***
]qpdkn9ik`aho*BknaecjGau$Lanokj%
then a call to >kkg*k^fa_po*oaha_p[nah]pa`$%*cap$e`90% will cache the related Lanokj and the
related ?epu:
APPENDIX B N DATABASE API REFERENCE 379
:::^9>kkg*k^fa_po*oaha_p[nah]pa`$%*cap$e`90%
:::l9^*]qpdkn@kaoj#pdeppda`]p]^]oa*
:::_9l*dkiapksj@kaoj#pdeppda`]p]^]oa*
:::^9>kkg*k^fa_po*cap$e`90%Jkoaha_p[nah]pa`$%ejpdeoat]ilha*
:::l9^*]qpdknDepopda`]p]^]oa*
:::_9l*dkiapksjDepopda`]p]^]oa*
Note that oaha_p[nah]pa`$% does not follow foreign keys that have jqhh9Pnqa.
Usually, using oaha_p[nah]pa`$% can vastly improve performance because your appli-
cation can avoid many database calls. However, in situations with deeply nested sets of
relationships, oaha_p[nah]pa`$% can sometimes end up following too many relationships and
can generate queries so large that they end up being slow.
QuerySet Methods That Do Not Return QuerySets
The following MqanuOap methods evaluate the MqanuOap and return something other than a
MqanuOap—a single object, a value, and so forth.
get(**lookup)
This returns the object matching the given lookup parameters, which should be in the format
described in the “Field Lookups” section. This raises =ooanpekjAnnkn if more than one object is
found.
cap$% raises a @kaoJkpAteop exception if an object isn’t found for the given parameters.
The @kaoJkpAteop exception is an attribute of the model class. Consider this example:
:::Ajpnu*k^fa_po*cap$e`9#bkk#%n]eoaoAjpnu*@kaoJkpAteop
The @kaoJkpAteop exception inherits from `f]jck*_kna*at_alpekjo*K^fa_p@kaoJkpAteop,
so you can target multiple @kaoJkpAteop exceptions:
:::bnki`f]jck*_kna*at_alpekjoeilknpK^fa_p@kaoJkpAteop
:::pnu6
***a9Ajpnu*k^fa_po*cap$e`9/%
***^9>hkc*k^fa_po*cap$e`9-%
***at_alpK^fa_p@kaoJkpAteop6
***lnejpAepdanpdaajpnukn^hkc`kaoj#pateop*
create(**kwargs)
This is a convenience method for creating an object and saving it all in one step. It lets you
compress two common steps
:::l9Lanokj$benop[j]ia9>nq_a(h]op[j]ia9Olnejcopaaj%
:::l*o]ra$%
into a single line:
:::l9Lanokj*k^fa_po*_na]pa$benop[j]ia9>nq_a(h]op[j]ia9Olnejcopaaj%
APPENDIX B N DATABASE API REFERENCE
380
get_or_create(**kwargs)
This is a convenience method for looking up an object and creating one if it doesn’t exist.
It returns a tuple of $k^fa_p(_na]pa`%, where k^fa_p is the retrieved or created object and
_na]pa` is a Boolean specifying whether a new object was created.
This method is meant as a shortcut to boilerplate code and is mostly useful for data-
import scripts. Here’s an example:
pnu6
k^f9Lanokj*k^fa_po*cap$benop[j]ia9#Fkdj#(h]op[j]ia9#Hajjkj#%
at_alpLanokj*@kaoJkpAteop6
k^f9Lanokj$benop[j]ia9#Fkdj#(h]op[j]ia9#Hajjkj#(^enpd`]u9`]pa$-50,(-,(5%%
k^f*o]ra$%
This pattern gets quite unwieldy as the number of fields in a model increases. The previ-
ous example can be rewritten using cap[kn[_na]pa$% like so:
k^f(_na]pa`9Lanokj*k^fa_po*cap[kn[_na]pa$
benop[j]ia9#Fkdj#(
h]op[j]ia9#Hajjkj#(
`ab]qhpo9w#^enpd`]u#6`]pa$-50,(-,(5%y
%
Any keyword arguments passed to cap[kn[_na]pa$%except an optional one called
`ab]qhpo—will be used in a cap$% call. If an object is found, cap[kn[_na]pa$% returns a tuple of
that object and B]hoa. If an object is not found, cap[kn[_na]pa$% will instantiate and save a new
object, returning a tuple of the new object and Pnqa. The new object will be created according
to this algorithm:
`ab]qhpo9gs]nco*lkl$#`ab]qhpo#(wy%
l]n]io9`e_p$W$g(r%bkng(rejgs]nco*epaio$%eb#[[#jkpejgY%
l]n]io*ql`]pa$`ab]qhpo%
k^f9oahb*ik`ah$&&l]n]io%
k^f*o]ra$%
In English, that means you should start with any non-#`ab]qhpo# keyword argument that
doesn’t contain a double underscore (which would indicate an inexact lookup). Then add the
contents of `ab]qhpo, overriding any keys if necessary, and use the result as the keyword argu-
ments to the model class.
If you have a field named `ab]qhpo and want to use it as an exact lookup in cap[kn[
_na]pa$%, just use #`ab]qhpo[[at]_p# like so:
Bkk*k^fa_po*cap[kn[_na]pa$
`ab]qhpo[[at]_p9#^]n#(
`ab]qhpo9w#`ab]qhpo#6#^]n#y
%
APPENDIX B N DATABASE API REFERENCE 381
NNote As mentioned earlier, cap[kn[_na]pa$% is mostly useful in scripts that need to parse data and cre
ATENEWRECORDSIFEXISTINGONESARENTAVAILABLE"UTIFYOUNEEDTOUSEcap[kn[_na]pa$% in a view, please
MAKESURETOUSEITONLYINLKOP requests unless you have a good reason not to. CAPREQUESTSSHOULDNTHAVE
any effect on data; use LKOP whenever a request to a page has a side effect on your data.
count()
_kqjp$% returns an integer representing the number of objects in the database matching the
MqanuOap. _kqjp$% never raises exceptions. Here’s an example:
Napqnjopdapkp]hjqi^ankbajpneaoejpda`]p]^]oa*
:::Ajpnu*k^fa_po*_kqjp$%
0
Napqnjopdajqi^ankbajpneaosdkoada]`heja_kjp]ejo#Hajjkj#
:::Ajpnu*k^fa_po*behpan$da]`heja[[_kjp]ejo9#Hajjkj#%*_kqjp$%
-
_kqjp$% performs a OAHA?P?KQJP$&% behind the scenes, so you should always use _kqjp$%
rather than loading all of the records into Python objects and calling haj$% on the result.
Depending on which database you’re using (e.g., PostgreSQL or MySQL), _kqjp$% may
return a long integer instead of a normal Python integer. This is an underlying implementation
quirk that shouldn’t pose any real-world problems.
in_bulk(id_list)
This method takes a list of primary-key values and returns a dictionary mapping each primary-
key value to an instance of the object with the given ID, as in this example:
:::>hkc*k^fa_po*ej[^qhg$W-Y%
w-6>a]phao>hkcy
:::>hkc*k^fa_po*ej[^qhg$W-(.Y%
w-6>a]phao>hkc(.6?da``]nP]hgy
:::>hkc*k^fa_po*ej[^qhg$WY%
wy
IDs of objects that don’t exist are silently dropped from the result dictionary. If you pass
ej[^qhg$% an empty list, you’ll get an empty dictionary.
latest(field_name=None)
This returns the latest object in the table, by date, using the beah`[j]ia provided as the date
field. This example returns the latest Ajpnu in the table, according to the lq^[`]pa field:
:::Ajpnu*k^fa_po*h]paop$#lq^[`]pa#%
APPENDIX B N DATABASE API REFERENCE
382
If your model’s Iap] specifies cap[h]paop[^u, you can leave off the beah`[j]ia argument to
h]paop$%. Django will use the field specified in cap[h]paop[^u by default.
Like cap$%, h]paop$% raises @kaoJkpAteop if an object doesn’t exist with the given parameters.
Field Lookups
Field lookups are how you specify the meat of an SQL SDANA clause. They’re specified as key-
word arguments to the MqanuOap methods behpan$%, at_hq`a$%, and cap$%.
Basic lookup keyword arguments take the form beah`[[hkkgqlpula9r]hqa (note the double
underscore). This example
:::Ajpnu*k^fa_po*behpan$lq^[`]pa[[hpa9#.,,2),-),-#%
translates (roughly) into the following SQL:
OAHA?P&BNKI^hkc[ajpnuSDANAlq^[`]pa89#.,,2),-),-#7
If you pass an invalid keyword argument, a lookup function will raise PulaAnnkn.
The supported lookup types follow.
exact
at]_p performs an exact match:
:::Ajpnu*k^fa_po*cap$da]`heja[[at]_p9I]j^epao`kc%
This matches any object with the exact headline “Man bites dog”.
If you don’t provide a lookup type—that is, if your keyword argument doesn’t contain a
double underscore—the lookup type is assumed to be at]_p. For example, the following two
statements are equivalent:
:::>hkc*k^fa_po*cap$e`[[at]_p9-0%Atlhe_epbkni
:::>hkc*k^fa_po*cap$e`9-0%[[at]_peoeilhea`
This is for convenience, because at]_p lookups are the common case.
iexact
This method performs a case-insensitive exact match:
:::>hkc*k^fa_po*cap$j]ia[[eat]_p9#^a]phao^hkc#%
This will match #>a]phao>hkc#, #^a]phao^hkc#, #>a=pHao>HkC#, and so forth.
contains
This method performs a case-sensitive containment test:
Ajpnu*k^fa_po*cap$da]`heja[[_kjp]ejo9#Hajjkj#%
This will match the headline #Pk`]uHajjkjdkjkna`# but not #pk`]uhajjkjdkjkna`#.
SQLite doesn’t support case-sensitive HEGA statements; when using SQLite, _kjp]ejo acts
like e_kjp]ejo.
APPENDIX B N DATABASE API REFERENCE 383
ESCAPING PERCENT SIGNS AND UNDERSCORES IN LIKE STATEMENTS
4HEFIELDLOOKUPSTHATEQUATETOHEGA SQL statements (eat]_p, _kjp]ejo, e_kjp]ejo, op]nposepd,
eop]nposepd, aj`osepd, and eaj`osepd) will automatically escape the two special characters used in
HEGA statements—the percent sign and the underscore)NAHEGA statement, the percent sign signifies a
MULTIPLECHARACTERWILDCARDANDTHEUNDERSCORESIGNIFIESASINGLECHARACTERWILDCARD
4HISMEANSTHINGSSHOULDWORKINTUITIVELYSOTHEABSTRACTIONDOESNTLEAK&OREXAMPLETORETRIEVEALL
the entries that contain a percent sign, just use the percent sign as any other character:
Ajpnu*k^fa_po*behpan$da]`heja[[_kjp]ejo9#!#%
$JANGOTAKESCAREOFTHEQUOTINGFORYOU4HERESULTING31,WILLLOOKSOMETHINGLIKETHIS
OAHA?P***SDANAda]`hejaHEGA#!X!!#7
4HESAMEGOESFORUNDERSCORES"OTHPERCENTSIGNS and underscores are handled for you transparently.
icontains
This performs a case-insensitive containment test:
:::Ajpnu*k^fa_po*cap$da]`heja[[e_kjp]ejo9#Hajjkj#%
Unlike _kjp]ejo, e_kjp]ejo will match #pk`]uhajjkjdkjkna`#.
gt, gte, lt, and lte
These represent greater than, greater than or equal to, less than, and less than or equal to:
:::Ajpnu*k^fa_po*behpan$e`[[cp90%
:::Ajpnu*k^fa_po*behpan$e`[[hp9-1%
:::Ajpnu*k^fa_po*behpan$e`[[hpa9/%
:::Ajpnu*k^fa_po*behpan$e`[[cpa9,%
These queries return any object with an ID greater than 4, an ID less than 15, and an ID
greater than or equal to 1, respectively.
You’ll usually use these on numeric fields. Be careful with character fields since character
order isn’t always what you’d expect (i.e., the string 0 sorts after the string -,).
in
The ej method filters where a value is on a given list:
Ajpnu*k^fa_po*behpan$e`[[ej9W-(/(0Y%
This returns all objects with the ID 1, 3, or 4.
APPENDIX B N DATABASE API REFERENCE
384
startswith
op]nposepd performs a case-sensitive search based on the starting characters:
:::Ajpnu*k^fa_po*behpan$da]`heja[[op]nposepd9#Sehh#%
This will return the headlines “Will he run?” and “Willbur named judge,” but not “Who is
Will?” or “will found in crypt.”
istartswith
This method performs a case-insensitive search based on the starting characters:
:::Ajpnu*k^fa_po*behpan$da]`heja[[eop]nposepd9#sehh#%
This will return the headlines “Will he run?” “Willbur named judge,” and “will found in
crypt,” but not “Who is Will?”
endswith and iendswith
These methods perform case-sensitive and case-insensitive, respectively, searches based on
the ending characters, similar to op]nposepd and eop]nposepd:
:::Ajpnu*k^fa_po*behpan$da]`heja[[aj`osepd9#_]po#%
:::Ajpnu*k^fa_po*behpan$da]`heja[[eaj`osepd9#_]po#%
range
n]jca performs an inclusive range check:
:::op]np[`]pa9`]papeia*`]pa$.,,1(-(-%
:::aj`[`]pa9`]papeia*`]pa$.,,1(/(/-%
:::Ajpnu*k^fa_po*behpan$lq^[`]pa[[n]jca9$op]np[`]pa(aj`[`]pa%%
You can use n]jca anywhere you can use >APSAAJ in SQL—for dates, numbers, and even
characters.
year, month, and day
For date/datetime fields, these methods perform exact year, month, or day matches:
Napqnj]hhajpneaolq^heoda`ej.,,1
:::Ajpnu*k^fa_po*behpan$lq^[`]pa[[ua]n9.,,1%
Napqnj]hhajpneaolq^heoda`ej@a_ai^an
:::Ajpnu*k^fa_po*behpan$lq^[`]pa[[ikjpd9-.%
Napqnj]hhajpneaolq^heoda`kjpda/n`kbpdaikjpd
:::Ajpnu*k^fa_po*behpan$lq^[`]pa[[`]u9/%
?ki^ej]pekj6napqnj]hhajpneaokj?dneopi]okb]juua]n
:::Ajpnu*k^fa_po*behpan$lq^[`]pa[[ikjpd9-.(lq^[`]pa[`]u9.1%
APPENDIX B N DATABASE API REFERENCE 385
isnull
This method takes either Pnqa or B]hoa, which correspond to SQL queries of EOJQHH and EO
JKPJQHH, respectively:
:::Ajpnu*k^fa_po*behpan$lq^[`]pa[[eojqhh9Pnqa%
search
oa]n_d is a Boolean full-text search that takes advantage of full-text indexing. This is like
_kjp]ejo but is significantly faster due to full-text indexing.
Note this is available only in MySQL and requires direct manipulation of the database
to add the full-text index.
The pk Lookup Shortcut
For convenience, Django provides a lg lookup type, which stands for “primary_key.”
In the example >hkc model, the primary key is the e` field, so these three statements are
equivalent:
:::>hkc*k^fa_po*cap$e`[[at]_p9-0%Atlhe_epbkni
:::>hkc*k^fa_po*cap$e`9-0%[[at]_peoeilhea`
:::>hkc*k^fa_po*cap$lg9-0%lgeilheaoe`[[at]_p
The use of lg isn’t limited to [[at]_p queries—any query term can be combined with lg to
perform a query on a model’s primary key:
Cap^hkcoajpneaosepde`-(0(]j`3
:::>hkc*k^fa_po*behpan$lg[[ej9W-(0(3Y%
Cap]hh^hkcajpneaosepde`:-0
:::>hkc*k^fa_po*behpan$lg[[cp9-0%
lg lookups also work across joins. For example, these three statements are equivalent:
:::Ajpnu*k^fa_po*behpan$^hkc[[e`[[at]_p9/%Atlhe_epbkni
:::Ajpnu*k^fa_po*behpan$^hkc[[e`9/%[[at]_peoeilhea`
:::Ajpnu*k^fa_po*behpan$^hkc[[lg9/%[[lgeilheao[[e`[[at]_p
The point of lg is to give you a generic way to refer to the primary key when you’re not
sure whether the model’s primary key is called e`.
Complex Lookups with Q Objects
Keyword argument queries—in behpan$% and so on—are =J@ed together. If you need to execute
more-complex queries (e.g., queries with KN statements), you can use M objects.
A M object (`f]jck*`^*ik`aho*M) is an object used to encapsulate a collection of keyword
arguments. These keyword arguments are specified as explained in the “Field Lookups”
section.
APPENDIX B N DATABASE API REFERENCE
386
For example, this M object encapsulates a single HEGA query:
M$mqaopekj[[op]nposepd9#Sd]p#%
M objects can be combined using the " and x operators. When an operator is used on two M
objects, it yields a new M object. For example, this statement yields a single M object that repre-
sents the KN of two mqaopekj[[op]nposepd queries:
M$mqaopekj[[op]nposepd9#Sdk#%xM$mqaopekj[[op]nposepd9#Sd]p#%
This is equivalent to the following SQL SDANA clause:
SDANAmqaopekjHEGA#Sdk!#KNmqaopekjHEGA#Sd]p!#
You can compose statements of arbitrary complexity by combining M objects with the "
and x operators. You can also use parenthetical grouping.
Each lookup function that takes keyword arguments (e.g., behpan$%, at_hq`a$%, cap$%)
can also be passed one or more M objects as positional (not-named) arguments. If you provide
multiple M object arguments to a lookup function, the arguments will be =J@ed together, as in
this example:
Lkhh*k^fa_po*cap$
M$mqaopekj[[op]nposepd9#Sdk#%(
M$lq^[`]pa9`]pa$.,,1(1(.%%xM$lq^[`]pa9`]pa$.,,1(1(2%%
%
This roughly translates into the following SQL:
OAHA?P&bnkilkhhoSDANAmqaopekjHEGA#Sdk!#
=J@$lq^[`]pa9#.,,1),1),.#KNlq^[`]pa9#.,,1),1),2#%
Lookup functions can mix the use of M objects and keyword arguments. All arguments
provided to a lookup function (be they keyword arguments or M objects) are =J@ed together.
However, if a M object is provided, it must precede the definition of any keyword arguments.
For example, the following
Lkhh*k^fa_po*cap$
M$lq^[`]pa9`]pa$.,,1(1(.%%xM$lq^[`]pa9`]pa$.,,1(1(2%%(
mqaopekj[[op]nposepd9#Sdk#%
would be a valid query, equivalent to the previous example, but this would not be valid:
EJR=HE@MQANU
Lkhh*k^fa_po*cap$
mqaopekj[[op]nposepd9#Sdk#(
M$lq^[`]pa9`]pa$.,,1(1(.%%xM$lq^[`]pa9`]pa$.,,1(1(2%%%
You can find some examples online at dppl6++sss*`f]jcklnkfa_p*_ki+`k_qiajp]pekj+ik`aho+
kn[hkkgqlo+.
APPENDIX B N DATABASE API REFERENCE 387
Related Objects
When you define a relationship in a model (i.e., a BknaecjGau, KjaPkKjaBeah`, or
I]juPkI]juBeah`), instances of that model will have a convenient API to access the related
object(s).
For example, an Ajpnu object a can get its associated >hkc object by accessing the ^hkc
attribute a*^hkc.
Django also creates API accessors for the “other” side of the relationship—the link from
the related model to the model that defines the relationship. For example, a >hkc object ^ has
access to a list of all related Ajpnu objects via the ajpnu[oap attribute: ^*ajpnu[oap*]hh$%.
All examples in this section use the sample >hkc, =qpdkn, and Ajpnu models defined at the
start of this appendix.
Lookups That Span Relationships
Django offers a powerful and intuitive way to “follow” relationships in lookups, taking care
of the SQL FKEJs for you automatically behind the scenes. To span a relationship, just use the
field name of related fields across models, separated by double underscores, until you get to
the field you want.
This example retrieves all Ajpnu objects with a >hkc whose j]ia is #>a]phao>hkc#:
:::Ajpnu*k^fa_po*behpan$^hkc[[j]ia[[at]_p9#>a]phao>hkc#%
This spanning can be as deep as you’d like.
It works backward, too. To refer to a “reverse” relationship (see the section “‘Reverse’
Foreign-Key Relationships”), just use the lowercase name of the model.
This example retrieves all >hkc objects that have at least one Ajpnu whose da]`heja con-
tains #Hajjkj#:
:::>hkc*k^fa_po*behpan$ajpnu[[da]`heja[[_kjp]ejo9#Hajjkj#%
Foreign-Key Relationships
If a model has a BknaecjGau, instances of that model will have access to the related (foreign)
object via a simple attribute of the model, as in this example:
a9Ajpnu*k^fa_po*cap$e`9.%
a*^hkcNapqnjopdanah]pa`>hkck^fa_p*
You can get and set foreign-key values via a foreign-key attribute. As you may expect,
changes to the foreign key aren’t saved to the database until you call o]ra$%, as in this example:
a9Ajpnu*k^fa_po*cap$e`9.%
a*^hkc9okia[^hkc
a*o]ra$%
APPENDIX B N DATABASE API REFERENCE
388
If a BknaecjGau field has jqhh9Pnqa set (i.e., it allows JQHH values), you can set it to JQHH by
assigning Jkja to it and saving:
a9Ajpnu*k^fa_po*cap$e`9.%
a*^hkc9Jkja
a*o]ra$%QL@=PA^hkc[ajpnuOAP^hkc[e`9JQHH***7
Forward access to one-to-many relationships is cached the first time the related object is
accessed. Subsequent accesses to the foreign key on the same object instance are cached, as in
this example:
a9Ajpnu*k^fa_po*cap$e`9.%
lnejpa*^hkcDepopda`]p]^]oapknapnearapda]ook_e]pa`>hkc*
lnejpa*^hkc@kaoj#pdeppda`]p]^]oa7qoao_]_da`ranoekj*
Note that the oaha_p[nah]pa`$% MqanuOap method recursively prepopulates the cache of all
one-to-many relationships:
a9Ajpnu*k^fa_po*oaha_p[nah]pa`$%*cap$e`9.%
lnejpa*^hkc@kaoj#pdeppda`]p]^]oa7qoao_]_da`ranoekj*
lnejpa*^hkc@kaoj#pdeppda`]p]^]oa7qoao_]_da`ranoekj*
oaha_p[nah]pa`$% is documented in the “select_related()” section earlier in this appendix.
“Reverse” Foreign-Key Relationships
Foreign-key relationships are automatically symmetrical—a reverse relationship is inferred
from the presence of a BknaecjGau pointing to another model.
If a model has a BknaecjGau, instances of the foreign-key model will have access to a
I]j]can that returns all instances of the first model that relate to that object. By default, this
I]j]can is named BKK[oap, where BKK is the source model name, lowercased. This I]j]can
returns MqanuOapo, which can be filtered and manipulated as described in the “Retrieving
Objects” section earlier in this appendix.
Here’s an example:
^9>hkc*k^fa_po*cap$e`9-%
^*ajpnu[oap*]hh$%Napqnjo]hhAjpnuk^fa_ponah]pa`pk>hkc*
^*ajpnu[oapeo]I]j]canpd]pnapqnjoMqanuOapo*
^*ajpnu[oap*behpan$da]`heja[[_kjp]ejo9#Hajjkj#%
^*ajpnu[oap*_kqjp$%
You can override the BKK[oap name by setting the nah]pa`[j]ia parameter in
the BknaecjGau$% definition. For example, if the Ajpnu model was altered to ^hkc9
BknaecjGau$>hkc(nah]pa`[j]ia9#ajpneao#%, the preceding example code would look
like this:
APPENDIX B N DATABASE API REFERENCE 389
^9>hkc*k^fa_po*cap$e`9-%
^*ajpneao*]hh$%Napqnjo]hhAjpnuk^fa_ponah]pa`pk>hkc*
^*ajpneaoeo]I]j]canpd]pnapqnjoMqanuOapo*
^*ajpneao*behpan$da]`heja[[_kjp]ejo9#Hajjkj#%
^*ajpneao*_kqjp$%
nah]pa`[j]ia is particularly useful if a first model has two foreign keys to the same second
model.
You cannot access a reverse BknaecjGau I]j]can from the class; it must be accessed from
an instance:
>hkc*ajpnu[oapN]eoao=ppne^qpaAnnkn6I]j]caniqop^a]__aooa`re]ejop]j_a*
In addition to the MqanuOap methods defined in the earlier “Retrieving Objects” section,
the BknaecjGau I]j]can has these methods:
ÊUÊ]``$k^f-(k^f.(***%: Adds the specified model objects to the related object set,
for example
^9>hkc*k^fa_po*cap$e`9-%
a9Ajpnu*k^fa_po*cap$e`9./0%
^*ajpnu[oap*]``$a%=ook_e]paoAjpnuasepd>hkc^*
ÊUÊ_na]pa$&&gs]nco%: Creates a new object, saves it, and puts it in the related object set.
It returns the newly created object:
^9>hkc*k^fa_po*cap$e`9-%
a9^*ajpnu[oap*_na]pa$da]`heja9#Dahhk#(^k`u[patp9#De#(
lq^[`]pa9`]papeia*`]pa$.,,1(-(-%%
Jkjaa`pk_]hha*o]ra$%]ppdeolkejpÍep#o]hna]`u^aajo]ra`*
This is equivalent to (but much simpler than) the following:
^9>hkc*k^fa_po*cap$e`9-%
a9Ajpnu$^hkc9^(da]`heja9#Dahhk#(^k`u[patp9#De#(
lq^[`]pa9`]papeia*`]pa$.,,1(-(-%%
a*o]ra$%
Note that there’s no need to specify the keyword argument of the model that defines
the relationship. In the preceding example, we don’t pass the parameter ^hkc to
_na]pa$%. Django figures out that the new Ajpnu object’s ^hkc field should be set to ^.
APPENDIX B N DATABASE API REFERENCE
390
ÊUÊnaikra$k^f-(k^f.(***%: Removes the specified model objects from the related
object set:
^9>hkc*k^fa_po*cap$e`9-%
a9Ajpnu*k^fa_po*cap$e`9./0%
^*ajpnu[oap*naikra$a%@eo]ook_e]paoAjpnuabnki>hkc^*
To prevent database inconsistency, this method exists only on BknaecjGau objects
where jqhh9Pnqa. If the related field can’t be set to Jkja (JQHH), then an object can’t be
removed from a relation without being added to another. In the preceding example,
removing a from ^*ajpnu[oap$% is equivalent to doing a*^hkc9Jkja, and because the
^hkc BknaecjGau doesn’t have jqhh9Pnqa, this is invalid.
ÊUÊ_ha]n$%: Removes all objects from the related object set:
^9>hkc*k^fa_po*cap$e`9-%
^*ajpnu[oap*_ha]n$%
Note that this doesn’t delete the related objects—it just disassociates them.
Just like naikra$%, _ha]n$% is available only on BknaecjGaus where jqhh9Pnqa.
To assign the members of a related set in one fell swoop, just assign to it from any iterable
object, as in this example:
^9>hkc*k^fa_po*cap$e`9-%
^*ajpnu[oap9Wa-(a.Y
If the _ha]n$% method is available, any pre-existing objects will be removed from the
ajpnu[oap before all objects in the iterable (in this case, a list) are added to the set. If the
_ha]n$% method is not available, all objects in the iterable will be added without removing any
existing elements.
Each “reverse” operation described in this section has an immediate effect on the data-
base. Every addition, creation, and deletion is immediately and automatically saved to the
database.
Many-to-Many Relationships
Both ends of a many-to-many relationship get automatic API access to the other end. The API
works just as a “reverse” one-to-many relationship (described in the previous section). The
only difference is in the attribute naming: the model that defines the I]juPkI]juBeah` uses
the attribute name of that field itself, whereas the “reverse” model uses the lowercased model
name of the original model, plus #[oap# (just like reverse one-to-many relationships).
An example makes this concept easier to understand:
a9Ajpnu*k^fa_po*cap$e`9/%
a*]qpdkno*]hh$%Napqnjo]hh=qpdknk^fa_pobknpdeoAjpnu*
a*]qpdkno*_kqjp$%
a*]qpdkno*behpan$j]ia[[_kjp]ejo9#Fkdj#%
]9=qpdkn*k^fa_po*cap$e`91%
]*ajpnu[oap*]hh$%Napqnjo]hhAjpnuk^fa_pobknpdeo=qpdkn*
APPENDIX B N DATABASE API REFERENCE 391
Like BknaecjGau, I]juPkI]juBeah` can specify nah]pa`[j]ia. In the preceding example,
if the I]juPkI]juBeah` in Ajpnu had specified nah]pa`[j]ia9#ajpneao#, then each =qpdkn
instance would have an ajpneao attribute instead of ajpnu[oap.
HOW ARE THE REVERSE RELATIONSHIPS POSSIBLE?
Some OBJECTRELATIONALMAPPERSREQUIREYOUTODEFINERELATIONSHIPSONBOTHSIDES4HE$JANGODEVELOPERS
BELIEVETHISISAVIOLATIONOFTHE$29$ONT2EPEAT9OURSELFPRINCIPLESO$JANGOREQUIRESYOUTODEFINETHE
RELATIONSHIPONONLYONEEND"UTHOWISTHISPOSSIBLEGIVENTHATAMODELCLASSDOESNTKNOWWHICHOTHER
model classes are related to it until those other model classes are loaded?
The answer lies in the EJOP=HHA@[=LLO setting. The first time any model is loaded, Django iterates
over every model in EJOP=HHA@[=LLO and creates the reverse relationships in memory as needed. Essen
tially, one of the functions of EJOP=HHA@[=LLO is to tell Django the entire model domain.
Queries over Related Objects
Queries involving related objects follow the same rules as queries involving normal value
fields. When specifying the value for a query to match, you may use either an object instance
itself or the primary-key value for the object.
For example, if you have a >hkc object ^ with e`91, the following three queries would be
identical:
Ajpnu*k^fa_po*behpan$^hkc9^%Mqanuqoejck^fa_pejop]j_a
Ajpnu*k^fa_po*behpan$^hkc9^*e`%Mqanuqoejce`bnkiejop]j_a
Ajpnu*k^fa_po*behpan$^hkc91%Mqanuqoejce``ena_phu
Deleting Objects
The deletion method, conveniently, is named `ahapa$%. This method immediately deletes the
object and has no return value:
a*`ahapa$%
You can also delete objects in bulk. Every MqanuOap has a `ahapa$% method, which deletes
all members of that MqanuOap. For example, this deletes all Ajpnu objects with a lq^[`]pa year
of 2005:
Ajpnu*k^fa_po*behpan$lq^[`]pa[[ua]n9.,,1%*`ahapa$%
When Django deletes an object, it emulates the behavior of the SQL constraint KJ@AHAPA
?=O?=@A—in other words, any objects that had foreign keys pointing at the object to be deleted
will be deleted along with it. Here’s an example:
^9>hkc*k^fa_po*cap$lg9-%
Pdeosehh`ahapapda>hkc]j`]hhkbepoAjpnuk^fa_po*
^*`ahapa$%
APPENDIX B N DATABASE API REFERENCE
392
Note that `ahapa$% is the only MqanuOap method that is not exposed on a I]j]can itself.
This is a safety mechanism to prevent you from accidentally requesting Ajpnu*k^fa_po*
`ahapa$% and deleting all the entries. If you do want to delete all the objects, then you have
to explicitly request a complete query set:
Ajpnu*k^fa_po*]hh$%*`ahapa$%
Shortcuts
As you develop views, you will discover a number of common idioms in the way you use the
database API. Django encodes some of these idioms as shortcuts that can be used to simplify
the process of writing views. These functions are in the `f]jck*odknp_qpo module.
get_object_or_404()
One common idiom is to use cap$% and raise Dppl0,0 if the object doesn’t exist. This idiom is
captured by cap[k^fa_p[kn[0,0$%. This function takes a Django model as its first argument
and an arbitrary number of keyword arguments, which it passes to the default manager’s cap$%
function. It raises Dppl0,0 if the object doesn’t exist. Consider this example:
CappdaAjpnusepd]lnei]nugaukb/
a9cap[k^fa_p[kn[0,0$Ajpnu(lg9/%
When you provide a model to this shortcut function, the default manager is used to exe-
cute the underlying cap$% query. If you don’t want to use the default manager or if you want
to search a list of related objects, you can provide cap[k^fa_p[kn[0,0$% with a I]j]can object
instead:
Cappda]qpdknkb^hkcejop]j_aasepd]j]iakb#Bna`#
]9cap[k^fa_p[kn[0,0$a*]qpdkno(j]ia9#Bna`#%
Qoa]_qopkii]j]can#na_ajp[ajpneao#ejpdaoa]n_dbkn]j
ajpnusepd]lnei]nugaukb/
a9cap[k^fa_p[kn[0,0$Ajpnu*na_ajp[ajpneao(lg9/%
get_list_or_404()
cap[heop[kn[0,0 behaves the same way as cap[k^fa_p[kn[0,0$%, except that it uses behpan$%
instead of cap$%. It raises Dppl0,0 if the list is empty.
APPENDIX B N DATABASE API REFERENCE 393
Falling Back to Raw SQL
If you find yourself needing to write an SQL query that is too complex for Django’s database
mapper to handle, you can fall back into raw SQL-statement mode.
The preferred way to do this is by giving your model custom methods or custom man-
ager methods that execute queries. Although there’s nothing in Django that requires database
queries to live in the model layer, this approach keeps all your data-access logic in one place,
which is smart from a code-organization standpoint. For instructions, see Appendix A.
Finally, it’s important to note that the Django database layer is merely an interface to your
database. You can access your database via other tools, programming languages, or database
frameworks—there’s nothing Django-specific about your database.
APPENDIX C
Generic View Reference
Chapter 11 introduced generic views but leaves out some of the gory details. This appendix
describes each generic view along with all the options each view can take. Be sure to read
Chapter 11 before trying to understand the reference material that follows. You might want to
refer to the >kkg, Lq^heodan, and =qpdkn objects defined in that chapter; the examples that fol-
low use these models.
Common Arguments to Generic Views
Most of these views take a large number of arguments that can change the generic view’s
behavior. Many of these arguments work the same across a large number of views. Table C-1
describes each of these common arguments; any time you see one of these arguments in a
generic view’s argument list, it will work as described in the table.
Table C-1. Common Arguments to Generic Views
Argument Description
]hhks[ailpu A Boolean specifying whether to display the page if no objects are avail-
able. If this is B]hoa and no objects are available, the view will raise a 404
error instead of displaying an empty page. By default, this is Pnqa.
_kjpatp[lnk_aookno A list of additional template-context processors (besides the defaults) to
apply to the view’s template. See Chapter 9 for information on template
context processors.
atpn][_kjpatp A dictionary of values to add to the template context. By default, this is an
empty dictionary. If a value in the dictionary is callable, the generic view
will call it just before rendering the template.
ieiapula The MIME type to use for the resulting document. It defaults to the value
of the @AB=QHP[IEIA[PULA setting, which is patp+dpih if you haven’t
changed it.
mqanuoap A MqanuOap (i.e., something like =qpdkn*k^fa_po*]hh$%) to read objects
from. See Appendix B for more information about MqanuOap objects. Most
generic views require this argument.
Continued
395
APPENDIX C N GENERIC VIEW REFERENCE
396
Table C-1. Continued
Argument Description
pailh]pa[hk]`an The template loader to use when loading the template. By default, it’s
`f]jck*pailh]pa*hk]`an. See Chapter 9 for information on template
loaders.
pailh]pa[j]ia The full name of a template to use in rendering the page. This lets you
override the default template name derived from the MqanuOap.
pailh]pa[k^fa_p[j]ia The name of the template variable to use in the template context. By
default, this is #k^fa_p#. Views that list more than one object (i.e., k^fa_p[
heop views and various objects-for-date views) will append #[heop# to the
value of this parameter.
“Simple” Generic Views
The module `f]jck*reaso*cajane_*oeilha contains simple views that handle a couple of com-
mon cases: rendering a template when no view logic is needed and issuing a redirect.
Rendering a Template
View function: `f]jck*reaso*cajane_*oeilha*`ena_p[pk[pailh]pa
This view renders a given template, passing it a wwl]n]ioyy template variable, which is a
dictionary of the parameters captured in the URL.
Example
Given the following URLconf, a request to +bkk+ would render the template bkk[ej`at*dpih,
and a request to +bkk+-1+ would render bkk[`ap]eh*dpih with a context variable
wwl]n]io*e`yy that is set to -1:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnki`f]jck*reaso*cajane_*oeilhaeilknp`ena_p[pk[pailh]pa
qnhl]ppanjo9l]ppanjo$##(
$n#Zbkk+ #(`ena_p[pk[pailh]pa(w#pailh]pa#6#bkk[ej`at*dpih#y%(
$n#Zbkk+$;L8e`:X`'%+ #(`ena_p[pk[pailh]pa(w#pailh]pa#6#bkk[`ap]eh*dpih#y%(
%
Required Arguments
ÊUÊpailh]pa: The full name of a template to use.
APPENDIX C N GENERIC VIEW REFERENCE 397
Redirecting to Another URL
View function: `f]jck*reaso*cajane_*oeilha*na`ena_p[pk
This view redirects to another URL. The given URL may contain dictionary-style string
formatting, which will be interpolated against the parameters captured in the URL.
If the given URL is Jkja, Django will return an HTTP 410 (“Gone”) message.
Example
This URLconf redirects from +bkk+8e`:+ to +^]n+8e`:+:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnki`f]jck*reaso*cajane_*oeilhaeilknpna`ena_p[pk
qnhl]ppanjo9l]ppanjo$#`f]jck*reaso*cajane_*oeilha#(
$#Zbkk+$;l8e`:X`'%+ #(na`ena_p[pk(w#qnh#6#+^]n+!$e`%o+#y%(
%
This example returns a “Gone” response for requests to +^]n+:
bnki`f]jck*reaso*cajane_*oeilhaeilknpna`ena_p[pk
qnhl]ppanjo9l]ppanjo$#`f]jck*reaso*cajane_*oeilha#(
$#Z^]n+ #(na`ena_p[pk(w#qnh#6Jkjay%(
%
Required Arguments
ÊUÊqnh: The URL to redirect to, as a string. Or Jkja to return a 410 (“Gone”) HTTP
response.
List/Detail Generic Views
The list/detail generic views (in the module `f]jck*reaso*cajane_*heop[`ap]eh) handle the
common case of displaying a list of items at one view and individual “detail” views of those
items at another.
Lists of Objects
View function: `f]jck*reaso*cajane_*heop[`ap]eh*k^fa_p[heop
Use this view to display a page representing a list of objects.
Example
Given the =qpdkn object from Chapter 5, we can use the k^fa_p[heop view to show a simple list
of all authors, given the following URLconf snippet:
bnkiiuoepa*^kkgo*ik`ahoeilknp=qpdkn
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnki`f]jck*reaso*cajane_eilknpheop[`ap]eh
APPENDIX C N GENERIC VIEW REFERENCE
398
]qpdkn[heop[ejbk9w
#mqanuoap#6=qpdkn*k^fa_po*]hh$%(
y
qnhl]ppanjo9l]ppanjo$##(
$n#]qpdkno+ #(heop[`ap]eh*k^fa_p[heop(]qpdkn[heop[ejbk%
%
Required Arguments
ÊUÊmqanuoap: A MqanuOap of objects to list (refer to Table C-1).
Optional Arguments
ÊUÊl]cej]pa[^u: An integer specifying how many objects should be displayed per page. If
this is given, the view will paginate objects with l]cej]pa[^u objects per page. The view
will expect either a l]ca query string parameter (via CAP) containing a zero-indexed
page number or a l]ca variable specified in the URLconf. (See the following “A Note
on Pagination” sidebar.)
Additionally, this view may take any of these common arguments (described in Table C-1):
ÊUÊ]hhks[ailpu
ÊUÊ_kjpatp[lnk_aookno
ÊUÊatpn][_kjpatp
ÊUÊieiapula
ÊUÊpailh]pa[hk]`an
ÊUÊpailh]pa[j]ia
ÊUÊpailh]pa[k^fa_p[j]ia
Template Name
If pailh]pa[j]ia isn’t specified, this view will use the template 8]ll[h]^ah:+8ik`ah[j]ia:[
heop*dpih by default. Both the application label and the model name are derived from the
mqanuoap parameter. The application label is the name of the application that the model is
defined in, and the model name is the lowercased version of the name of the model class.
In the previous example using =qpdkn*k^fa_po*]hh$% as the mqanuoap, the application label
would be ^kkgo and the model name would be ]qpdkn. This means the default template would
be ^kkgo+]qpdkn[heop*dpih.
APPENDIX C N GENERIC VIEW REFERENCE 399
Template Context
In addition to atpn][_kjpatp, the template’s context will contain the following:
ÊUÊk^fa_p[heop: The list of objects. This variable’s name depends on the pailh]pa[k^fa_p[
j]ia parameter, which is #k^fa_p# by default. If pailh]pa[k^fa_p[j]ia is #bkk#, this
variable’s name will be bkk[heop.
ÊUÊeo[l]cej]pa`: A Boolean representing whether the results are paginated. Specifically,
this is set to B]hoa if the number of available objects is less than or equal to l]cej]pa[^u.
If the results are paginated, the context will contain these extra variables:
ÊUÊnaoqhpo[lan[l]ca: The number of objects per page (this is the same as the l]cej]pa[^u
parameter).
ÊUÊd]o[jatp: A Boolean representing whether there’s a next page.
ÊUÊd]o[lnarekqo: A Boolean representing whether there’s a previous page.
ÊUÊl]ca: The current page number as an integer. This is 1-based.
ÊUÊjatp: The next page number, as an integer. If there’s no next page, this will still be an
integer representing the theoretical next-page number. This is 1-based.
ÊUÊlnarekqo: The previous page number, as an integer. This is 1-based.
ÊUÊl]cao: The total number of pages, as an integer.
ÊUÊdepo: The total number of objects across all pages, not just this page.
A NOTE ON PAGINATION
If l]cej]pa[^u is specified, Django will paginate the results. You can specify the page number in the URL in
one of two ways:
s 5SETHEl]ca parameter in the URLconf. For example, this is what your URLconf might look like:
$n#Zk^fa_po+l]ca$;L8l]ca:W,)5Y'%+ #(#k^fa_p[heop#(`e_p$ejbk[`e_p%%
s 0ASSTHEPAGENUMBERVIATHEl]ca query-string parameter. For example, a URL would look like this:
+k^fa_po+;l]ca9/
In both cases, l]ca is 1-based, not 0-based, so the first page would be represented as page -.
APPENDIX C N GENERIC VIEW REFERENCE
400
Detail Views
View function: `f]jck*reaso*cajane_*heop[`ap]eh*k^fa_p[`ap]eh
This view provides a “detail” view of a single object.
Example
Continuing the previous k^fa_p[heop example, we could add a detail view for a given author by
modifying the URLconf:
bnkiiuoepa*^kkgo*ik`ahoeilknp=qpdkn
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnki`f]jck*reaso*cajane_eilknpheop[`ap]eh
]qpdkn[heop[ejbk9w
#mqanuoap#6=qpdkn*k^fa_po*]hh$%(
y
]qpdkn[`ap]eh[ejbk9w
mqanuoap6=qpdkn*k^fa_po*]hh$%(
pailh]pa[k^fa_p[j]ia6]qpdkn(
y
qnhl]ppanjo9l]ppanjo$##(
$n#]qpdkno+ #(heop[`ap]eh*k^fa_p[heop(]qpdkn[heop[ejbk%(
$n#Z]qpdkno+$;L8k^fa_p[e`:`'%+ #(heop[`ap]eh*k^fa_p[`ap]eh(
]qpdkn[`ap]eh[ejbk%(
%
Required Arguments
ÊUÊmqanuoap: A MqanuOap that will be searched for the object (refer to Table C-1).
You'll also need either:
ÊUÊk^fa_p[e`: The value of the primary-key field for the object.
or
ÊUÊohqc: The slug of the given object. If you pass this field, the ohqc[beah` argument
(see the following section) is also required.
Optional Arguments
ÊUÊohqc[beah`: The name of the field on the object containing the slug. This is required if
you are using the ohqc argument, but it must be absent if you’re using the k^fa_p[e`
argument.
ÊUÊpailh]pa[j]ia[beah`: The name of a field on the object whose value is the template
name to use. This lets you store template names in your data.
APPENDIX C N GENERIC VIEW REFERENCE 401
In other words, if your object has a field #pda[pailh]pa# that contains a string #bkk*
dpih#, and you set pailh]pa[j]ia[beah` to #pda[pailh]pa#, the generic view for this
object will use the template #bkk*dpih#.
If the template named by pailh]pa[j]ia[beah` doesn’t exist, the one named by
pailh]pa[j]ia is used instead. It’s a bit of a brain-bender, but it’s useful in some cases.
This view may also take these common arguments (refer to Table C-1):
ÊUÊ_kjpatp[lnk_aookno
ÊUÊatpn][_kjpatp
ÊUÊieiapula
ÊUÊpailh]pa[hk]`an
ÊUÊpailh]pa[j]ia
ÊUÊpailh]pa[k^fa_p[j]ia
Template Name
If pailh]pa[j]ia and pailh]pa[j]ia[beah` aren’t specified, this view will use the template
8]ll[h]^ah:+8ik`ah[j]ia:[`ap]eh*dpih by default.
Template Context
In addition to atpn][_kjpatp, the template’s context will be as follows:
ÊUÊk^fa_p: The object. This variable’s name depends on the pailh]pa[k^fa_p[j]ia param-
eter, which is #k^fa_p# by default. If pailh]pa[k^fa_p[j]ia is #bkk#, this variable’s
name will be bkk.
Date-Based Generic Views
Date-based generic views are generally used to provide a set of “archive” pages for dated mate-
rial. Think year/month/day archives for a newspaper, or a typical blog archive.
NTip "YDEFAULTTHESEVIEWSIGNOREOBJECTSWITHDATESINTHEFUTURE4HISMEANSTHATIFYOUTRYTOVISITAN
ARCHIVEPAGEINTHEFUTURE$JANGOWILLAUTOMATICALLYSHOWAh0AGENOTFOUNDvERROREVENIFTHEREARE
OBJECTSPUBLISHEDTHATDAY4HUSYOUCANPUBLISHPOSTDATEDOBJECTSTHATDONTAPPEARPUBLICLYUNTILTHEIR
DESIREDPUBLICATIONDATE(OWEVERFORDIFFERENTTYPESOFDATEBASEDOBJECTSTHISISNTAPPROPRIATEEGACAL-
ENDAROFUPCOMINGEVENTS&ORTHESEVIEWSSETTINGTHE]hhks[bqpqna option to Pnqa will make the future
OBJECTSAPPEARANDALLOWUSERSTOVISIThFUTUREvARCHIVEPAGES
APPENDIX C N GENERIC VIEW REFERENCE
402
Archive Index
View function: `f]jck*reaso*cajane_*`]pa[^]oa`*]n_dera[ej`at
This view provides a top-level index page showing the “latest” (i.e., most recent) objects
by date.
Example
Say a typical book publisher wants a page of recently published books. Given some >kkg object
with a lq^he_]pekj[`]pa field, we can use the ]n_dera[ej`at view for this common task:
bnkiiuoepa*^kkgo*ik`ahoeilknp>kkg
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnki`f]jck*reaso*cajane_eilknp`]pa[^]oa`
^kkg[ejbk9w
mqanuoap6>kkg*k^fa_po*]hh$%(
`]pa[beah`6lq^he_]pekj[`]pa
y
qnhl]ppanjo9l]ppanjo$##(
$n#Z^kkgo+ #(`]pa[^]oa`*]n_dera[ej`at(^kkg[ejbk%(
%
Required Arguments
ÊUÊ`]pa[beah`: The name of the @]paBeah` or @]paPeiaBeah` in the MqanuOap’s model that
the date-based archive should use to determine the objects on the page.
ÊUÊmqanuoap: A MqanuOap of objects for which the archive serves.
Optional Arguments
ÊUÊ]hhks[bqpqna: A Boolean specifying whether to include “future” objects on this page, as
described in the previous note.
ÊUÊjqi[h]paop: The number of latest objects to send to the template context. By default,
it’s 15.
This view may also take these common arguments (refer to Table C-1):
ÊUÊ]hhks[ailpu
ÊUÊ_kjpatp[lnk_aookno
ÊUÊatpn][_kjpatp
ÊUÊieiapula
ÊUÊpailh]pa[hk]`an
ÊUÊpailh]pa[j]ia
APPENDIX C N GENERIC VIEW REFERENCE 403
Template Name
If pailh]pa[j]ia isn’t specified, this view will use the template 8]ll[h]^ah:+8ik`ah[j]ia:[
]n_dera*dpih by default.
Template Context
In addition to atpn][_kjpatp, the template’s context will be as follows:
ÊUÊ`]pa[heop: A list of `]papeia*`]pa objects representing all years that have objects avail-
able according to mqanuoap. These are ordered in reverse.
For example, if you have blog entries from 2003 through 2006, this list will contain four
`]papeia*`]pa objects: one for each of those years.
ÊUÊh]paop: The jqi[h]paop objects in the system, in descending order by `]pa[beah`.
For example, if jqi[h]paop is -,, then h]paop will be a list of the latest 10 objects in
mqanuoap.
Year Archives
View function: `f]jck*reaso*cajane_*`]pa[^]oa`*]n_dera[ua]n
Use this view for yearly archive pages. These pages have a list of months in which objects
exist and they can optionally display all the objects published in a given year.
Example
Extending the ]n_dera[ej`at example from earlier, we’ll add a way to view all the books pub-
lished in a given year:
bnkiiuoepa*^kkgo*ik`ahoeilknp>kkg
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
bnki`f]jck*reaso*cajane_eilknp`]pa[^]oa`
^kkg[ejbk9w
mqanuoap6>kkg*k^fa_po*]hh$%(
`]pa[beah`6lq^he_]pekj[`]pa
y
qnhl]ppanjo9l]ppanjo$##(
$n#Z^kkgo+ #(`]pa[^]oa`*]n_dera[ej`at(^kkg[ejbk%(
$n#Z^kkgo+$;L8ua]n:`w0y%+; #(`]pa[^]oa`*]n_dera[ua]n(^kkg[ejbk%(
%
Required Arguments
ÊUÊ`]pa[beah`: As for ]n_dera[ej`at (refer to the previous section).
ÊUÊmqanuoap: A MqanuOap of objects for which the archive serves.
ÊUÊua]n: The four-digit year for which the archive serves (as in our example, this is usually
taken from a URL parameter).
APPENDIX C N GENERIC VIEW REFERENCE
404
Optional Arguments
ÊUÊi]ga[k^fa_p[heop: A Boolean specifying whether to retrieve the full list of objects for
this year and pass those to the template. If Pnqa, this list of objects will be made avail-
able to the template as k^fa_p[heop. (The name k^fa_p[heop may be different; see
the information about k^fa_p[heop in the following “Template Context” section.) By
default, this is B]hoa.
ÊUÊ]hhks[bqpqna: A Boolean specifying whether to include “future” objects on this page.
This view may also take these common arguments (refer to Table C-1):
ÊUÊ]hhks[ailpu
ÊUÊ_kjpatp[lnk_aookno
ÊUÊatpn][_kjpatp
ÊUÊieiapula
ÊUÊpailh]pa[hk]`an
ÊUÊpailh]pa[j]ia
ÊUÊpailh]pa[k^fa_p[j]ia
Template Name
If pailh]pa[j]ia isn’t specified, this view will use the template 8]ll[h]^ah:+8ik`ah[j]ia:[
]n_dera[ua]n*dpih by default.
Template Context
In addition to atpn][_kjpatp, the template’s context will be as follows:
ÊUÊ`]pa[heop: A list of `]papeia*`]pa objects representing all months that have objects
available in the given year, according to mqanuoap, in ascending order.
ÊUÊua]n: The given year, as a four-character string.
ÊUÊk^fa_p[heop: If the i]ga[k^fa_p[heop parameter is Pnqa, this will be set to a list of
objects available for the given year, ordered by the date field. This variable’s name
depends on the pailh]pa[k^fa_p[j]ia parameter, which is #k^fa_p# by default.
If pailh]pa[k^fa_p[j]ia is #bkk#, this variable’s name will be bkk[heop.
If i]ga[k^fa_p[heop is B]hoa, k^fa_p[heop will be passed to the template as an
empty list.
Month Archives
View function: `f]jck*reaso*cajane_*`]pa[^]oa`*]n_dera[ikjpd
This view provides monthly archive pages showing all objects for a given month.
APPENDIX C N GENERIC VIEW REFERENCE 405
Example
Continuing with our example, adding month views should look familiar:
qnhl]ppanjo9l]ppanjo$##(
$n#Z^kkgo+ #(`]pa[^]oa`*]n_dera[ej`at(^kkg[ejbk%(
$n#Z^kkgo+$;L8ua]n:`w0y%+; #(`]pa[^]oa`*]n_dera[ua]n(^kkg[ejbk%(
$
n#Z$;L8ua]n:`w0y%+$;L8ikjpd:W])vYw/y%+ #(
`]pa[^]oa`*]n_dera[ikjpd(
^kkg[ejbk
%(
%
Required Arguments
ÊUÊua]n: The four-digit year for which the archive serves (a string).
ÊUÊikjpd: The month for which the archive serves, formatted according to the ikjpd[
bkni]p argument.
ÊUÊmqanuoap: A MqanuOap of objects for which the archive serves.
ÊUÊ`]pa[beah`: The name of the @]paBeah` or @]paPeiaBeah` in the MqanuOap’s model that
the date-based archive should use to determine the objects on the page.
Optional Arguments
ÊUÊikjpd[bkni]p: A format string that regulates what format the ikjpd parameter uses.
This should be in the syntax accepted by Python’s peia*opnbpeia. (See Python’s
opnbpeia documentation at dppl6++`k_o*lupdkj*knc+he^n]nu+peia*dpihpeia*
opnbpeia.) It’s set to !^ by default, which is a three-letter month abbreviation
(i.e., “jan,” “feb,” etc.). To change it to use numbers, use !i.
ÊUÊ]hhks[bqpqna: A Boolean specifying whether to include “future” objects on this page, as
described in the previous note.
This view may also take these common arguments (refer to Table C-1):
ÊUÊ]hhks[ailpu
ÊUÊ_kjpatp[lnk_aookno
ÊUÊatpn][_kjpatp
ÊUÊieiapula
ÊUÊpailh]pa[hk]`an
ÊUÊpailh]pa[j]ia
ÊUÊpailh]pa[k^fa_p[j]ia
APPENDIX C N GENERIC VIEW REFERENCE
406
Template Name
If pailh]pa[j]ia isn’t specified, this view will use the template 8]ll[h]^ah:+8ik`ah[j]ia:[
]n_dera[ikjpd*dpih by default.
Template Context
In addition to atpn][_kjpatp, the template’s context will be as follows:
ÊUÊikjpd: A `]papeia*`]pa object representing the given month.
ÊUÊjatp[ikjpd: A `]papeia*`]pa object representing the first day of the next month. If the
next month is in the future, this will be Jkja.
ÊUÊlnarekqo[ikjpd: A `]papeia*`]pa object representing the first day of the previous
month. Unlike jatp[ikjpd, this will never be Jkja.
ÊUÊk^fa_p[heop: A list of objects available for the given month. This variable’s name
depends on the pailh]pa[k^fa_p[j]ia parameter, which is #k^fa_p# by default. If
pailh]pa[k^fa_p[j]ia is #bkk#, this variable’s name will be bkk[heop.
Week Archives
View function: `f]jck*reaso*cajane_*`]pa[^]oa`*]n_dera[saag
This view shows all objects in a given week.
NNote &ORTHESAKEOFCONSISTENCYWITH0YTHONSBUILTINDATETIMEHANDLING$JANGOASSUMESTHATTHEFIRST
day of the week is Sunday.
Example
qnhl]ppanjo9l]ppanjo$##(
***
$
n#Z$;L8ua]n:`w0y%+$;L8saag:`w.y%+ #(
`]pa[^]oa`*]n_dera[saag(
^kkg[ejbk
%(
%
APPENDIX C N GENERIC VIEW REFERENCE 407
Required Arguments
ÊUÊua]n: The four-digit year for which the archive serves (a string).
ÊUÊsaag: The week of the year for which the archive serves (a string).
ÊUÊmqanuoap: A MqanuOap of objects for which the archive serves.
ÊUÊ`]pa[beah`: The name of the @]paBeah` or @]paPeiaBeah` in the MqanuOap’s model that
the date-based archive should use to determine the objects on the page.
Optional Arguments
ÊUÊ]hhks[bqpqna: A Boolean specifying whether to include “future” objects on this page, as
described in the previous note.
This view may also take these common arguments (refer to Table C-1):
ÊUÊ]hhks[ailpu
ÊUÊ_kjpatp[lnk_aookno
ÊUÊatpn][_kjpatp
ÊUÊieiapula
ÊUÊpailh]pa[hk]`an
ÊUÊpailh]pa[j]ia
ÊUÊpailh]pa[k^fa_p[j]ia
Template Name
If pailh]pa[j]ia isn’t specified, this view will use the template 8]ll[h]^ah:+8ik`ah[j]ia:[
]n_dera[saag*dpih by default.
Template Context
In addition to atpn][_kjpatp, the template’s context will be as follows:
ÊUÊsaag: A `]papeia*`]pa object representing the first day of the given week.
ÊUÊk^fa_p[heop: A list of objects available for the given week. This variable’s name
depends on the pailh]pa[k^fa_p[j]ia parameter, which is #k^fa_p# by default.
If pailh]pa[k^fa_p[j]ia is #bkk#, this variable’s name will be bkk[heop.
APPENDIX C N GENERIC VIEW REFERENCE
408
Day Archives
View function: `f]jck*reaso*cajane_*`]pa[^]oa`*]n_dera[`]u
This view generates all objects in a given day.
Example
qnhl]ppanjo9l]ppanjo$##(
***
$
n#Z$;L8ua]n:`w0y%+$;L8ikjpd:W])vYw/y%+$;L8`]u:`w.y%+ #(
`]pa[^]oa`*]n_dera[`]u(
^kkg[ejbk
%(
%
Required Arguments
ÊUÊua]n: The four-digit year for which the archive serves (a string).
ÊUÊikjpd: The month for which the archive serves, formatted according to the ikjpd[
bkni]p argument.
ÊUÊ`]u: The day for which the archive serves, formatted according to the `]u[bkni]p
argument.
ÊUÊmqanuoap: A MqanuOap of objects for which the archive serves.
ÊUÊ`]pa[beah`: The name of the @]paBeah` or @]paPeiaBeah` in the MqanuOap’s model that
the date-based archive should use to determine the objects on the page.
Optional Arguments
ÊUÊikjpd[bkni]p: A format string that regulates what format the ikjpd parameter uses.
See the detailed explanation in the preceding “Month Archives” section.
ÊUÊ`]u[bkni]p: Like ikjpd[bkni]p, but for the `]u parameter. It defaults to !` (the day of
the month as a decimal number, 01-31).
ÊUÊ]hhks[bqpqna: A Boolean specifying whether to include “future” objects on this page, as
described in the previous note.
This view may also take these common arguments (refer to Table C-1):
ÊUÊ]hhks[ailpu
ÊUÊ_kjpatp[lnk_aookno
ÊUÊatpn][_kjpatp
APPENDIX C N GENERIC VIEW REFERENCE 409
ÊUÊieiapula
ÊUÊpailh]pa[hk]`an
ÊUÊpailh]pa[j]ia
ÊUÊpailh]pa[k^fa_p[j]ia
Template Name
If pailh]pa[j]ia isn’t specified, this view will use the template 8]ll[h]^ah:+8ik`ah[j]ia:[
]n_dera[`]u*dpih by default.
Template Context
In addition to atpn][_kjpatp, the template’s context will be as follows:
ÊUÊ`]u: A `]papeia*`]pa object representing the given day.
ÊUÊjatp[`]u: A `]papeia*`]pa object representing the next day. If the next day is in the
future, this will be Jkja.
ÊUÊlnarekqo[`]u: A `]papeia*`]pa object representing the previous day. Unlike jatp[`]u,
this will never be Jkja.
ÊUÊk^fa_p[heop: A list of objects available for the given day. This variable’s name depends
on the pailh]pa[k^fa_p[j]ia parameter, which is #k^fa_p# by default. If pailh]pa[
k^fa_p[j]ia is #bkk#, this variable’s name will be bkk[heop.
Archive for Today
The `f]jck*reaso*cajane_*`]pa[^]oa`*]n_dera[pk`]u view shows all objects for today. This
is exactly the same as ]n_dera[`]u, except the ua]n/ikjpd/`]u arguments are not used, and
today’s date is used instead.
Example
qnhl]ppanjo9l]ppanjo$##(
***
$n#Z^kkgo+pk`]u+ #(`]pa[^]oa`*]n_dera[pk`]u(^kkg[ejbk%(
%
Date-Based Detail Pages
View function: `f]jck*reaso*cajane_*`]pa[^]oa`*k^fa_p[`ap]eh
Use this view for a page representing an individual object.
This has a different URL from the k^fa_p[`ap]eh view; the k^fa_p[`ap]eh view uses URLs
such as +ajpneao+8ohqc:+, whereas this one uses URLs such as +ajpneao+.,,2+]qc+.3+8ohqc:+.
APPENDIX C N GENERIC VIEW REFERENCE
410
NNote )FYOUREUSINGDATEBASEDDETAILPAGESWITHSLUGSINTHE52,SYOUPROBABLYALSOWANTTOUSE
the qjemqa[bkn[`]paOPTIONONTHESLUGFIELDTOVALIDATETHATSLUGSARENTDUPLICATEDINASINGLEDAY
See Appendix A for details on qjemqa[bkn[`]pa.
Example
This one differs (slightly) from all the other date-based examples in that we need to provide
either an object ID or a slug so that Django can look up the object in question.
Since the object we’re using doesn’t have a slug field, we’ll use ID-based URLs. It’s consid-
ered a best practice to use a slug field, but in the interest of simplicity we’ll let it go.
qnhl]ppanjo9l]ppanjo$##(
***
$
n#Z$;L8ua]n:`w0y%+$;L8ikjpd:W])vYw/y%+$;L8`]u:`w.y%+$;L8k^fa_p[e`:Ws)Y'%+ #(
`]pa[^]oa`*k^fa_p[`ap]eh(
^kkg[ejbk
%(
%
Required Arguments
ÊUÊua]n: The object’s four-digit year (a string).
ÊUÊikjpd: The object’s month, formatted according to the ikjpd[bkni]p argument.
ÊUÊ`]u: The object’s day, formatted according to the `]u[bkni]p argument.
ÊUÊmqanuoap: A MqanuOap that contains the object.
ÊUÊ`]pa[beah`: The name of the @]paBeah` or @]paPeiaBeah` in the MqanuOap’s model that
the generic view should use to look up the object according to ua]n, ikjpd, and `]u.
You’ll also need either:
ÊUÊk^fa_p[e`: The value of the primary-key field for the object.
or:
ÊUÊohqc: The slug of the given object. If you pass this field, then the ohqc[beah` argument
(described in the following section) is also required.
APPENDIX C N GENERIC VIEW REFERENCE 411
Optional Arguments
ÊUÊ]hhks[bqpqna: A Boolean specifying whether to include “future” objects on this page,
as described in the previous note.
ÊUÊ`]u[bkni]p: Like ikjpd[bkni]p, but for the `]u parameter. It defaults to !` (the day of
the month as a decimal number, 01-31).
ÊUÊikjpd[bkni]p: A format string that regulates what format the ikjpd parameter uses.
See the detailed explanation in the “Month Archives” section.
ÊUÊohqc[beah`: The name of the field on the object containing the slug. This is required if
you are using the ohqc argument, but it must be absent if you’re using the k^fa_p[e`
argument.
ÊUÊpailh]pa[j]ia[beah`: The name of a field on the object whose value is the template
name to use. This lets you store template names in the data. In other words, if your
object has a field #pda[pailh]pa# that contains a string #bkk*dpih#, and you set
pailh]pa[j]ia[beah` to #pda[pailh]pa#, the generic view for this object will use
the template #bkk*dpih#.
This view may also take these common arguments (refer to Table C-1):
ÊUÊ_kjpatp[lnk_aookno
ÊUÊatpn][_kjpatp
ÊUÊieiapula
ÊUÊpailh]pa[hk]`an
ÊUÊpailh]pa[j]ia
ÊUÊpailh]pa[k^fa_p[j]ia
Template Name
If pailh]pa[j]ia and pailh]pa[j]ia[beah` aren’t specified, this view will use the template
8]ll[h]^ah:+8ik`ah[j]ia:[`ap]eh*dpih by default.
Template Context
In addition to atpn][_kjpatp, the template’s context will be as follows:
ÊUÊk^fa_p: The object. This variable’s name depends on the pailh]pa[k^fa_p[j]ia param-
eter, which is #k^fa_p# by default. If pailh]pa[k^fa_p[j]ia is #bkk#, this variable’s
name will be bkk.
APPENDIX D
Settings
Your Django settings file contains all the configuration of your Django installation. This
appendix explains how settings work and which settings are available.
The Basics of Settings Files
A settings file is just a Python module with module-level variables.
Here are a couple of example settings:
@A>QC9B]hoa
@AB=QHP[BNKI[AI=EH9#sa^i]opan<at]ilha*_ki#
PAILH=PA[@ENO9$#+dkia+pailh]pao+iega#(#+dkia+pailh]pao+fkdj#%
Because a settings file is a Python module, the following apply to it:
Ê UÊ ÌÊÕÃÌÊLiÊÛ>`Ê*ÞÌÊV`iÆÊÃÞÌ>ÝÊiÀÀÀÃÊ>Ài½ÌÊ>Üi`°
Ê UÊ ÌÊV>Ê>ÃÃ}ÊÃiÌÌ}ÃÊ`Þ>V>ÞÊÕÃ}ÊÀ>Ê*ÞÌÊÃÞÌ>Ý]ÊvÀÊiÝ>«i
IU[OAPPEJC9Wopn$e%bkneejn]jca$/,%Y
Ê UÊ ÌÊV>Ê«ÀÌÊÛ>Õià from other settings files.
Default Settings
A Django settingsÊviÊ`iÃ½ÌÊ>ÛiÊÌÊ`iviÊ>ÞÊÃiÌÌ}ÃÊvÊÌÊ`iÃ½ÌÊii`ÊÌ°Ê>VÊÃiÌÌ}Ê
has a sensible default value. These defaults live in the file `f]jck+_kjb+chk^]h[oappejco*lu.
Here are the steps Django uses in compiling settings:
1. Load settings from chk^]h[oappejco*lu.
2. Load settings from the specified settings file, overriding the global settings as
necessary.
Note that a settings file should not import from chk^]h[oappejco*lu, becauseÊÌ>̽ÃÊ
redundant.
413
APPENDIX D N SETTINGS
414
Seeing Which Settings You’ve Changed
/iÀi½ÃÊ>Êi>ÃÞ way to view which of your settings deviate from the default settings. The
command i]j]ca*lu`ebboappejco displays differences between the current settings file and
>}½ÃÊ`iv>ÕÌÊÃiÌÌ}ð
i]j]ca*lu is described in more detail in Appendix F.
Using Settings in Python Code
ÊÞÕÀÊ>} applications, use settings by importing the object `f]jck*_kjb*oappejco, as in
this example:
bnki`f]jck*_kjbeilknpoappejco
eboappejco*@A>QC6
@kokiapdejc
Note that `f]jck*_kjb*oappejcoÊÃ½ÌÊ>Ê`ÕiÆÊ̽ÃÊ>ÊLiVÌ°Ê-Ê«ÀÌ}Ê`Û`Õ>ÊÃiÌ-
tings is not possible:
bnki`f]jck*_kjb*oappejcoeilknp@A>QCPdeoskj#pskng*
Also note that your code should not import from either chk^]h[oappejco or your own set-
tings file. `f]jck*_kjb*oappejco abstracts the concepts of default settings and site-specific
ÃiÌÌ}ÃÆÊÌÊ«ÀiÃiÌÃÊ>ÊÃ}iÊÌiÀv>Vi°ÊÌÊ>ÃÊ`iVÕ«iÃÊÌiÊV`iÊÌ>ÌÊÕÃiÃÊÃiÌÌ}Ã from the
location of your settings.
Altering Settings at Runtime
9ÕÊÃÕ`½ÌÊ>ÌiÀÊÃiÌÌ}ÃÊÊÞÕÀÊ>««V>ÌÃÊ>ÌÊÀÕÌi°ÊÀÊiÝ>«i]Ê`½ÌÊ`ÊÌÃÊÊ
a view:
bnki`f]jck*_kjbeilknpoappejco
oappejco*@A>QC9Pnqa@kj#p`kpdeo
The only place that settings should be defined in is a settings file.
Security
Because a settings file contains sensitive information, such as the database password, you
should make every attempt to limit access to it. For example, change its file permissions so
Ì>ÌÊÞÊÞÕÊ>`ÊÞÕÀÊ7iLÊÃiÀÛiÀ½ÃÊÕÃiÀÃÊV>ÊÀi>`ÊÌ°Ê/ÃÊÃÊiëiV>Þ important in a shared-
hosting environment.
APPENDIX D N SETTINGS 415
Creating Your Own Settings
/iÀi½ÃÊÌ}ÊÃÌ««} you from creating your own settings for your own Django applica-
tions. Just follow these conventions:
Ê UÊ 1ÃiÊ>ÊÕ««iÀV>ÃiÊvÀÊÃiÌÌ}Ê>ið
Ê UÊ ÀÊÃiÌÌ}ÃÊÌ>ÌÊ>ÀiÊÃiµÕiViÃ]ÊÕÃiÊÌÕ«iÃÊÃÌi>`ÊvÊÃÌðÊ-iÌÌ}ÃÊÃÕ`ÊLiÊVÃ`-
iÀi`ÊÕÌ>LiÊ>`ÊÃÕ`½ÌÊLiÊV>}i`ÊViÊÌiÞ½ÀiÊ`ivi`°Ê
Ê UÊ ½ÌÊÀiÛiÌ an existing setting.
Designating the Settings: DJANGO_SETTINGS_
MODULE
When you use Django, you haveÊÌÊÌiÊÌÊÜVÊÃiÌÌ}ÃÊÞÕ½ÀiÊÕÃ}°ÊÊÌÃÊLÞÊÕÃ}ÊÌiÊiÛ-
ronment variable @F=JCK[OAPPEJCO[IK@QHA.
The value of @F=JCK[OAPPEJCO[IK@QHA should be in Python path syntax (e.g., iuoepa*
oappejco). Note that the settings module should be on the Python import search path
(LUPDKJL=PD).
NTip A good guide to LUPDKJL=PD can be found at dppl6++`eraejpklupdkj*knc+cappejc[pk[gjks[
lupdkj+aranupdejc[eo[]j[k^fa_p*dpih.
The django-admin.py Utility
When using `f]jck)]`iej*lu (see Appendix F), you can either set the environment variable
once or explicitly pass in the settings module each time you run the utility.
iÀi½ÃÊ>ÊiÝ>«iÊÕÃ}ÊÌiÊ1ÝÊ>ÃÊÃi\
atlknp@F=JCK[OAPPEJCO[IK@QHA9iuoepa*oappejco
`f]jck)]`iej*lunqjoanran
iÀi½ÃÊ>ÊiÝ>«iÊÕÃ}ÊÌiÊ7`ÜÃÊÃi\
oap@F=JCK[OAPPEJCO[IK@QHA9iuoepa*oappejco
`f]jck)]`iej*lunqjoanran
1ÃiÊÌiÊ))oappejco command-line argument to specify the settings manually:
`f]jck)]`iej*lunqjoanran))oappejco9iuoepa*oappejco
The i]j]ca*lu utility created by op]nplnkfa_p as part of the project skeleton sets @F=JCK[
OAPPEJCO[IK@QHAÊ>ÕÌ>ÌV>ÞÆÊÃiiÊ««i`ÝÊ for more about i]j]ca*lu.
APPENDIX D N SETTINGS
416
On the Server (mod_python)
ÊÞÕÀÊÛiÊÃiÀÛiÀÊiÛÀiÌ]ÊÞÕ½Êii`ÊÌÊÌiÊ«>ViÉ`Ú«ÞÌÊÜVÊÃiÌÌ}ÃÊviÊÌÊ
use. Do that with OapAjr:
8Hk_]pekj+iuoepa+:
OapD]j`hanlupdkj)lnkcn]i
LupdkjD]j`han`f]jck*_kna*d]j`hano*ik`lupdkj
OapAjr@F=JCK[OAPPEJCO[IK@QHAiuoepa*oappejco
8+Hk_]pekj:
For more information, readÊÌiÊ>}Ê`Ú«ÞÌ documentation online at dppl6++
`k_o*`f]jcklnkfa_p*_ki+aj+`ar+dkspk+`alhkuiajp+ik`lupdkj+.
Using Settings Without Setting DJANGO_
SETTINGS_MODULE
ÊÃiÊV>ÃiÃ]ÊÞÕ might want to bypass the @F=JCK[OAPPEJCO[IK@QHA environment variable.
ÀÊiÝ>«i]ÊvÊÞÕ½ÀiÊÕÃ}ÊÌiÊÌi«>ÌiÊÃÞÃÌiÊLÞÊÌÃiv]ÊÞÕÊiÞÊ`½ÌÊÜ>ÌÊÌÊ>ÛiÊÌÊÃiÌÊ
up an environment variable pointing to a settings module.
ÊÌiÃiÊV>ÃiÃ]ÊÞÕÊV>ÊVv}ÕÀiÊ>}½ÃÊÃiÌÌ}ÃÊ>Õ>Þ°ÊÊÌÃÊLÞÊV>}Ê`f]jck*
_kjb*oappejco*_kjbecqna$%°ÊiÀi½ÃÊ>ÊiÝ>«i\
bnki`f]jck*_kjbeilknpoappejco
oappejco*_kjbecqna$
@A>QC9Pnqa(
PAILH=PA[@A>QC9Pnqa(
PAILH=PA[@ENO9W
#+dkia+sa^)]llo+iu]ll#(
#+dkia+sa^)]llo+^]oa#(
Y
%
Pass _kjbecqna$%Ê>ÃÊ>ÞÊiÞÜÀ`Ê>À}ÕiÌÃÊ>ÃÊÞÕ½`Êi]ÊÜÌÊi>VÊiÞÜÀ`Ê>À}ÕiÌÊ
Ài«ÀiÃiÌ}Ê>ÊÃiÌÌ}Ê>`ÊÌÃÊÛ>Õi°Ê>VÊ>À}ÕiÌÊ>iÊÃÕ`ÊLiÊ>ÊÕ««iÀV>Ãi]ÊÜÌÊÌiÊ
Ã>iÊ>iÊ>ÃÊÌiÊÃiÌÌ}ÃÊ`iÃVÀLi`Êi>ÀiÀ°ÊvÊ>Ê«>ÀÌVÕ>ÀÊÃiÌÌ}ÊÃÊÌÊ«>ÃÃi`ÊÌÊ_kjbecqna$%
and is needed at some later point, Django will use the default setting value.
Configuring Django in this fashion is necessary mostly—and, indeed, recommended—
ÜiÊÞÕ½ÀiÊÕÃ}Ê>Ê«iViÊvÊÌiÊvÀ>iÜÀÊÃ`iÊ>Ê>À}iÀÊ>««V>Ì°ÊÃiµÕiÌÞ]ÊÜiÊ
configured via oappejco*_kjbecqna$%, Django will not make any modifications to the process
iÛÀiÌÊÛ>À>LiðÊ-iiÊÌiÊiÝ«>>ÌÊvÊPEIA[VKJA later in this appendix to find out why
ÌÃÊÜÕ`ÊÀ>ÞÊVVÕÀ°®Ê̽ÃÊ>ÃÃÕi`ÊÌ>ÌÊÞÕ½ÀiÊ>Ài>`ÞÊÊvÕÊVÌÀÊvÊÞÕÀÊiÛÀ-
ment in these cases.
APPENDIX D N SETTINGS 417
Custom Default Settings
vÊÞÕ½`Êi default values to come from somewhere other than `f]jck*_kjb*chk^]h[oappejco,
you can pass in a module or class that provides the default settings as the `ab]qhp[oappejco
argument (or as the first positional argument) in the call to _kjbecqna$%.
ÊÌÃÊiÝ>«i]Ê`iv>ÕÌÊÃiÌÌ}ÃÊ>ÀiÊÌ>iÊvÀÊiu]ll[`ab]qhpo, and the @A>QC setting is
set to Pnqa, regardless of its value in iu]ll[`ab]qhpo:
bnki`f]jck*_kjbeilknpoappejco
bnkiiu]lleilknpiu]ll[`ab]qhpo
oappejco*_kjbecqna$`ab]qhp[oappejco9iu]ll[`ab]qhpo(@A>QC9Pnqa%
The following example, which uses iu]ll[`ab]qhpoÊ>ÃÊ>Ê«ÃÌ>Ê>À}ÕiÌ]ÊÃÊiµÕÛ>iÌ\
oappejco*_kjbecqna$iu]ll[`ab]qhpo(@A>QC9Pnqa%
Normally, you will not need to override the defaults in this fashion. The Django defaults
are sufficiently tame that you can safely use them. Be aware that if you do pass in a new default
module, it entirely replaces the Django defaults, so you must specify a value for every pos-
sible setting that might be used in that code you are importing. Check `f]jck*_kjb*oappejco*
chk^]h[oappejco for the full list.
Either configure() or DJANGO_SETTINGS_MODULE Is Required
vÊÞÕ½ÀiÊÌ setting the @F=JCK[OAPPEJCO[IK@QHA environment variable, you must call
_kjbecqna$% at some point before using any code that reads settings.
vÊÞÕÊ`½ÌÊÃiÌÊ@F=JCK[OAPPEJCO[IK@QHAÊ>`Ê`½ÌÊV>Ê_kjbecqna$%, Django will raise an
AjrenkjiajpAnnknÊiÝVi«ÌÊÌiÊvÀÃÌÊÌiÊ>ÊÃiÌÌ}ÊÃÊ>VViÃÃi`°ÊvÊÞÕÊÃiÌÊ@F=JCK[OAPPEJCO[
IK@QHA, access settings values, and then call _kjbecqna$%, Django will raise an AjrenkjiajpAnnkn
stating that settings have already been configured.
Ã]Ê̽ÃÊ>ÊiÀÀÀÊÌÊV>Ê_kjbecqna$% more than once or to call _kjbecqna$% after any set-
ting has been accessed.
ÌÊLÃÊ`ÜÊÌÊÌÃ\ÊÕÃiÊiÝ>VÌÞÊiÊv either _kjbecqna$% or @F=JCK[OAPPEJCO[IK@QHA, and
use it only once.
Available Settings
The following sections consist of a list of the main available settings, in alphabetical order, and
their default values.
ABSOLUTE_URL_OVERRIDES
Default: wy (empty dictionary)
This is a dictionary mapping ]ll[h]^ah*ik`ah[j]ia strings to functions that take a
`iÊLiVÌÊ>`ÊÀiÌÕÀÊÌÃÊ1,°Ê/ÃÊÃÊ>ÊÜ>ÞÊvÊÛiÀÀ`}Êcap[]^okhqpa[qnh$% methods on a
«iÀÃÌ>>ÌÊL>ÃðÊiÀi½ÃÊ>ÊiÝ>«i\
=>OKHQPA[QNH[KRANNE@AO9w
#^hkco*sa^hkc#6h]i^`]k6+^hkco+!o+!k*ohqc(
#jaso*opknu#6h]i^`]k6+opkneao+!o+!o+!$k*lq^[ua]n(k*ohqc%(
y
APPENDIX D N SETTINGS
418
Note that the model name used in this setting should be all lowercase, regardless of the
case of the actual model class name.
ADMIN_MEDIA_PREFIX
Default: #+ia`e]+#
This setting isÊÌiÊ1,Ê«ÀivÝÊvÀÊ>`Êi`>\Ê--]Ê>Û>-VÀ«Ì]Ê>`Ê>}iðÊ>iÊÃÕÀiÊÌÊ
use a trailing slash.
ADMINS
Default: $% (empty tuple)
This is a tuple that lists people who get code-error notifications. When @A>QC9B]hoa and a
view raises an exception, Django will e-mail these people with the full exception information.
>VÊiLiÀÊvÊÌiÊÌÕ«iÊÃÕ`ÊLiÊ>ÊÌÕ«iÊvÊÕÊ>i]Êi>Ê>``ÀiÃî]ÊvÀÊiÝ>«i\
$$#Fkdj#(#fkdj<at]ilha*_ki#%($#I]nu#(#i]nu<at]ilha*_ki#%%
Note that Django will e-mail all of these people whenever an error happens.
ALLOWED_INCLUDE_ROOTS
Default: $% (empty tuple)
This is a tuple of strings representing allowed prefixes for the w!ooe!y template tag.
/ÃÊÃÊ>ÊÃiVÕÀÌÞÊi>ÃÕÀiÊÃÊÌ>ÌÊÌi«>ÌiÊ>ÕÌÀÃÊV>½ÌÊ>VViÃÃÊviÃÊÌ>ÌÊÌiÞÊÃÕ`½ÌÊLiÊ
accessing.
For example, if =HHKSA@[EJ?HQ@A[NKKPO is $#+dkia+dpih#(#+r]n+sss#%, then w!ooe
+dkia+dpih+bkk*ptp!y would work, but w!ooe+ap_+l]oos`!yÊÜÕ`½Ì°
APPEND_SLASH
Default: Pnqa
This setting indicatesÊÜiÌiÀÊÌÊ>««i`ÊÌÀ>}ÊÃ>ÃiÃÊÌÊ1,ðÊ/ÃÊÃÊÕÃi`ÊÞÊvÊ
?kiikjIe``has]naÊÃÊÃÌ>i`ÊÃiiÊ>«ÌiÀʣǮ°Ê-ii also LNALAJ@[SSS.
CACHE_BACKEND
Default: #hk_iai6++#
This is the cache back-end to use (see Chapter 15).
CACHE_MIDDLEWARE_KEY_PREFIX
Default: ## (empty string)
This is the cache key prefix that the cache middleware should use (see Chapter 15).
DATABASE_ENGINE
Default: ## (empty string)
This setting indicates which database back-end to use, (e.g., #lkopcnaomh[lou_klc.# or
#iuomh#).
APPENDIX D N SETTINGS 419
DATABASE_HOST
Default: ## (empty string)
This setting indicates which host to use when connecting to the database. An empty string
means hk_]hdkop°Ê/ÃÊÃÊÌÊÕÃi`ÊÜÌÊ-+Ìi°
vÊÌÃÊÛ>ÕiÊÃÌ>ÀÌÃÊÜÌÊ>ÊvÀÜ>À`ÊÃ>ÃÊ#+#®Ê>`ÊÞÕ½ÀiÊÕÃ}ÊÞ-+]ÊÞ-+ÊÜÊViVÌÊ
Û>Ê>Ê1ÝÊÃViÌÊÌÊÌiÊëiVvi`ÊÃViÌ\
@=P=>=OA[DKOP9#+r]n+nqj+iuomh#
vÊÞÕ½ÀiÊÕÃ}ÊÞ-+Ê>`ÊÌÃÊÛ>ÕiÊdoesn’t start with a forward slash, then this value is
assumed to be the host.
DATABASE_NAME
Default: ## (empty string)
This is the nameÊvÊÌiÊ`>Ì>L>ÃiÊÌÊÕÃi°ÊÀÊ-+Ìi]Ê̽ÃÊÌiÊvÕÊ«>Ì to the database file.
DATABASE_OPTIONS
Default: wy (empty dictionary)
This specifies extra parameters to use when connecting to the database. Consult the back-
i`Ê`Õi½ÃÊ`VÕiÌ for available keywords.
DATABASE_PASSWORD
Default: ## (empty string)
This setting isÊÌiÊ«>ÃÃÜÀ`ÊÌÊÕÃiÊÜiÊViVÌ}ÊÌÊÌiÊ`>Ì>L>Ãi°ÊÌ is not used with
-+Ìi°
DATABASE_PORT
Default: ## (empty string)
This is the port to use when connecting to the database. An empty string means the
`iv>ÕÌÊ«ÀÌ°ÊÌÊÃÊÌÊÕÃi`ÊÜÌÊ-+Ìi°
DATABASE_USER
Default: ## (empty string)
This setting isÊÌiÊÕÃiÀ>iÊÌÊÕÃiÊÜiÊViVÌ}ÊÌÊÌiÊ`>Ì>L>Ãi°ÊÌ is not used with
-+Ìi°
DATE_FORMAT
Default: #Jf(U# (e.g., Ba^*0(.,,/)
This is the default formatting to use for date fields on Django admin change-list pages—
>`]Ê«ÃÃLÞ]ÊLÞÊÌiÀÊ«>ÀÌÃÊvÊÌiÊÃÞÃÌi°ÊÌÊ>VVi«ÌÃÊÌiÊÃ>iÊvÀ>Ì as the jks tag (see
««i`ÝÊ]Ê/>LiÊÓ®°
-iiÊ>ÃÊ@=PAPEIA[BKNI=P, PEIA[BKNI=P, UA=N[IKJPD[BKNI=P, and IKJPD[@=U[BKNI=P.
APPENDIX D N SETTINGS
420
DATETIME_FORMAT
Default: #Jf(U(L# (e.g., Ba^*0(.,,/(0l*i*)
This is the default formatting to use for datetime fields on Django admin change-list
«>}iÃp>`]Ê«ÃÃLÞ]ÊLÞÊÌiÀÊ«>ÀÌÃÊvÊÌiÊÃÞÃÌi°ÊÌÊ>VVi«ÌÃÊÌiÊÃ>iÊvÀ>ÌÊ>ÃÊÌiÊjks tag
(see AppendixÊ]Ê/>LiÊÓ®°
-iiÊ>ÃÊ@=PA[BKNI=P, PEIA[BKNI=P, UA=N[IKJPD[BKNI=P, and IKJPD[@=U[BKNI=P.
DEBUG
Default: B]hoa
This setting is a Boolean that turns debug mode on and off.
vÊÞÕÊ`iviÊVÕÃÌÊÃiÌÌ}Ã]Ê`f]jck+reaso+`a^qc*lu has a DE@@AJ[OAPPEJCO regular
expression that will hide from the @A>QC view anything that contains OA?NAP, L=OOSKN@, or
LNKB=JEPEAO. This allows untrusted users to be able to provide backtraces without seeing
sensitive (or offensive) settings.
-Ì]ÊÌiÊÌ>ÌÊÌiÀiÊ>ÀiÊ>Ü>ÞÃÊ}}ÊÌÊLiÊÃiVÌÃÊvÊÞÕÀÊ`iLÕ}ÊÕÌ«ÕÌÊÌ>ÌÊ>ÀiÊ>«-
propriate for public consumption. File paths, configuration options, and the like all give
attackers extra information about your server. Never deploy a site with @A>QC turned on.
DEFAULT_CHARSET
Default: #qpb)4#
This is the default charset to use for all DpplNaolkjoaÊLiVÌÃÊvÊ>ÊÊÌÞ«iÊÃ½ÌÊëiV-
vi`Ê>Õ>Þ°ÊÌÊÃÊÕÃi`ÊÜÌÊ@AB=QHP[?KJPAJP[PULA to construct the ?kjpajp)Pula header.
-iiÊ««i`ÝÊÊvÀÊÀi about DpplNaolkjoa objects.
DEFAULT_CONTENT_TYPE
Default: #patp+dpih#
This is the default content type to use for all DpplNaolkjoaÊLiVÌÃÊvÊ>ÊÊÌÞ«iÊÃ½ÌÊ
>Õ>ÞÊëiVvi`°ÊÌÊÃÊÕÃi`ÊÜÌÊ@AB=QHP[?D=NOAP to construct the ?kjpajp)Pula header.
-iiÊ««i`ÝÊÊvÀÊÀi about DpplNaolkjoa objects.
DEFAULT_FROM_EMAIL
Default: #sa^i]opan<hk_]hdkop#
This is the default e-mail address to use for various automated correspondence from the
site manager(s).
DISALLOWED_USER_AGENTS
Default: $% (empty tuple)
This is a list of compiled regular-expression objects representing user-agent strings that
>ÀiÊÌÊ>Üi`ÊÌÊÛÃÌÊ>ÞÊ«>}i]ÊÃÞÃÌiÜ`i°Ê1ÃiÊÌÃÊvÀÊL>`ÊÀLÌÃÉVÀ>ÜiÀðÊ/ÃÊÃÊÕÃi`Ê
only if ?kiikjIe``has]na is installed (see Chapter 17).
APPENDIX D N SETTINGS 421
EMAIL_HOST
Default: #hk_]hdkop#
This is theÊÃÌÊÌÊÕÃiÊvÀÊÃi`}Êi>°Ê-ii also AI=EH[LKNP.
EMAIL_HOST_PASSWORD
Default: ## (empty string)
This is theÊ«>ÃÃÜÀ`ÊÌÊÕÃiÊvÀÊÌiÊ-/*ÊÃiÀÛiÀÊ`ivi`ÊÊAI=EH[DKOP. This setting is used
in conjunction with AI=EH[DKOP[QOANÊÜiÊ>ÕÌiÌV>Ì}ÊÌÊÌiÊ-/*ÊÃiÀÛiÀ°ÊvÊiÌiÀÊvÊ
ÌiÃiÊÃiÌÌ}ÃÊÃÊi«ÌÞ]Ê>}ÊÜ½ÌÊ>ÌÌi«ÌÊ>ÕÌiÌV>Ì°
-ii also AI=EH[DKOP[QOAN.
EMAIL_HOST_USER
Default: ## (empty string)
This is theÊÕÃiÀ>iÊÌÊÕÃiÊvÀÊÌiÊ-/*ÊÃiÀÛiÀÊ`ivi`ÊÊAI=EH[DKOP°ÊvÊ̽ÃÊi«ÌÞ]Ê
>}ÊÜ½ÌÊ>ÌÌi«ÌÊ>ÕÌiÌV>Ì°Ê-iiÊ>ÃÊAI=EH[DKOP[L=OOSKN@.
EMAIL_PORT
Default: .1
This is theÊ«ÀÌÊÌÊÕÃiÊvÀÊÌiÊ-/*ÊÃiÀÛiÀ defined in AI=EH[DKOP.
EMAIL_SUBJECT_PREFIX
Default: #W@f]jckY#
This is the subject-line prefix for e-mail messages sent with `f]jck*_kna*i]eh*i]eh[]`iejo
or `f]jck*_kna*i]eh*i]eh[i]j]cano°Ê9Õ½Ê«ÀL>LÞÊÜ>ÌÊÌ include a trailing space.
FIXTURE_DIRS
Default: $% (empty tuple)
This is a list of locations of the fixture data files, in search order. Note that these paths
ÃÕ`ÊÕÃiÊ1ÝÃÌÞiÊvÀÜ>À`ÊÃ>ÃiÃ]ÊiÛiÊÊ7`ÜðÊÌÊÃÊÕÃi`ÊLÞÊ>}½ÃÊÌiÃÌ}ÊvÀ>i-
work, which is covered online at dppl6++`k_o*`f]jcklnkfa_p*_ki+aj+`ar+pkle_o+paopejc+.
IGNORABLE_404_ENDS
Default: $#i]eh*lh#(#i]ehbkni*lh#(#i]eh*_ce#(#i]ehbkni*_ce#(#b]re_kj*e_k#(#*ldl#%
This is a tupleÊvÊÃÌÀ}ÃÊÌ>ÌÊëiVvÞÊLi}}ÃÊvÊ1,ÃÊÌ>ÌÊÃÕ`ÊLiÊ}Ài`ÊLÞÊÌiÊ{ä{Ê
i>iÀ°Ê-iiÊ>«ÌiÀÊ£ÓÊvÀÊÀiÊÊÌiÊ{ä{Êi>iÀ°®
ÊiÀÀÀÃÊÜÊLiÊÃiÌÊvÀÊ1,ÃÊÌ>ÌÊi`ÊÜÌÊÃÌÀ}ÃÊvÀÊÌÃÊÃiµÕiVi°
-ii also ECJKN=>HA[0,0[OP=NPO and OAJ@[>NKGAJ[HEJG[AI=EHO.
APPENDIX D N SETTINGS
422
IGNORABLE_404_STARTS
Default: $#+_ce)^ej+#(#+[rpe[^ej#(#+[rpe[ejb#%
This is just like ECJKN=>HA[0,0[AJ@OÊiÝVi«ÌÊÌÊ>««iÃÊÌÊÌiÊi`ÊvÊ1,ð
-ii also OAJ@[>NKGAJ[HEJG[AI=EHO and ECJKN=>HA[0,0[AJ@O.
INSTALLED_APPS
Default: $% (empty tuple)
A tuple of strings designating all applications that are enabled in this Django installation.
>VÊÃÌÀ}ÊÃÕ`ÊLiÊ>ÊvÕÊ*ÞÌÊ«>ÌÊÌÊ>Ê*ÞÌÊ«>V>}iÊÌ>ÌÊVÌ>ÃÊ>Ê>}Ê>««V>-
Ì°Ê-iiÊ>«ÌiÀÊxÊvÀ more about applications.
LANGUAGE_CODE
Default: #aj)qo#
This is a string representing the language code for this installation. This should be in stan-
`>À`Ê>}Õ>}iÊvÀ>ÌpvÀÊiÝ>«i]Ê1-Ê}Ã is aj)qo°Ê-iiÊ>«ÌiÀÊ£°
LANGUAGES
Default: A tuple of all available languages. This list is continually growing and any copy
included here would inevitably become rapidly out of date. You can see the current list of
translated languages by looking in `f]jck+_kjb+chk^]h[oappejco*lu.
The list is a tuple of two-tuples in the format (language code, language name)—for exam-
ple, $#f]#(#F]l]jaoa#%. This specifies which languages are available for language selection.
-iiÊ>«ÌiÀÊ£ÊvÀÊÀiÊÊ>}Õ>}iÊÃiiVÌ°
iiÀ>Þ]ÊÌiÊ`iv>ÕÌÊÛ>ÕiÊÃÕ`ÊÃÕvvVi°Ê"ÞÊÃiÌÊÌÃÊÃiÌÌ}ÊvÊÞÕÊÜ>ÌÊÌÊÀiÃÌÀVÌÊ>-
guage selection to a subset of the Django-provided languages.
vÊÞÕÊ`iviÊ>ÊVÕÃÌÊH=JCQ=CAOÊÃiÌÌ}]Ê̽ÃÊ"ÊÌÊ>ÀÊÌiÊ>}Õ>}iÃÊ>ÃÊÌÀ>Ã>ÌÊ
strings, but you should never import `f]jck*qpeho*pn]joh]pekj from within your settings file,
because that module itself depends on the settings, and that would cause a circular import.
The solution is to use a “dummy” cappatp$% function°ÊiÀi½ÃÊ>ÊÃ>«iÊÃiÌÌ}ÃÊvi\
cappatp9h]i^`]o6o
H=JCQ=CAO9$
$#`a#(cappatp$#Cani]j#%%(
$#aj#(cappatp$#Ajcheod#%%(
%
With this arrangement, i]ga)iaoo]cao*lu will still find and mark these strings for transla-
Ì]ÊLÕÌÊÌiÊÌÀ>Ã>ÌÊÜ½ÌÊ>««iÊ>ÌÊÀÕÌipÃÊÞÕ½Ê>ÛiÊÌÊÀiiLiÀÊÌÊÜÀ>«ÊÌiÊ
languages in the real cappatp$% in any code that uses H=JCQ=CAO at runtime.
APPENDIX D N SETTINGS 423
MANAGERS
Default: $% (empty tuple)
This tuple is in the same format as =@IEJOÆÊÌÊëiVviÃÊÜÊÃÕ`Ê}iÌÊLÀiÊÌvV>-
tions when OAJ@[>NKGAJ[HEJG[AI=EHO9Pnqa.
MEDIA_ROOT
Default: ## (empty string)
This is an absolute path to the directory that holds media for this installation (e.g., +dkia+
ia`e]+ia`e]*h]snaj_a*_ki+®°Ê-ii also IA@E=[QNH.
MEDIA_URL
Default: ## (empty string)
/ÃÊ1,Ê>`ià the media served from IA@E=[NKKP (e.g., dppl6++ia`e]*h]snaj_a*_ki).
Note that this should have a trailing slash if it has a path component:
ÊUÊCorrect: dppl6++sss*at]ilha*_ki+op]pe_+
ÊUÊIncorrect: dppl6++sss*at]ilha*_ki+op]pe_
-iiÊ>«ÌiÀÊ£ÓÊvÀÊÀiÊÊ`i«ÞiÌ and serving media.
MIDDLEWARE_CLASSES
Default:
$`f]jck*_kjpne^*oaooekjo*ie``has]na*OaooekjIe``has]na(
`f]jck*_kjpne^*]qpd*ie``has]na*=qpdajpe_]pekjIe``has]na(
`f]jck*ie``has]na*_kiikj*?kiikjIe``has]na(
`f]jck*ie``has]na*`k_*TReasIe``has]na%
This is a tuple of middleware classes toÊÕÃi°Ê-iiÊ>«ÌiÀʣǰ
MONTH_DAY_FORMAT
Default: #Bf#
This is the default formatting to use for date fields on Django admin change-list pages—
and, possibly, by other parts of the system—in cases when only the month and day are
`ë>Þi`°ÊÌÊ>VVi«ÌÃÊÌiÊÃ>iÊvÀ>ÌÊ>ÃÊÌiÊjksÊÌ>}ÊÃiiÊ««i`ÝÊ]Ê/>LiÊÓ®°
For example, when a Django admin change-list page is being filtered by a date, the header
for a given day displays the day and month. Different locales have different formats. For exam-
«i]Ê1-Ê}ÃÊÜÕ`Ê>Ûiʺ>Õ>ÀÞÊ£]»ÊÜiÀi>ÃÊ-«>ÃÊ}ÌÊ>Ûiʺ£ÊiiÀ°»
-ii also @=PA[BKNI=P, @=PAPEIA[BKNI=P, PEIA[BKNI=P, and UA=N[IKJPD[BKNI=P.
APPENDIX D N SETTINGS
424
PREPEND_WWW
Default: B]hoa
This setting indicatesÊÜiÌiÀÊÌÊ«Ài«i`ÊÌiʺÜÜÜ°»ÊÃÕL`>ÊÌÊ1,ÃÊÌ>ÌÊ`½ÌÊ>ÛiÊ
it. This is used only if ?kiikjIe``has]na is installed (seeÊ>«ÌiÀʣǮ°Ê-iiÊ>ÃÊ=LLAJ@[OH=OD.
ROOT_URLCONF
Default: Not defined
This is a stringÊÀi«ÀiÃiÌ}ÊÌiÊvÕÊ*ÞÌÊ«ÀÌÊ«>ÌÊÌÊÞÕÀÊÀÌÊ1,VvÊi°}°]Ê
iu`f]jck]llo*qnho®°Ê-ii Chapter 3.
SECRET_KEY
Default\ÊiiÀ>Ìi`Ê>ÕÌ>ÌV>Þ when you start a project
/ÃÊÃÊ>ÊÃiVÀiÌÊiÞÊvÀÊÌÃÊ«>ÀÌVÕ>ÀÊ>}ÊÃÌ>>Ì°ÊÌÊÃÊÕÃi`ÊÌÊ«ÀÛ`iÊ>Ê
Ãii`ÊÊÃiVÀiÌiÞÊ>Ã}Ê>}ÀÌðÊ-iÌÊÌÃÊÌÊ>ÊÀ>`ÊÃÌÀ}pÌiÊ}iÀ]ÊÌiÊLiÌÌiÀ°Ê
`f]jck)]`iej*luop]nplnkfa_p creates one automatically, and most of the time youÊÜ½ÌÊ
need to change it.
SEND_BROKEN_LINK_EMAILS
Default: B]hoa
This setting indicates whether to send an e-mail to the I=J=CANO each time somebody vis-
ÌÃÊ>Ê>}«ÜiÀi`Ê«>}iÊÌ>ÌÊÃÊ{ä{½i`ÊÜÌÊ>Êi«ÌÞÊÀiviÀiÀÊ°i°]Ê>ÊLÀiÊ®°Ê/ÃÊÃÊ
used only if ?kiikjIe``has]na is installed (seeÊ>«ÌiÀʣǮ°Ê-iiÊ>ÃÊECJKN=>HA[0,0[OP=NPO and
ECJKN=>HA[0,0[AJ@O.
SERIALIZATION_MODULES
Default: Not defined
-iÀ>â>ÌÊÃÊ>Êvi>ÌÕÀiÊÃÌÊÕ`iÀÊi>ÛÞÊ`iÛi«iÌ°Ê,iviÀÊÌÊÌiÊiÊ`VÕiÌ>-
tion at dppl6++`k_o*`f]jcklnkfa_p*_ki+aj+`ar+pkle_o+oane]hev]pekj+ for more information.
SERVER_EMAIL
Default: #nkkp<hk_]hdkop#
This is the e-mail address that error messages come from, such as those sent to =@IEJO and
I=J=CANO.
SESSION_COOKIE_AGE
Default: -.,52,, (two weeks, in seconds)
This is the age of session cookies, inÊÃiV`ðÊ-iiÊ>«ÌiÀÊ£{°
APPENDIX D N SETTINGS 425
SESSION_COOKIE_DOMAIN
Default: Jkja
This is theÊ`>ÊÌÊÕÃiÊvÀÊÃiÃÃÊViðÊ-iÌÊÌÃÊÌÊ>ÊÃÌÀ}ÊÃÕVÊ>ÃÊ*h]snaj_a*_ki
for cross-domain cookies, or use Jkja for a standard domainÊVi°Ê-iiÊ>«ÌiÀÊ£{°
SESSION_COOKIE_NAME
Default: #oaooekje`#
This is theÊ>iÊvÊÌiÊViÊÌÊÕÃiÊvÀÊÃiÃÃÃÆÊÌÊV>ÊLiÊÜ>ÌiÛiÀÊÞÕÊÜ>Ì°Ê-iiÊ
>«ÌiÀÊ£{°
SESSION_COOKIE_SECURE
Default: B]hoa
This setting indicatesÊÜiÌiÀÊÌÊÕÃiÊ>ÊÃiVÕÀiÊViÊvÀÊÌiÊÃiÃÃÊVi°ÊvÊÌÃÊÃÊÃiÌÊÌÊ
Pnqa, the cookie will be marked as “secure,” which means browsers may ensure that the cookie
ÃÊÃiÌÊÞÊÕ`iÀÊ>Ê//*-ÊViVÌ°Ê-iiÊ>«ÌiÀÊ£{°
SESSION_EXPIRE_AT_BROWSER_CLOSE
Default: B]hoa
This setting indicates whether to expire the session when the user closes his browser.
-iiÊ>«ÌiÀÊ£{°
SESSION_SAVE_EVERY_REQUEST
Default: B]hoa
This setting indicates whether to save the session data on everyÊÀiµÕiÃÌ°Ê-iiÊ>«ÌiÀÊ£{°
SITE_ID
Default: Not defined
/ÃÊÃÊÌiÊ]Ê>Ã an integer, of the current site in the `f]jck[oepaÊ`>Ì>L>ÃiÊÌ>Li°ÊÌÊÃÊÕÃi`Ê
so that application data can hook into specific site(s) and a single database can manage con-
tent for multipleÊÃÌiðÊ-iiÊ>«ÌiÀʣȰ
TEMPLATE_CONTEXT_PROCESSORS
Default:
$`f]jck*_kna*_kjpatp[lnk_aookno*]qpd(
`f]jck*_kna*_kjpatp[lnk_aookno*`a^qc(
`f]jck*_kna*_kjpatp[lnk_aookno*e-4j(
`f]jck*_kna*_kjpatp[lnk_aookno*ia`e]%
This is a tuple of callables that are used to populate the context in Namqaop?kjpatp. These
V>>LiÃÊÌ>iÊ>ÊÀiµÕiÃÌÊLiVÌÊ>ÃÊÌiÀÊ>À}ÕiÌÊ>`ÊÀiÌÕÀÊ>Ê`VÌ>ÀÞÊvÊÌiÃÊÌÊLiÊiÀ}i`Ê
into theÊVÌiÝÌ°Ê-iiÊ>«ÌiÀÊ°
APPENDIX D N SETTINGS
426
TEMPLATE_DEBUG
Default: B]hoa
This Boolean turnsÊÌi«>ÌiÊ`iLÕ}Ê`iÊÊ>`Êvv°ÊvÊÌÊÃÊPnqa, the fancy error page will
display a detailed report for any Pailh]paOujp]tAnnkn. This report contains the relevant snip-
pet of the template, with the appropriate line highlighted.
Note that Django displays fancy error pages only if @A>QC is Pnqa]ÊÃÊÞÕ½ÊÜ>ÌÊÌÊÃiÌÊÌ>ÌÊ
to take advantage of this setting.
-iiÊ>ÃÊ@A>QC.
TEMPLATE_DIRS
Default: $% (empty tuple)
This is a list of locations of the template source files, in search order. Note that these paths
ÃÕ`ÊÕÃiÊ1ÝÃÌÞiÊvÀÜ>À`ÊÃ>ÃiÃ]ÊiÛiÊÊ7`ÜðÊ-iiÊ>«ÌiÀÃÊ{Ê>`Ê°
TEMPLATE_LOADERS
Default: $#`f]jck*pailh]pa*hk]`ano*behaouopai*hk]`[pailh]pa[okqn_a#(#`f]jck*pailh]pa*
hk]`ano*]ll[`ena_pkneao*hk]`[pailh]pa[okqn_a#%
This is a tuple of callables (as strings) that know how to import templates from various
ÃÕÀViðÊ-iiÊ>«ÌiÀÊ°
TEMPLATE_STRING_IF_INVALID
Default: ##Ê«ÌÞÊÃÌÀ}®
This is output, as a string, that the template system should use for invalid (e.g., misspelled)
Û>À>LiðÊ-iiÊ>«ÌiÀÊ°
TEST_DATABASE_NAME
Default: Jkja
This is the nameÊvÊ`>Ì>L>ÃiÊÌÊÕÃiÊÜiÊÀÕ}ÊÌiÊÌiÃÌÊÃÕÌi°ÊvÊ>ÊÛ>ÕiÊvÊJkja is
specified, the test database will use the name #paop[#'oappejco*@=P=>=OA[J=IA°Ê-iiÊÌiÊ
`VÕiÌ>ÌÊvÀÊ>}½ÃÊÌiÃÌ}ÊvÀ>iÜÀ]ÊÜV is covered online at dppl6++`k_o*
`f]jcklnkfa_p*_ki+aj+`ar+pkle_o+paopejc+.
TEST_RUNNER
Default: #`f]jck*paop*oeilha*nqj[paopo#
This is theÊ>iÊvÊÌiÊiÌ`ÊÌÊÕÃiÊvÀÊÃÌ>ÀÌ}ÊÌiÊÌiÃÌÊÃÕÌi°ÊÌÊÃÊÕÃi`ÊLÞÊ>}½ÃÊÌiÃÌ-
ing framework, which is covered online at dppl6++`k_o*`f]jcklnkfa_p*_ki+aj+`ar+pkle_o+
paopejc+.
APPENDIX D N SETTINGS 427
TIME_FORMAT
Default: #L# (e.g., 0l*i*)
This is the default formatting to use for time fields on Django admin change-list pages—
>`]Ê«ÃÃLÞ]ÊLÞÊÌiÀÊ«>ÀÌÃÊvÊÌiÊÃÞÃÌi°ÊÌÊ>VVi«ÌÃÊÌiÊÃ>iÊvÀ>ÌÊ>ÃÊÌiÊjks tag (see
««i`ÝÊ]Ê/>LiÊÓ®°
-ii also @=PA[BKNI=P, @=PAPEIA[BKNI=P, PEIA[BKNI=P, UA=N[IKJPD[BKNI=P, and IKJPD[@=U[
BKNI=P.
TIME_ZONE
Default: #=iane_]+?de_]ck#
This is a stringÊÀi«ÀiÃiÌ}ÊÌiÊÌiÊâiÊvÀÊÌÃÊÃÌ>>Ì°Ê"iÊÀi>ÌÛiÞÊV«iÌiÊ
ÃÌÊvÊÌiâiÊÃÌÀ}ÃÊV>ÊLiÊvÕ`Ê>ÌÊdppl6++sss*lkopcnaomh*knc+`k_o+4*-+op]pe_+
`]papeia)gauskn`o*dpih@=PAPEIA)PEIAVKJA)OAP)P=>HA.
/ÃÊÃÊÌiÊÌiÊâiÊÌÊÜVÊ>}ÊÜÊVÛiÀÌÊ>Ê`>ÌiÃÉÌiÃpÌÊiViÃÃ>ÀÞÊÌiÊ
ÌiÊâiÊvÊÌiÊÃiÀÛiÀ°ÊÀÊiÝ>«i]ÊiÊÃiÀÛiÀÊ>ÞÊÃiÀÛiÊÕÌ«iÊ>}«ÜiÀi`ÊÃÌiÃ]Ê
i>VÊÜÌÊ>ÊÃi«>À>ÌiÊÌiâiÊÃiÌÌ}°
Normally, Django sets the ko*ajrenkjW#PV#Y variableÊÌÊÌiÊÌiÊâiÊÞÕÊëiVvÞÊÊÌiÊ
PEIA[VKJA setting. Thus, all your views and models will automatically operate in the correct
ÌiÊâi°ÊÜiÛiÀ]ÊvÊÞÕ½ÀiÊÕÃ}ÊÌiÊ>Õ>ÞÊVv}ÕÀi`ÊÃiÌÌ}ÃÊ`iÃVÀLi`Êi>ÀiÀÊÊÌiÊ
ÃiVÌʺ1Ã}Ê-iÌÌ}ÃÊ7ÌÕÌÊ-iÌÌ}Ê "Ú-// -Ú"1»®]Ê>}ÊÜÊnot
touch the PV environment variable, and it will be up to you to ensure your processes are run-
ning in the correct environment.
NNote Django cannot reliably use alternate time zones in a Windows environment. If you’re running Django
on Windows, this variable must be set to match the system time zone.
URL_VALIDATOR_USER_AGENT
Default: @f]jck+8ranoekj:$dppl6++sss*`f]jcklnkfa_p*_ki+%
This is the string to use as the Qoan)=cajpÊi>`iÀÊÜiÊViV}ÊÌÊÃiiÊvÊ1,ÃÊiÝÃÌÊÃiiÊ
the ranebu[ateopo option on QNHBeah`ÆÊÀiviÀ to Appendix A).
USE_ETAGS
Default: B]hoa
This Boolean specifiesÊÜiÌiÀÊÌÊÕÌ«ÕÌÊÌiÊ/>}Êi>`iÀ°ÊÌÊÃ>ÛiÃÊL>`Ü`ÌÊLÕÌÊÃÜÃÊ
down performance. This is used only if ?kiikjIe``has]na is installed (see Chapter 17).
APPENDIX D N SETTINGS
428
USE_I18N
Default: Pnqa
This Boolean specifiesÊÜiÌiÀÊ>}½ÃÊÌiÀ>Ì>â>ÌÊÃÞÃÌiÊÃiiÊ>«ÌiÀÊ£®Ê
ÃÕ`ÊLiÊi>Li`°ÊÌÊ«ÀÛ`iÃÊ>Êi>ÃÞÊÜ>ÞÊÌÊÌÕÀÊvvÊÌiÀ>Ì>â>ÌÊvÀÊ«iÀvÀ>Vi°Ê
vÊÌÃÊÃÊÃiÌÊÌÊB]hoa]Ê>}ÊÜÊ>iÊÃiÊ«Ìâ>ÌÃÊÃÊ>ÃÊÌÊÌÊ>`ÊÌiÊÌiÀ>Ì>-
â>Ì machinery.
YEAR_MONTH_FORMAT
Default: #BU#
This is the default formatting to use for date fields on Django admin change-list pages—
and, possibly, by other parts of the system—in cases when only the year and month are
`ë>Þi`°ÊÌÊ>VVi«ÌÃÊÌiÊÃ>iÊvÀ>ÌÊ>ÃÊÌiÊjksÊÌ>}ÊÃiiÊ««i`ÝÊ®°
For example, when a Django admin change-list page is being filtered by a date drill-down,
the header for a given month displays the month and the year. Different locales have different
vÀ>ÌðÊÀÊiÝ>«i]Ê1-Ê}Ã would use “JanuaryÊÓääÈ]»ÊÜiÀi>ÃÊ>ÌiÀÊV>iÊ}Ì use
ºÓääÈÉ>Õ>ÀÞ°»
-iiÊ>ÃÊ@=PA[BKNI=P, @=PAPEIA[BKNI=P, PEIA[BKNI=P, and IKJPD[@=U[BKNI=P.
APPENDIX E
Built-in Template Tags
and Filters
Chapter 4 lists a number of the most useful built-in template tags and filters. However,
Django ships with many more built-in tags and filters. This appendix covers them.
Built-in Tag Reference
autoescape
Controls the current autoescaping behavior. This tag takes either kj or kbb as an argument,
which determines whether autoescaping is in effect inside the block.
When autoescaping is in effect, all variable content has HTML escaping applied to it
before placing the result into the output (but after any filters have been applied). This is equiv-
alent to manually applying the ao_]la filter to each variable.
The only exceptions are variables that are already marked as “safe” from escaping, either
by the code that populated the variable or because it has had the o]ba or ao_]la filters applied.
block
Defines a block that can be overridden by child templates. See Chapter 4 for more information
on template inheritance.
comment
Ignores everything between w!_kiiajp!y and w!aj`_kiiajp!y.
429
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS
430
cycle
Cycles among the given strings or variables each time this tag is encountered.
Within a loop, cycles among the given strings each time through the loop:
w!bknkejokia[heop!y
8pn_h]oo9w!_u_ha#nks-##nks.#!y:
***
8+pn:
w!aj`bkn!y
You can use variables, too. For example, if you have two template variables, nksr]hqa- and
nksr]hqa., you can cycle between their values like this:
w!bknkejokia[heop!y
8pn_h]oo9w!_u_hanksr]hqa-nksr]hqa.!y:
***
8+pn:
w!aj`bkn!y
Yes, you can mix variables and strings:
w!bknkejokia[heop!y
8pn_h]oo9w!_u_ha#nks-#nksr]hqa.#nks/#!y:
***
8+pn:
w!aj`bkn!y
In some cases, you might want to refer to the next value of a cycle from outside of a loop.
To do this, just give the w!_u_ha!y tag a name, using ]o like this:
w!_u_ha#nks-##nks.#]onks_khkno!y
From then on, you can insert the current value of the cycle wherever you’d like in your
template:
8pn_h]oo9w!_u_hanks_khkno!y:***8+pn:
8pn_h]oo9w!_u_hanks_khkno!y:***8+pn:
You can use any number of values in a w!_u_ha!y tag, separated by spaces. Values
enclosed in single quotes (#) or double quotes () are treated as string literals, whereas values
without quotes are treated as template variables.
For backward-compatibility, the w!_u_ha!y tag supports the much inferior old syntax
from previous Django versions. You shouldn’t use this in any new projects, but for the sake of
the people who are still using it, here’s what it looks like:
w!_u_hanks-(nks.(nks/!y
In this syntax, each value gets interpreted as a literal string, and there’s no way to specify
variable values. Or literal commas. Or spaces. Did we mention you shouldn’t use this syntax in
any new projects?
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS 431
debug
Outputs a whole load of debugging information, including the current context and imported
modules.
extends
Signals that this template extends a parent template.
This tag can be used in two ways:
ÊUÊw!atpaj`o^]oa*dpih!y (with quotes) uses the literal value ^]oa*dpih as the
name of the parent template to extend.
ÊUÊw!atpaj`or]ne]^ha!y uses the value of r]ne]^ha. If the variable evaluates to a string,
Django will use that string as the name of the parent template. If the variable evaluates
to a Pailh]pa object, Django will use that object as the parent template.
See Chapter 4 for more information on template inheritance.
filter
Filters the contents of the variable through variable filters.
Filters can also be piped through each other, and they can have arguments just as in vari-
able syntax.
For example:
w!behpanbkn_a[ao_]laxhksan!y
Pdeopatpsehh^aDPIH)ao_]la`(]j`sehh]lla]nej]hhhksan_]oa*
w!aj`behpan!y
firstof
Outputs the first variable passed that is not B]hoa. Outputs nothing if all the passed variables
are B]hoa.
For example:
w!benopkbr]n-r]n.r]n/!y
This is equivalent to the following:
w!ebr]n-!y
wwr]n-yy
w!ahoa!yw!ebr]n.!y
wwr]n.yy
w!ahoa!yw!ebr]n/!y
wwr]n/yy
w!aj`eb!yw!aj`eb!yw!aj`eb!y
You can also use a literal string as a fallback value in case all passed variables are B]hoa:
w!benopkbr]n-r]n.r]n/b]hh^]_gr]hqa!y
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS
432
for
Loops over each item in an array. For example, to display a list of athletes provided in
]pdhapa[heop:
8qh:
w!bkn]pdhapaej]pdhapa[heop!y
8he:ww]pdhapa*j]iayy8+he:
w!aj`bkn!y
8+qh:
You can loop over a list in reverse by using w!bknk^fejheopnaranoa`!y.
If you need to loop over a list of lists, you can unpack the values in each sublist into indi-
vidual variables. For example, if your context contains a list of (x,y) coordinates called lkejpo,
you could use the following to output the list of points:
w!bknt(uejlkejpo!y
Pdanaeo]lkejp]pwwtyy(wwuyy
w!aj`bkn!y
This can also be useful if you need to access the items in a dictionary. For example, if your
context contained a dictionary `]p], the following would display the keys and values of the
dictionary:
w!bkngau(r]hqaej`]p]*epaio!y
wwgauyy6wwr]hqayy
w!aj`bkn!y
The bkn loop sets a number of variables available within the loop (see Table E-1).
Table E-1. Variables Available Inside {% for %} Loops
Variable Description
bknhkkl*_kqjpan The current iteration of the loop (1-indexed)
bknhkkl*_kqjpan, The current iteration of the loop (0-indexed)
bknhkkl*nar_kqjpan The number of iterations from the end of the loop (1-indexed)
bknhkkl*nar_kqjpan, The number of iterations from the end of the loop (0-indexed)
bknhkkl*benop Pnqa if this is the first time through the loop
bknhkkl*h]op Pnqa if this is the last time through the loop
bknhkkl*l]najphkkl For nested loops, this is the loop “above” the current one
The bkn tag can take an optional w!ailpu!y clause that will be displayed if the given
array is empty or could not be found:
8qh:
w!bkn]pdhapaej]pdhapa[heop!y
8he:ww]pdhapa*j]iayy8+he:
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS 433
w!ailpu!y
8he:Oknnu(jk]pdhapaejpdeoheop8+he:
w!aj`bkn!y
8qh:
The preceding is equivalent to but shorter, cleaner, and possibly faster than the following:
8qh:
w!eb]pdhapa[heop!y
w!bkn]pdhapaej]pdhapa[heop!y
8he:ww]pdhapa*j]iayy8+he:
w!aj`bkn!y
w!ahoa!y
8he:Oknnu(jk]pdhapaoejpdeoheop*8+he:
w!aj`eb!y
8+qh:
if
The w!eb!y tag evaluates a variable, and if that variable is pnqa (i.e., exists, is not empty, and
is not a false Boolean value), the contents of the block are output:
w!eb]pdhapa[heop!y
Jqi^ankb]pdhapao6ww]pdhapa[heopxhajcpdyy
w!ahoa!y
Jk]pdhapao*
w!aj`eb!y
In the preceding code, if ]pdhapa[heop is not empty, the number of athletes will be dis-
played by the ww]pdhapa[heopxhajcpdyy variable.
As you can see, the eb tag can take an optional w!ahoa!y clause that will be displayed if
the test fails.
eb tags may use ]j`, kn, or jkp to test a number of variables or to negate a given variable:
w!eb]pdhapa[heop]j`_k]_d[heop!y
>kpd]pdhapao]j`_k]_dao]na]r]eh]^ha*
w!aj`eb!y
w!ebjkp]pdhapa[heop!y
Pdana]najk]pdhapao*
w!aj`eb!y
w!eb]pdhapa[heopkn_k]_d[heop!y
Pdana]naokia]pdhapaoknokia_k]_dao*
w!aj`eb!y
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS
434
w!ebjkp]pdhapa[heopkn_k]_d[heop!y
Pdana]najk]pdhapaoknpdana]naokia_k]_dao$KG(ok
snepejcAjcheodpn]joh]pekjokb^kkha]jhkce_okqj`o
opqle`7ep#ojkpkqnb]qhp%*
w!aj`eb!y
w!eb]pdhapa[heop]j`jkp_k]_d[heop!y
Pdana]naokia]pdhapao]j`]^okhqpahujk_k]_dao*
w!aj`eb!y
eb tags don’t allow ]j` and kn clauses within the same tag because the order of logic would
be ambiguous. For example, this is invalid:
w!eb]pdhapa[heop]j`_k]_d[heopkn_daanha]`an[heop!y
If you need to combine ]j` and kn to do advanced logic, just use nested eb tags. For example:
w!eb]pdhapa[heop!y
w!eb_k]_d[heopkn_daanha]`an[heop!y
Sad]ra]pdhapao(]j`aepdan_k]_daokn_daanha]`ano
w!aj`eb!y
w!aj`eb!y
Multiple uses of the same logical operator are fine, as long as you use the same operator.
For example, this is valid:
w!eb]pdhapa[heopkn_k]_d[heopknl]najp[heopknpa]_dan[heop!y
ifchanged
Checks to see whether a value has changed from the last iteration of a loop.
The eb_d]jca` tag is used within a loop. It has two possible uses:
Ê UÊ iVÃÊÌÃÊÜÊÀi`iÀi`ÊVÌiÌÃÊ>}>ÃÌÊÌÃÊ«ÀiÛÕÃÊÃÌ>ÌiÊ>`ÊÞÊ`ë>ÞÃÊÌiÊ
content if it has changed. For example, this displays a list of days, only displaying the
month if it changes:
8d-:=n_derabknwwua]nyy8+d-:
w!bkn`]paej`]uo!y
w!eb_d]jca`!y8d/:ww`]pax`]pa6Byy8+d/:w!aj`eb_d]jca`!y
8]dnab9ww`]pax`]pa6I+`xhksanyy+:ww`]pax`]pa6fyy8+]:
w!aj`bkn!y
Ê UÊ vÊ}ÛiÊ>ÊÛ>À>Li]ÊViVÊÜiÌiÀÊÌ>ÌÊÛ>À>LiÊ>ÃÊV>}i`°ÊÀÊiÝ>«i]ÊÌiÊvÜ}Ê
shows the date every time it changes, but only shows the hour if both the hour and the
date have changed:
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS 435
w!bkn`]paej`]uo!y
w!eb_d]jca``]pa*`]pa!yww`]pa*`]payyw!aj`eb_d]jca`!y
w!eb_d]jca``]pa*dkqn`]pa*`]pa!y
ww`]pa*dkqnyy
w!aj`eb_d]jca`!y
w!aj`bkn!y
The eb_d]jca` tag can also take an optional w!ahoa!y clause that will be displayed if the
value has not changed:
w!bkni]p_deji]p_dao!y
8`eropuha9^]_gcnkqj`)_khkn6
w!eb_d]jca`i]p_d*^]hhkp[e`!y
w!_u_hana`(^hqa!y
w!ahoa!y
cnau
w!aj`eb_d]jca`!y
:wwi]p_dyy8+`er:
w!aj`bkn!y
ifequal
Outputs the contents of the block if the two arguments equal each other.
For example:
w!ebamq]hqoan*e`_kiiajp*qoan[e`!y
***
w!aj`ebamq]h!y
As in the w!eb!y tag, an w!ahoa!y clause is optional.
The arguments can be hard-coded strings, so the following is valid:
w!ebamq]hqoan*qoanj]ia]`ne]j!y
***
w!aj`ebamq]h!y
It is possible to compare an argument only to template variables or strings. You cannot
check for equality with Python objects such as Pnqa or B]hoa. If you need to test whether some-
thing is pnqa or b]hoa, use the eb tag instead.
ifnotequal
Just like ebamq]h, except that it tests that the two arguments are not equal.
include
Loads a template and renders it with the current context. This is a way of “including” other
templates within a template.
The template name can either be a variable or a hard-coded (quoted) string in either
single or double quotes.
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS
436
This example includes the contents of the template bkk+^]n*dpih:
w!ej_hq`abkk+^]n*dpih!y
This example includes the contents of the template whose name is contained in the vari-
able pailh]pa[j]ia:
w!ej_hq`apailh]pa[j]ia!y
An included template is rendered with the context of the template that includes it. This
example produces the output Dahhk(Fkdj:
Ê UÊ ÌiÝÌ\ÊÛ>À>LiÊlanokj is set to fkdj.
Ê UÊ /i«>Ìi\
w!ej_hq`aj]ia[ojellap*dpih!y
Ê UÊ /iÊj]ia[ojellap*dpih template:
Dahhk(wwlanokjyy
See also: w!ooe!y.
load
Loads a custom template tag set. See Chapter 9 for more information on custom template
libraries.
now
Displays the date, formatted according to the given string.
Uses the same format as PHP’s `]pa$% function (dppl6++ldl*jap+`]pa) with some custom
extensions.
Table E-2 shows the available format strings.
Table E-2. Available Date Format Strings
Format Character Description Example Output
a#]*i*# or #l*i*# (Note that this is slightly differ-
ent from PHP’s output because it includes periods
to match Associated Press style.)
#]*i*#
A#=I# or #LI#.#=I#
b Month, textual, three letters, lowercase. #f]j#
B Not implemented.
d Day of the month, two digits with leading zeros. #,-# to #/-#
D Day of the week, textual, three letters. #Bne#
f Time, in 12-hour hours and minutes, with minutes
left off if they’re zero. Proprietary extension.
#-#, #-6/,#
F Month, textual, long. #F]jq]nu#
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS 437
Format Character Description Example Output
g Hour, 12-hour format without leading zeros. #-# to #-.#
G Hour, 24-hour format without leading zeros. #,# to #./#
h Hour, 12-hour format. #,-# to #-.#
H Hour, 24-hour format. #,,# to #./#
i Minutes. #,,# to #15#
I Not implemented.
j Day of the month without leading zeros. #-# to #/-#
l Day of the week, textual, long. #Bne`]u#
L Boolean for whether it’s a leap year. Pnqa or B]hoa
m Month, two digits with leading zeros. #,-# to #-.#
M Month, textual, three letters. #F]j#
n Month without leading zeros. #-# to #-.#
N Month abbreviation in Associated Press style.
Proprietary extension.
#F]j*#, #Ba^*#,
#I]n_d#, #I]u#
O Difference to Greenwich time in hours. #',.,,#
P Time, in 12-hour hours and minutes, and
‘a.m.’/’p.m.’, with minutes left off if they’re zero
and the special-case strings #ie`jecdp# and
#jkkj# if appropriate. Proprietary extension.
#-]*i*#, #-6/,l*i*#,
#ie`jecdp#, #jkkj#,
#-.6/,l*i*#
r RFC 2822 formatted date. #Pdq(.-@a_.,,,
-26,-6,3',.,,#
s Seconds, two digits with leading zeros. #,,# to #15#
S English ordinal suffix for day of the month, two
characters.
#op#, #j`#, #n`#, or #pd#
t Number of days in the given month. .4 to /-
T Time zone of this machine. #AOP#, #I@P#
U Not implemented.
w Day of the week, digits without leading zeros. #,# (Sunday) to #2#
(Saturday)
W ISO-8601 week number of year, with weeks starting
on Monday.
-, 1/
y Year, two digits. #55#
Y Year, four digits. #-555#
z Day of the year. , to /21
Z Time zone offset in seconds. The offset for time
zones west of UTC is always negative, and for those
east of UTC is always positive.
)0/.,, to 0/.,,
For example:
Epeow!jksfOBUD6e!y
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS
438
Note that you can backslash-escape a format string if you want to use the “raw” value. In
this example, “f” is backslash-escaped because otherwise “f” is a format string that displays the
time. The “o” doesn’t need to be escaped, because it’s not a format character:
Epeopdaw!jksfOkXbB!y
This would display as “It is the 4th of September.”
regroup
Regroups a list of like objects by a common attribute.
This complex tag is best illustrated by use of an example: say that laklha is a list of people
represented by dictionaries with benop[j]ia, h]op[j]ia, and caj`an keys:
laklha9W
w#benop[j]ia#6#Caknca#(#h]op[j]ia#6#>qod#(#caj`an#6#I]ha#y(
w#benop[j]ia#6#>ehh#(#h]op[j]ia#6#?hejpkj#(#caj`an#6#I]ha#y(
w#benop[j]ia#6#I]nc]nap#(#h]op[j]ia#6#Pd]p_dan#(#caj`an#6#Bai]ha#y(
w#benop[j]ia#6#?kj`khaavv]#(#h]op[j]ia#6#Ne_a#(#caj`an#6#Bai]ha#y(
w#benop[j]ia#6#L]p#(#h]op[j]ia#6#Oiepd#(#caj`an#6#Qjgjksj#y(
Y
And you want to display a hierarchical list that is ordered by gender, like this:
ÊUÊMale:
Ê UÊiÀ}iÊÕÃ
Ê UÊÊÌ
ÊUÊFemale:
Ê UÊ>À}>ÀiÌÊ/>ÌViÀ
Ê UÊ`iiââ>Ê,Vi
ÊUÊUnknown:
Ê UÊ*>ÌÊ-Ì
You can use the w!nacnkql!y tag to group the list of people by gender. The following
snippet of template code would accomplish it:
w!nacnkqllaklha^ucaj`an]ocaj`an[heop!y
8qh:
w!bkncaj`anejcaj`an[heop!y
8he:wwcaj`an*cnkqlanyy
8qh:
w!bknepaiejcaj`an*heop!y
8he:wwepai*benop[j]iayywwepai*h]op[j]iayy8+he:
w!aj`bkn!y
8+qh:
8+he:
w!aj`bkn!y
8+qh:
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS 439
Let’s walk through this example. w!nacnkql!y takes three arguments: the list you want
to regroup, the attribute to group by, and the name of the resulting list. Here, we’re regrouping
the laklha list by the caj`an attribute and calling the result caj`an[heop.
w!nacnkql!y produces a list (in this case, caj`an[heop) of group objects. Each group
object has two attributes:
ÊUÊcnkqlan: The item that was grouped by (e.g., the string I]haor Bai]ha)
ÊUÊheop: A list of all items in this group (e.g., a list of all people with caj`an9#I]ha#)
Note that w!nacnkql!y does not order its input! Our example relies on the fact that the
laklha list was ordered by caj`an in the first place. If the laklha list did not order its members
by caj`an, the regrouping would naively display more than one group for a single gender. For
example, say the laklha list was set to this (note that the males are not grouped together):
laklha9W
w#benop[j]ia#6#>ehh#(#h]op[j]ia#6#?hejpkj#(#caj`an#6#I]ha#y(
w#benop[j]ia#6#L]p#(#h]op[j]ia#6#Oiepd#(#caj`an#6#Qjgjksj#y(
w#benop[j]ia#6#I]nc]nap#(#h]op[j]ia#6#Pd]p_dan#(#caj`an#6#Bai]ha#y(
w#benop[j]ia#6#Caknca#(#h]op[j]ia#6#>qod#(#caj`an#6#I]ha#y(
w#benop[j]ia#6#?kj`khaavv]#(#h]op[j]ia#6#Ne_a#(#caj`an#6#Bai]ha#y(
Y
With this input for laklha, the previous example w!nacnkql!y template code would
result in the following output:
ÊUÊMale:
Ê UÊÊÌ
ÊUÊUnknown:
Ê UÊ*>ÌÊ-Ì
ÊUÊFemale:
Ê UÊ>À}>ÀiÌÊ/>ÌViÀ
ÊUÊMale:
Ê UÊiÀ}iÊÕÃ
ÊUÊFemale:
Ê UÊ`iiââ>Ê,Vi
The easiest solution to this gotcha is to make sure in your view code that the data is
ordered according to how you want to display it.
Another solution is to sort the data in the template using the `e_poknp filter if your data is
in a list of dictionaries:
w!nacnkqllaklhax`e_poknp6caj`an^ucaj`an]ocaj`an[heop!y
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS
440
spaceless
Removes whitespace between HTML tags (this includes tab characters and newlines).
For example:
w!ol]_ahaoo!y
8l:
8]dnab9bkk+:Bkk8+]:
8+l:
w!aj`ol]_ahaoo!y
This example would return this HTML:
8l:8]dnab9bkk+:Bkk8+]:8+l:
Only space between tags is removed; not space between tags and text. In this example, the
space around Dahhk won’t be stripped:
w!ol]_ahaoo!y
8opnkjc:
Dahhk
8+opnkjc:
w!aj`ol]_ahaoo!y
ssi
Outputs the contents of a given file into the page.
Like a simple ej_hq`a tag, w!ooe!y includes the contents of another file that must be
specified using an absolute path in the current page:
w!ooe+dkia+dpih+hfsknh`*_ki+ej_hq`ao+necdp[cajane_*dpih!y
If the optional “parsed” parameter is given, the contents of the included file are evaluated
as template code within the current context:
w!ooe+dkia+dpih+hfsknh`*_ki+ej_hq`ao+necdp[cajane_*dpihl]noa`!y
Note that if you use w!ooe!y, you’ll need to define =HHKSA@[EJ?HQ@A[NKKPO in your
Django settings as a security measure.
See also w!ej_hq`a!y.
templatetag
Outputs one of the syntax characters used to compose template tags.
Because the template system has no concept of “escaping,” to display one of the bits used
in template tags, you must use the w!pailh]pap]c!y tag.
See Table E-3 for the available arguments.
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS 441
Table E-3. Available Arguments for templatetag Filter
Argument Output
klaj^hk_g w!
_hkoa^hk_g !y
klajr]ne]^ha ww
_hkoar]ne]^ha yy
klaj^n]_a w
_hkoa^n]_a y
klaj_kiiajp w
_hkoa_kiiajp y
url
Returns an absolute URL (i.e., a URL without the domain name) matching a given view func-
tion and optional parameters. This is a way to output links without violating the DRY principle
by having to hard-code URLs in your templates:
w!qnhl]pd*pk*okia[reas]nc-(]nc.(j]ia-9r]hqa-!y
The first argument is a path to a view function in the format l]_g]ca*l]_g]ca*ik`qha*
bqj_pekj. Additional arguments are optional and should be comma-separated values that will
be used as positional and keyword arguments in the URL. All arguments required by the URL-
conf should be present.
For example, suppose that you have a view, ]ll[reaso*_heajp, whose URLconf takes a cli-
ent ID (here, _heajp$% is a method inside the views file ]ll[reaso*lu). The URLconf line might
look like this:
$#Z_heajp+$X`'%+ #(#]ll[reaso*_heajp#%
If this app’s URLconf is included into the project’s URLconf under a path such as this:
$#Z_heajpo+#(ej_hq`a$#lnkfa_p[j]ia*]ll[j]ia*qnho#%%
you can create a link to this view like this in a template:
w!qnh]ll[reaso*_heajp_heajp*e`!y
The template tag will output the string +_heajpo+_heajp+-./+.
widthratio
For creating bar charts and such, this tag calculates the ratio of a given value to a maximum
value, and then applies that ratio to a constant.
For example:
8eicon_9^]n*cebdaecdp9-,se`pd9w!se`pdn]pekpdeo[r]hqai]t[r]hqa-,,!y+:
If pdeo[r]hqa is -31 and i]t[r]hqa is .,,, the image in the preceding example will be 88
pixels wide (because 175 / 200 = .875, .875 * 100 = 87.5, which is rounded up to 88).
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS
442
with
Caches a complex variable under a simpler name. This is useful when accessing an “expensive”
method (e.g., one that hits the database multiple times).
For example:
w!sepd^qoejaoo*ailhkuaao*_kqjp]opkp]h!y
wwpkp]hyyailhkuaawwpkp]hxlhqn]hevayy
w!aj`sepd!y
The populated variable (in the example above, pkp]h) is only available between the
w!sepd!y and w!aj`sepd!y tags.
Built-in Filter Reference
add
Adds the argument to the value.
For example:
wwr]hqax]``6.yy
If r]hqa is 0, the output will be 2.
addslashes
Adds slashes before quotes. Useful for escaping strings in CSV, for example.
capfirst
Capitalizes the first character of the value.
center
Centers the value in a field of a given width.
cut
Removes all values of ]nc from the given string. For example:
wwr]hqax_qp6yy
If r]hqa is Opnejcsepdol]_ao, the output will be Opnejcsepdol]_ao.
date
Formats a date according to the given format (same as the w!jks!y tag). For example:
wwr]hqax`]pa6@`IUyy
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS 443
If r]hqa is a `]papeia object (e.g., the result of `]papeia*`]papeia*jks$%), the output will
be the string #Sa`,5F]j.,,4#.
When used without a format string, as follows, the formatting string defined in the @=PA[
BKNI=P setting will be used:
wwr]hqax`]payy
default
If value evaluates to B]hoa, use given default. Otherwise, use the value.
For example:
wwr]hqax`ab]qhp6jkpdejcyy
If r]hqa is  (the empty string), the output will be jkpdejc.
default_if_none
If (and only if) r]hqa is Jkja, use the given default. Otherwise, use the value.
Note that if an empty string is given, the default value will not be used. Use the `ab]qhp
filter if you want to fallback for empty strings.
For example:
wwr]hqax`ab]qhp[eb[jkja6jkpdejcyy
If r]hqa is Jkja, the output will be the string jkpdejc.
dictsort
Takes a list of dictionaries and returns that list sorted by the key given in the argument.
For example:
wwr]hqax`e_poknp6j]iayy
If r]hqa is:
W
w#j]ia#6#va`#(#]ca#6-5y(
w#j]ia#6#]iu#(#]ca#6..y(
w#j]ia#6#fka#(#]ca#6/-y(
Y
then the output would be:
W
w#j]ia#6#]iu#(#]ca#6..y(
w#j]ia#6#fka#(#]ca#6/-y(
w#j]ia#6#va`#(#]ca#6-5y(
Y
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS
444
dictsortreversed
Takes a list of dictionaries and returns that list sorted in reverse order by the key given in the
argument. This works exactly the same as the previous filter, but the returned value will be in
reverse order.
divisibleby
Returns Pnqa if the value is divisible by the argument.
For example:
wwr]hqax`ereoe^ha^u6/yy
If r]hqa is .-, the output would be Pnqa.
escape
Escapes a string’s HTML. Specifically, it makes these replacements:
ÊUÊ8 is converted to "hp7
ÊUÊ: is converted to "cp7
ÊUÊ# (single quote) is converted to "/57
ÊUÊ (double quote) is converted to "mqkp7
ÊUÊ" is converted to "]il7
The escaping is applied only when the string is output, so it does not matter where in a
chained sequence of filters you put ao_]la: it will always be applied as if it were the last filter.
If you want escaping to be applied immediately, use the bkn_a[ao_]la filter.
Applying ao_]la to a variable that would normally have autoescaping applied to the result
will result in only one round of escaping being done. So it is safe to use this function even
in autoescaping environments. If you want multiple escaping passes to be applied, use the
bkn_a[ao_]la filter.
escapejs
Escapes characters for use in JavaScript strings. This does not make the string safe for use in
HTML, but does protect you from syntax errors when using templates to generate JavaScript/
JSON.
filesizeformat
Formats the value like a ‘human-readable’ file size (i.e., #-/G>#, #0*-I>#, #-,.^upao#, etc).
For example:
wwr]hqaxbehaoevabkni]pyy
If r]hqa is 123456789, the output would be --3*3I>.
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS 445
first
Returns the first item in a list.
For example:
wwr]hqaxbenopyy
If r]hqa is the list W#]#(#^#(#_#Y, the output will be #]#.
fix_ampersands
Replaces ampersands with "]il7 entities.
For example:
wwr]hqaxbet[]ilano]j`oyy
If r]hqa is Pki"Fannu, the output will be Pki"]il7Fannu.
floatformat
When used without an argument, rounds a floating-point number to one decimal place (but
only if there’s a decimal part to be displayed). See Table E-4.
Table E-4. Example Output of floatformat Tag
R]hqa Template Output
/0*././0 wwr]hqaxbhk]pbkni]pyy /0*.
/0*,,,,, wwr]hqaxbhk]pbkni]pyy /0
/0*.2,,, wwr]hqaxbhk]pbkni]pyy /0*/
If used with a numeric integer argument, bhk]pbkni]p rounds a number to that many
decimal places. See Table E-5.
Table E-5. More Example Output of floatformat Tag
R]hqa Template Output
/0*././0 wwr]hqaxbhk]pbkni]p6/yy /0*./.
/0*,,,,, wwr]hqaxbhk]pbkni]p6/yy /0*,,,
/0*.2,,, wwr]hqaxbhk]pbkni]p6/yy /0*.2,
If the argument passed to bhk]pbkni]p is negative, it will round a number to that many
decimal places, but only if there’s a decimal part to be displayed. See Table E-6.
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS
446
Table E-6. Even More Example Output of floatformat Tag
R]hqa Template Output
/0*././0 wwr]hqaxbhk]pbkni]p6)/yy /0*./.
/0*,,,,, wwr]hqaxbhk]pbkni]p6)/yy /0
/0*.2,,, wwr]hqaxbhk]pbkni]p6)/yy /0*.2,
Using bhk]pbkni]p with no argument is equivalent to using bhk]pbkni]p with an argument
of )-.
force_escape
Applies HTML escaping to a string (see the ao_]la filter for details). This filter is applied
immediately and returns a new escaped string. This is useful in the rare cases where you need
multiple escaping or want to apply other filters to the escaped results. Normally, you want to
use the ao_]la filter.
get_digit
Given a whole number, returns the requested digit, where 1 is the rightmost digit, 2 is the
second digit, and so on. Returns the original value for invalid input (if the input or argument is
not an integer or if the argument is less than 1). Otherwise, output is always an integer.
For example:
wwr]hqaxcap[`ecep6.yy
If r]hqa is -./012345, the output will be 4.
iriencode
Converts an Internationalized Resource Identifier (IRI) to a string that is suitable for including
in a URL. This is necessary if you’re trying to use strings containing non-ASCII characters in a
URL.
It’s safe to use this filter on a string that has already gone through the qnhaj_k`a filter.
join
Joins a list with a string such as Python’s opn*fkej$heop%.
For example:
wwr]hqaxfkej6++yy
If r]hqa is the list W#]#(#^#(#_#Y, the output will be the string ]++^++_.
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS 447
last
Returns the last item in a list.
For example:
wwr]hqaxh]opyy
If r]hqa is the list W#]#(#^#(#_#(#`#Y, the output will be the string `.
length
Returns the length of the value (this works for both strings and lists).
For example:
wwr]hqaxhajcpdyy
If r]hqa is W#]#(#^#(#_#(#`#Y, the output will be 0.
length_is
Returns Pnqa if the value’s length is the argument, or B]hoa otherwise.
For example:
wwr]hqaxhajcpd[eo60yy
If r]hqa is W#]#(#^#(#_#(#`#Y, the output will be Pnqa.
linebreaks
Replaces line breaks in plain text with appropriate HTML; a single newline becomes an HTML
line break (8^n+:) and a new line followed by a blank line becomes a paragraph break (8+l:).
For example:
wwr]hqaxheja^na]goyy
If r]hqa is FkahXjeo]ohqc, the output will be 8l:Fkah8^n+:eo]ohqc8+l:.
linebreaksbr
Converts all newlines in a piece of plain text to HTML line breaks (8^n+:).
linenumbers
Displays text with line numbers.
ljust
Left-aligns the value in a field of a given width.
Argument: field size
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS
448
lower
Converts a string into all lowercase.
For example:
wwr]hqaxhksanyy
If r]hqa is OpehhI=@=pUkgk, the output will be opehhi]`]pukgk.
make_list
Returns the value turned into a list. For an integer, it’s a list of digits. For a string, it’s a list of
characters.
For example:
wwr]hqaxi]ga[heopyy
If r]hqa is the string Fkah, the output would be the list Wq#F#(q#k#(q#a#(q#h#Y. If
r]hqa is -./, the output will be the list W-(.(/Y.
phone2numeric
Converts a phone number (possibly containing letters) to its numerical equivalent. For exam-
ple, #4,,)?KHHA?P# will be converted to #4,,).211/.4#.
The input doesn’t have to be a valid phone number. This will happily convert any string.
pluralize
Returns a plural suffix if the value is not -. By default, this suffix is #o#.
For example:
Ukqd]rawwjqi[iaoo]caoyyiaoo]cawwjqi[iaoo]caoxlhqn]hevayy*
For words that require a suffix other than #o#, you can provide an alternate suffix as a
parameter to the filter.
For example:
Ukqd]rawwjqi[s]hnqoaoyys]hnqowwjqi[s]hnqoxlhqn]heva6aoyy*
For words that don’t pluralize by simple suffix, you can specify both a singular and plural
suffix, separated by a comma.
For example:
Ukqd]rawwjqi[_danneaoyy_dannwwjqi[_danneaoxlhqn]heva6u(eaoyy*
pprint
A wrapper around the Python standard library’s llnejp*llnejp function for debugging, really.
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS 449
random
Returns a random item from the given list.
For example:
wwr]hqaxn]j`kiyy
If r]hqa is the list W#]#(#^#(#_#(#`#Y, the output could be ^.
removetags
Removes a space-separated list of [X]HTML tags from the output.
For example:
wwr]hqaxnaikrap]co6^ol]jxo]bayy
If r]hqa is 8^:Fkah8+^:8^qppkj:eo8+^qppkj:]8ol]j:ohqc8+ol]j: the output will be
Fkah8^qppkj:eo8+^qppkj:]ohqc.
rjust
Right-aligns the value in a field of a given width.
Argument: field size
safe
Marks a string as not requiring further HTML escaping prior to output. When autoescaping is
off, this filter has no effect.
safeseq
Applies the o]ba filter to each element of a sequence. Useful in conjunction with other filters
that operate on sequences, such as fkej. For example:
wwokia[heopxo]baoamxfkej6(yy
You couldn’t use the o]ba filter directly in this case because it would first convert the vari-
able into a string instead of working with the individual elements of the sequence.
slice
Returns a slice of the list.
Uses the same syntax as Python’s list slicing. See dppl6++`eraejpklupdkj*knc+j]pera[
`]p][pulao+heopo*dpihk`^_dahlan*heop*ohe_a for an introduction.
For example:
wwokia[heopxohe_a66.yy
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS
450
slugify
Converts to lowercase, removes nonword characters (only alphanumerics and underscores are
kept), and converts spaces to hyphens. Also strips leading and trailing whitespace.
For example:
wwr]hqaxohqcebuyy
If r]hqa is Fkaheo]ohqc, the output will be fkah)eo)])ohqc.
stringformat
Formats the variable according to the argument, a string-formatting specifier. This specifier
uses Python string-formatting syntax, with the exception that the leading ! is dropped.
See dppl6++`k_o*lupdkj*knc+he^n]nu+op`pulao*dpihopnejc)bkni]ppejc)klan]pekjo for
documentation of Python string formatting.
For example:
wwr]hqaxopnejcbkni]p6oyy
If r]hqa is Fkaheo]ohqc, the output will be Fkaheo]ohqc.
striptags
Strips all [X]HTML tags.
For example:
wwr]hqaxopnelp]coyy
If r]hqa is 8^:Fkah8+^:8^qppkj:eo8+^qppkj:]8ol]j:ohqc8+ol]j:, the output will be
Fkaheo]ohqc.
time
Formats a time according to the given format (same as the jks tag). The peia filter will accept
parameters in the format string that relate to the time of day, not the date (for obvious rea-
sons). If you need to format a date, use the `]pa filter.
For example:
wwr]hqaxpeia6D6eyy
If r]hqa is equivalent to `]papeia*`]papeia*jks$%, the output will be the string ,-6./.
When used without a format string, the format string defined in the PEIA[BKNI=P setting
will be used:
wwr]hqaxpeiayy
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS 451
timesince
Formats a date as the time since that date (e.g., “4 days, 6 hours”).
Takes an optional argument that is a variable containing the date to use as the compari-
son point (without the argument, the comparison point is now). For example, if ^hkc[`]pa is
a date instance representing midnight on 1 June 2006, and _kiiajp[`]pa is a date instance for
08:00 on 1 June 2006, then ww^hkc[`]paxpeiaoej_a6_kiiajp[`]payy would return “4dkqno”.
Comparing offset-naive and offset-aware datetimes will return an empty string.
Minutes is the smallest unit used, and ,iejqpao will be returned for any date that is in
the future relative to the comparison point.
timeuntil
Similar to peiaoej_a, except that it measures the time from now until the given date or date-
time. For example, if today is 1 June 2006, and _kjbanaj_a[`]pa is a date instance holding 29
June 2006, then ww_kjbanaj_a[`]paxpeiaqjpehyy will return 0saago.
Takes an optional argument that is a variable containing the date to use as the
comparison point (instead of now). If bnki[`]pa contains 22 June 2006, then ww_kjbanaj_a[
`]paxpeiaqjpeh6bnki[`]payy will return -saag.
Comparing offset-naive and offset-aware datetimes will return an empty string.
Minutes is the smallest unit used, and ,iejqpao will be returned for any date that is in
the past relative to the comparison point.
title
Converts a string into titlecase.
truncatewords
Truncates a string after a certain number of words.
Argument: Number of words to truncate after.
For example:
wwr]hqaxpnqj_]paskn`o6.yy
If r]hqa is Fkaheo]ohqc, the output will be Fkaheo***.
truncatewords_html
Similar to pnqj_]paskn`o, except that it is aware of HTML tags. Any tags that are opened in the
string and not closed before the truncation point are closed immediately after the truncation.
This is less efficient than pnqj_]paskn`o, so should be used only when it is being passed
HTML text.
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS
452
unordered_list
Recursively takes a self-nested list and returns an HTML unordered list without opening and
closing 8qh: tags.
The list is assumed to be in the proper format. For example, if r]n contains W#Op]pao#(
W#G]jo]o#(W#H]snaj_a#(#Pklag]#Y(#Ehhejkeo#YY, then wwr]nxqjkn`ana`[heopyy would
return the following:
8he:Op]pao
8qh:
8he:G]jo]o
8qh:
8he:H]snaj_a8+he:
8he:Pklag]8+he:
8+qh:
8+he:
8he:Ehhejkeo8+he:
8+qh:
8+he:
upper
Converts a string into all uppercase.
For example:
wwr]hqaxqllanyy
If r]hqa is Fkaheo]ohqc, the output will be FKAHEO=OHQC.
urlencode
Escapes a value for use in a URL.
urlize
Converts URLs in plain text into clickable links.
Note that if qnheva is applied to text that already contains HTML markup, things won’t
work as expected. Apply this filter only to plain text.
For example:
wwr]hqaxqnhevayy
If r]hqa is ?da_gkqpsss*`f]jcklnkfa_p*_ki, the output will be ?da_gkqp8]
dnab9dppl6++sss*`f]jcklnkfa_p*_ki:sss*`f]jcklnkfa_p*_ki8+]:.
APPENDIX E N BUILT-IN TEMPLATE TAGS AND FILTERS 453
urlizetrunc
Converts URLs into clickable links, truncating URLs longer than the given character limit.
As with qnheva, this filter should be applied only to plain text.
Argument: Length to truncate URLs to.
For example:
wwr]hqaxqnhevapnqj_6-1yy
If r]hqa is ?da_gkqpsss*`f]jcklnkfa_p*_ki, the output would be #?da_gkqp8]
dnab9dppl6++sss*`f]jcklnkfa_p*_ki:sss*`f]jckln***8+]:#.
wordcount
Returns the number of words.
wordwrap
Wraps words at a specified line length.
Argument: number of characters at which to wrap the text.
For example:
wwr]hqaxskn`sn]l61yy
If r]hqa is Fkaheo]ohqc, the output would be the following:
Fkah
eo]
ohqc
yesno
Given a string mapping values for Pnqa, B]hoa, and (optionally) Jkja returns one of those
strings according to the value (see Table E-7).
Table E-7. Examples of the yesno Filter
Value Argument Output
Pnqa ua]d(jk(i]u^a ua]d
B]hoa ua]d(jk(i]u^a jk
Jkja ua]d(jk(i]u^a i]u^a
Jkja ua]d(jk jk (converts Jkja to B]hoa if no mapping for Jkja is given)
APPENDIX F
The django-admin Utility
`f]jck)]`iej*lu is Django’s command-line utility for administrative tasks. This appendix
explains its many powers.
Usually you’ll access `f]jck)]`iej*lu through a project’s i]j]ca*lu wrapper. i]j]ca*lu
is created automatically in each Django project and is a thin wrapper around `f]jck)]`iej*lu.
It takes care of two things for you before delegating to `f]jck)]`iej*lu:
Ê UÊ ÌÊ«ÕÌÃÊÞÕÀÊ«ÀiV̽ÃÊ«>V>}iÊÊouo*l]pd.
Ê UÊ ÌÊÃiÌÃÊÌiÊ@F=JCK[OAPPEJCO[IK@QHA environment variable so that it points to your
project’s oappejco*lu file.
The `f]jck)]`iej*lu script should be on your system path if you installed Django via its
oapql*lu utility. If it’s not on your path, you can find it in oepa)l]_g]cao+`f]jck+^ej within
your Python installation. Consider symlinking it from some place on your path, such as +qon+
hk_]h+^ej.
Windows users, who do not have symlinking functionality available, can copy `f]jck)]`iej*
lu to a location on their existing path or edit the L=PD settings (under Settings ¢ Control Panel
¢ System ¢ Advanced ¢ Environment) to point to its installed location.
Generally, when working on a single Django project it’s easier to use i]j]ca*lu. If you
need to switch between multiple Django settings files, use `f]jck)]`iej*lu with @F=JCK[
OAPPEJCO[IK@QHA or use the ))oappejco command-line option.
The command-line examples throughout this appendix use `f]jck)]`iej*lu to be consis-
tent, but any example can use i]j]ca*lu just as well.
Usage
Here’s how to use `f]jck)]`iej*lu:
`f]jck)]`iej*lu8oq^_kii]j`:WklpekjoY
i]j]ca*lu8oq^_kii]j`:WklpekjoY
455
APPENDIX F N THE DJANGO-ADMIN UTILITY
456
oq^_kii]j` should be one of the subcommands listed in the “Available Subcommands”
section of this appendix. klpekjo, which is optional, should be zero or more of the options
available for the given subcommand.
Getting Runtime Help
Run `f]jck)]`iej*ludahl to display a list of all available subcommands. Run `f]jck)]`iej*lu
dahl8oq^_kii]j`: to display a description of the given subcommand and a list of its available
options.
App Names
Many subcommands take a list of app names. An app name is the base name of the package
containing your models. For example, if your EJOP=HHA@[=LLO contains the string #iuoepa*^hkc#,
the app name is ^hkc.
Determining the Version
Run `f]jck)]`iej*lu))ranoekj to display the current Django version.
Here are some examples of output:
-*-
-*,
,*52
,*53)lna)ORJ)2,25
Displaying Debug Output
Use ))ran^koepu to specify the amount of notification and debug information that `f]jck)]`iej*
lu should print to the console.
Available Subcommands
cleanup
This can be run as a cron job, or directly to clean out old data from the database (only expired
sessions currently).
compilemessages
The _kilehaiaoo]cao subcommand compiles *lk files created with i]gaiaoo]cao to *ik files for
use with the built-in cappatp support. See Chapter 19.
APPENDIX F N THE DJANGO-ADMIN UTILITY 457
--locale
Use the ))hk_]ha or )h option to specify the locale to process. If this option is not provided, all
locales are processed.
Here is a usage example:
`f]jck)]`iej*lu_kilehaiaoo]cao))hk_]ha9^n[LP
createcachetable
This subcommand creates a cache table with a given name for use with the database-cache
back-end. See Chapter 15.
Example usage:
`f]jck)]`iej*lu_na]pa_]_dap]^haiu[_]_da[p]^ha
createsuperuser
This creates a superuser account (a user who has all permissions). This is useful if you need to
create an initial superuser account but did not do so during ouj_`^, or if you need to generate
superuser accounts programmatically for your site(s).
When run interactively, this command will prompt for a password for the new superuser
account. When run non-interactively, no password will be set, and the superuser account will
not be able to log in until a password has been set for it manually.
The username and e-mail address for the new account can be supplied by using the
))qoanj]ia and ))ai]eh arguments on the command line. If either of these is not supplied,
_na]paoqlanqoan will prompt for it when running interactively.
This command is available only if Django’s authentication system (`f]jck*_kjpne^*]qpd)
is in EJOP=HHA@[=LLO. See Chapter 14.
dbshell
`^odahh runs the command-line client for the database engine specified in your @=P=>=OA[
AJCEJA setting, with the connection parameters specified in your @=P=>=OA[QOAN, @=P=>=OA[
L=OOSKN@, and other such settings:
Ê UÊ ÀÊ*ÃÌ}Ài-+]ÊÌÃÊÀÕÃÊÌiÊlomh command-line client.
Ê UÊ ÀÊÞ-+]ÊÌÃÊÀÕÃÊÌiÊiuomh command-line client.
Ê UÊ ÀÊ-+Ìi]ÊÌÃÊÀÕÃÊÌiÊomhepa/ command-line client.
This command assumes the programs are on your L=PD so that a simple call to the pro-
gram name (lomh, iuomh, omhepa/) will find the program in the right place. There’s no way to
specify the location of the program manually.
APPENDIX F N THE DJANGO-ADMIN UTILITY
458
diffsettings
Use this to display differences between the current settings file and Django’s default settings.
Settings that don’t appear in the defaults are followed by . For example, the default
settings don’t define NKKP[QNH?KJB, so NKKP[QNH?KJB is followed by  in the output of
`ebboappejco.
Note that Django’s default settings live in `f]jck+_kjb+chk^]h[oappejco*lu, in case you’re
ever curious to see the full list of defaults.
dumpdata
This outputs to standard output all data in the database associated with the named application(s).
If no application name is provided, all installed applications will be dumped. The output of
`qil`]p] can be used as input for hk]``]p].
Note that `qil`]p] uses the default manager on the model for selecting the records to
dump. If you’re using a custom manager as the default manager and it filters some of the avail-
able records, not all of the objects will be dumped.
Here is a usage example:
`f]jck)]`iej*lu`qil`]p]^kkgo
Use the ))at_hq`a option to exclude a specific application from the applications whose
contents are output. For example, to specifically exclude the auth application from the output,
you would call:
`f]jck)]`iej*lu`qil`]p]))at_hq`a9]qpd
If you want to exclude multiple applications, use multiple ))at_hq`a directives:
`f]jck)]`iej*lu`qil`]p]))at_hq`a9]qpd))at_hq`a9_kjpajppulao
By default, `qil`]p] will format its output in JSON, but you can use the ))bkni]p option to
specify another format. Currently supported formats are listed in the Django documentation.
By default, `qil`]p] will output all data on a single line. This isn’t easy for humans to read, so
you can use the ))ej`ajp option to pretty-print the output with a number of indentation spaces.
In addition to specifying application names, you can provide a list of individual models,
in the form of ]llj]ia*Ik`ah. If you specify a model name to `qil`]p], the dumped output will
be restricted to that model, rather than the entire application. You can also mix application
names and model names.
flush
bhqod returns the database to the state it was in immediately after ouj_`^ was executed. This
means that all data will be removed from the database, any post-synchronization handlers will
be re-executed, and the ejepe]h[`]p] fixture will be reinstalled.
Use the ))jkejlqp option to suppress all user prompting, such as “Are you sure?” con-
firmation messages. This is useful if `f]jck)]`iej*lu is being executed as an unattended,
automated script.
APPENDIX F N THE DJANGO-ADMIN UTILITY 459
inspectdb
This subcommand introspects the database tables in the database pointed to by the @=P=>=OA[
J=IA setting and outputs a Django model module (a ik`aho*lu file) to standard output.
Use this if you have a legacy database with which you’d like to use Django. The script will
inspect the database and create a model for each table within it.
As you might expect, the created models will have an attribute for every field in the table.
Note that ejola_p`^ has a few special cases in its field-name output:
Ê UÊ vÊejola_p`^ cannot map a column’s type to a model field type, it’ll use PatpBeah` and
insert the Python comment #Pdeobeah`pulaeo]cqaoo*# next to the field in the
generated model.
Ê UÊ vÊÌiÊ`>Ì>L>ÃiÊVÕÊ>iÊÃÊ>Ê*ÞÌÊÀiÃiÀÛi`ÊÜÀ`ÊÃÕVÊ>ÃÊ#l]oo#, #_h]oo#, or
#bkn#), ejola_p`^ will append #[beah`# to the attribute name. For example, if a table
has a column #bkn#, the generated model will have a field #bkn[beah`#, with the `^[
_khqij attribute set to #bkn#. ejola_p`^ will insert the Python comment #Beah`naj]ia`
^a_]qoaeps]o]Lupdkjnaoanra`skn`*# next to the field.
This feature is meant as a shortcut, not as definitive model generation. After you run it,
you’ll want to look over the generated models yourself to make customizations. In particular,
you’ll need to rearrange models’ order so that models that refer to other models are ordered
properly.
*À>ÀÞÊiÞÃÊ>ÀiÊ>ÕÌ>ÌV>ÞÊÌÀëiVÌi`ÊvÀÊ*ÃÌ}Ài-+]ÊÞ-+]Ê>`Ê-+Ìi]ÊÊÜVÊ
case Django puts in the lnei]nu[gau9Pnqa where needed.
ejola_p`^ÊÜÀÃÊÜÌÊ*ÃÌ}Ài-+]ÊÞ-+]Ê>`Ê-+Ìi°ÊÀi}iÞÊ`iÌiVÌÊÜÀÃÊÞÊ
Ê*ÃÌ}Ài-+Ê>`ÊÜÌÊViÀÌ>ÊÌÞ«iÃÊvÊÞ-+ÊÌ>Lið
loaddata <fixture fixture ...>
This subcommand searches for and loads the contents of the named fixture into the database.
What’s a Fixture?
A fixture is a collection of files that contain the serialized contents of the database. Each fixture
has a unique name, and the files that compose the fixture can be distributed over multiple
directories, in multiple applications.
Django will search in three locations for fixtures:
Ê UÊ ÊÌiÊbetpqnao directory of every installed application
Ê UÊ Ê>ÞÊ`ÀiVÌÀÞÊ>i`ÊÊÌiÊBETPQNA[@ENO setting
Ê UÊ ÊÌiÊÌiÀ>Ê«>ÌÊ>i`ÊLÞÊÌiÊvÝÌÕÀi
Django will load any and all fixtures it finds in these locations that match the provided
fixture names.
APPENDIX F N THE DJANGO-ADMIN UTILITY
460
If the named fixture has a file extension, only fixtures of that type will be loaded. For
example:
`f]jck)]`iej*luhk]``]p]iu`]p]*fokj
would load only JSON fixtures called iu`]p]. The fixture extension must correspond to the reg-
istered name of a serializer (e.g., fokj or tih). For more on serializers, see the Django docs.
If you omit the extensions, Django will search all available fixture types for a matching
fixture. For example:
`f]jck)]`iej*luhk]``]p]iu`]p]
would look for any fixture of any fixture type called iu`]p]. If a fixture directory contained
iu`]p]*fokj, that fixture would be loaded as a JSON fixture.
The fixtures that are named can include directory components. These directories will be
included in the search path. For example:
`f]jck)]`iej*luhk]``]p]bkk+^]n+iu`]p]*fokj
would search 8]llj]ia:+betpqnao+bkk+^]n+iu`]p]*fokj for each installed application,
8`enj]ia:+bkk+^]n+iu`]p]*fokj for each directory in BETPQNA[@ENO, and the literal path bkk+
^]n+iu`]p]*fokj.
When fixture files are processed, the data is saved to the database as is. Model-defined
o]ra methods and lna[o]ra signals are not called.
Note that the order in which fixture files are processed is undefined. However, all fixture
data is installed as a single transaction, so data in one fixture can reference data in another
fixture. If the database back-end supports row-level constraints, these constraints will be
checked at the end of the transaction.
The `qil`]p] command can be used to generate input for hk]``]p].
Compressed Fixtures
Fixtures may be compressed in vel, cv, or ^v. format. For example:
`f]jck)]`iej*luhk]``]p]iu`]p]*fokj
would look for any of iu`]p]*fokj, iu`]p]*fokj*vel, iu`]p]*fokj*cv, or iu`]p]*fokj*^v.. The
first file contained within a ZIP-compressed archive is used.
Note that if two fixtures with the same name but different fixture types are discovered (for
example, if iu`]p]*fokj and iu`]p]*tih*cv were found in the same fixture directory), fixture
installation will be aborted, and any data installed in the call to hk]``]p] will be removed from
the database.
MYSQL AND FIXTURES
Unfortunately, MySQL isn’t capable of completely supporting all the features of Django fixtures. If you use
MyISAM tables, because MySQL doesn’t support transactions or constraints, you won’t get a rollback if multi-
ple fixture files are found or if validation of fixture data fails.
If you use InnoDB tables, you won’t be able to have any forward references in your data files—MySQL
doesn’t provide a mechanism to defer checking of row constraints until a transaction is committed.
APPENDIX F N THE DJANGO-ADMIN UTILITY 461
makemessages
This runs over the entire source tree of the current directory and pulls out all strings marked
for translation. It creates (or updates) a message file in the _kjb+hk_]ha (in the Django tree) or
hk_]ha (for projects and applications) directory. After making changes to the messages files,
you need to compile them with _kilehaiaoo]cao for use with the built-in cappatp support. See
Chapter 19 for details.
--all
Use the ))]hh or )] option to update the message files for all available languages.
Here’s an example of its usage:
`f]jck)]`iej*lui]gaiaoo]cao))]hh
--extension
Use the ))atpajoekj or )a option to specify a list of file extensions to examine (default:
*dpih”).
Here’s a usage example:
`f]jck)]`iej*lui]gaiaoo]cao))hk_]ha9`a))atpajoekjtdpih
Separate multiple extensions with commas or use )a or ))atpajoekj multiple times:
`f]jck)]`iej*lui]gaiaoo]cao))hk_]ha9`a))atpajoekj9dpih(ptp))atpajoekjtih
--locale
Use the ))hk_]ha or )h option to specify the locale to process.
Here’s a usage example:
`f]jck)]`iej*lui]gaiaoo]cao))hk_]ha9^n[LP
--domain
Use the ))`ki]ej or )` option to change the domain of the messages files. These are currently
supported:
ÊUÊ`f]jck for all &*lu and &*dpih files (default)
ÊUÊ`f]jckfo for &*fo files
reset <appname appname ...>
This subcommand executes the equivalent of omhnaoap for the given app name(s).
--noinput
Use the ))jkejlqp option to suppress all user prompting, such as “Are you sure?” confirmation
messages. This is useful if `f]jck)]`iej*lu is being executed as an unattended, automated script.
APPENDIX F N THE DJANGO-ADMIN UTILITY
462
runfcgi [options]
This starts a set of FastCGI processes suitable for use with any Web server that supports the
FastCGI protocol. See Chapter 12 for details. Requires the Python FastCGI module from flup:
dppl6++pn]_*o]``e*_ki+bhql.
runserver
This starts a lightweight development Web server on the local machine. By default, the server
runs on port 8000 on the IP address 127.0.0.1. You can pass in an IP address and port number
explicitly.
If you run this script as a user with normal privileges (recommended), you might not
>ÛiÊ>VViÃÃÊÌÊÃÌ>ÀÌÊ>Ê«ÀÌÊÊ>ÊÜÊ«ÀÌÊÕLiÀ°ÊÜÊ«ÀÌÊÕLiÀÃÊ>ÀiÊÀiÃiÀÛi`ÊvÀÊÌiÊ
superuser (root).
Do not use this server in a production setting. It has not gone through security audits
or performance tests. (And that’s how it’s gonna stay. We’re in the business of making Web
frameworks, not Web servers, so improving this server to be able to handle a production envi-
ronment is outside the scope of Django.)
The development server automatically reloads Python code for each request, as needed.
You don’t need to restart the server for code changes to take effect.
When you start the server, and each time you change Python code while the server is run-
ning, the server will validate all of your installed models. (See the r]he`]pa command later in
this appendix.) If the validator finds errors, it will print them to standard output, but it won’t
stop the server.
You can run as many servers as you want, as long as they’re on separate ports. Just execute
`f]jck)]`iej*lunqjoanran more than once.
Note that the default IP address, 127.0.0.1, is not accessible from other machines on your
network. To make your development server viewable to other machines on the network, use
its own IP address (e.g., 192.168.2.1) or 0.0.0.0 (which you can use if you don’t know what your
IP address is on the network).
Use the ))]`iejia`e] option to tell Django where to find the various CSS and JavaScript
files for the Django admin interface. Normally, the development server serves these files out of
the Django source tree magically, but you’d want to use this if you made any changes to those
files for your own site.
Here’s an example of usage:
`f]jck)]`iej*lunqjoanran))]`iejia`e]9+pil+jas)]`iej)opuha+
Use the ))jknahk]` option to disable the use of the auto-reloader. This means any Python
code changes you make while the server is running will not take effect if the particular Python
modules have already been loaded into memory.
Here’s an example:
`f]jck)]`iej*lunqjoanran))jknahk]`
APPENDIX F N THE DJANGO-ADMIN UTILITY 463
Examples of Using Different Ports and Addresses
Port 8000 on IP address 127.0.0.1:
`f]jck)]`iej*lunqjoanran
Port 8000 on IP address 1.2.3.4:
`f]jck)]`iej*lunqjoanran-*.*/*064,,,
Port 7000 on IP address 127.0.0.1:
`f]jck)]`iej*lunqjoanran3,,,
Port 7000 on IP address 1.2.3.4:
`f]jck)]`iej*lunqjoanran-*.*/*063,,,
Serving Static Files with the Development Server
By default, the development server doesn’t serve any static files for your site (such as CSS files,
images, things under IA@E=[QNH, and so forth).
shell
odahh starts the Python interactive interpreter.
Django will use IPython (dppl6++elupdkj*o_elu*knc+), if it’s installed. If you have IPython
installed and want to force use of the “plain” Python interpreter, use the ))lh]ej option, like so:
`f]jck)]`iej*luodahh))lh]ej
sql <appname appname ...>
This prints the ?NA=PAP=>HAÊ-+ÊÃÌ>ÌiiÌÃÊvÀÊÌi given app name(s).
sqlall <appname appname ...>
This prints the ?NA=PAP=>HAÊ>`ÊÌ>`>Ì>Ê-+ÊÃÌ>ÌiiÌÃÊvÀÊÌiÊ}ÛiÊ>««Ê>iî°
Refer to the description of omh_qopki for an explanation of how to specify initial data.
sqlclear <appname appname ...>
This prints the @NKLP=>HAÊ-+ÊÃÌ>ÌiiÌÃÊvÀÊÌi given app name(s).
APPENDIX F N THE DJANGO-ADMIN UTILITY
464
sqlcustom <appname appname ...>
This prints theÊVÕÃÌÊ-+ÊÃÌ>ÌiiÌÃÊvÀÊÌiÊ}ÛiÊ>««Ê>iî°ÊÀÊi>VÊ`iÊÊi>VÊëiV-
fied app, this command looks for the file 8]llj]ia:+omh+8ik`ahj]ia:*omh, where 8]llj]ia: is the
given app name and 8ik`ahj]ia: is the model’s name in lowercase. For example, if you have an
app jaso that includes a Opknu model, omh_qopki will attempt to read a file jaso+omh+opknu*omh
and append it to the output of this command.
>VÊvÊÌiÊ-+ÊviÃ]ÊvÊ}Ûi]ÊÃÊiÝ«iVÌi`ÊÌÊVÌ>ÊÛ>`Ê-+°Ê/iÊ-+ÊviÃÊ>ÀiÊ««i`Ê
directly into the database after all of the models’ table-creation statements have been exe-
VÕÌi`°Ê1ÃiÊÌÃÊ-+ÊÊÌÊ>iÊ>ÞÊÌ>LiÊ`vV>ÌÃÊÀÊÃiÀÌÊ>ÞÊ-+ÊvÕVÌÃÊÌÊ
the database.
ÌiÊÌ>ÌÊÌiÊÀ`iÀÊÊÜVÊÌiÊ-+ÊviÃÊ>Ài processed is undefined.
sqlflush
This prints theÊ-+ÊÃÌ>ÌiiÌÃÊÌ>ÌÊÜÕ`ÊLiÊiÝiVÕÌi`ÊvÀ the bhqod command.
sqlindexes <appname appname ...>
This subcommand prints the ?NA=PAEJ@ATÊ-+ÊÃÌ>ÌiiÌÃÊvÀÊÌiÊ}Ûi app name(s).
sqlreset <appname appname ...>
This prints the @NKLP=>HAÊ-+ÊÌiÊÌiÊ?NA=PAP=>HAÊ-+ÊvÀÊÌi given app name(s).
sqlsequencereset <appname appname ...>
This prints theÊ-+ÊÃÌ>ÌiiÌÃÊvÀÊÀiÃiÌÌ}ÊÃiµÕiViÃÊvÀ the given app name(s).
startapp <appname>
op]np]ll8]llj]ia: creates a Django app directory structure for the given app name in the
current directory.
startproject <projectname>
This creates a Django project directory structure for the given project name in the current
directory. This command is disabled when the ))oappejco option to `f]jck)]`iej*lu is used,
or when the environment variable @F=JCK[OAPPEJCO[IK@QHA has been set. To re-enable it in
these situations, either omit the ))oappejco option or unset @F=JCK[OAPPEJCO[IK@QHA.
syncdb
ouj_`^ creates the database tables for all apps in EJOP=HHA@[=LLO whose tables have not already
been created. Use this command when you’ve added new applications to your project and
want to install them in the database. This includes any apps shipped with Django that might
be in EJOP=HHA@[=LLO by default. When you start a new project, run this command to install the
default apps.
APPENDIX F N THE DJANGO-ADMIN UTILITY 465
SYNCDB WILL NOT ALTER EXISTING TABLES
ouj_`^ will only create tables for models that have not yet been installed. It will never issue =HPANP=>HA
statements to match changes made to a model class after installation. Changes to model classes and data-
base schemas often involve some form of ambiguity and, in those cases, Django would have to guess at the
correct changes to make. There is a risk that critical data would be lost in the process.
If you have made changes to a model and wish to alter the database tables to match, use the omh
command to display the new SQL structure and compare that to your existing table schema to work out
the changes.
If you’re installing the `f]jck*_kjpne^*]qpd application, ouj_`^ will give you the option of
creating a superuser immediately.
ouj_`^ will also search for and install any fixture named ejepe]h[`]p] with an appropriate
extension (e.g., fokj or tih). See the section on hk]``]p] in the official Django documentation
for details on the specification of fixture data files.
--noinput
Use the ))jkejlqp option to suppress all user prompting, such as “Are you sure?” confirmation
messages. This is useful if `f]jck)]`iej*lu is being executed as an unattended, automated
script.
test
This subcommand runs tests for all installed models. See the Django documentation for more
on testing.
--noinput
Use the ))jkejlqp option to suppress all user prompting, such as “Are you sure?” confir-
mation messages. This is useful if `f]jck)]`iej*lu is being executed as an unattended,
automated script.
testserver <fixture fixture ...>
This runs a Django development server (as in nqjoanran) using data from the given fixture(s).
For more information, see the Django documentation.
validate
This validates all installed models (according to the EJOP=HHA@[=LLO setting) and prints valida-
tion errors to standard output.
APPENDIX F N THE DJANGO-ADMIN UTILITY
466
Default Options
Although some subcommands may allow their own custom options, every subcommand
allows for the following options.
--pythonpath
This adds the given filesystem path to the Python import search path. If this isn’t provided,
`f]jck)]`iej*lu will use the LUPDKJL=PD environment variable.
Here is a usage example:
`f]jck)]`iej*luouj_`^))lupdkjl]pd9#+dkia+`f]jcklnkfa_po+iulnkfa_p#
Note that this option is unnecessary in i]j]ca*lu, which takes care of setting the Python
path for you.
--settings
This explicitly specifies the settings module to use. The settings module should be in Python
package syntax, for example iuoepa*oappejco. If this isn’t provided, `f]jck)]`iej*lu will use
the @F=JCK[OAPPEJCO[IK@QHA environment variable.
Here is a usage example:
`f]jck)]`iej*luouj_`^))oappejco9iuoepa*oappejco
Note that this option is unnecessary in i]j]ca*lu, which uses oappejco*lu from the cur-
rent project by default.
--traceback
By default, `f]jck)]`iej*lu will show a simple error message whenever an error occurs. If you
specify ))pn]_a^]_g, `f]jck)]`iej*lu will output a full stack trace whenever an exception is
raised.
Here is a usage example:
`f]jck)]`iej*luouj_`^))pn]_a^]_g
--verbosity
Use ))ran^koepu to specify the amount of notification and debug information that `f]jck)
]`iej*lu should print to the console.
ÊUÊ, means no output.
ÊUÊ- means normal output (default).
ÊUÊ. means verbose output.
Here is a usage example:
`f]jck)]`iej*luouj_`^))ran^koepu.
APPENDIX F N THE DJANGO-ADMIN UTILITY 467
Extra Niceties
Syntax Coloring
The `f]jck)]`iej*lu / i]j]ca*luÊV>`ÃÊÌ>ÌÊ«ÀÌÊ-+ÊÌ standard output will use pretty
color-coded output if your terminal supports ANSI colors. It won’t use the color codes if you’re
piping the command’s output to another program.
Bash Completion
If you use the Bash shell, consider installing the Django bash completion script, which lives
in atpn]o+`f]jck[^]od[_kilhapekj in the Django distribution. It enables tab completion of
`f]jck)]`iej*lu and i]j]ca*lu commands, so you can, for instance
Ê UÊ /Þ«iÊ`f]jck)]`iej*lu
Ê UÊ *ÀiÃÃÊÌiÊ/>LÊiÞÊÌ see all available options
Ê UÊ /Þ«iÊomh, then press the Tab key to see all available options whose names start with omh
APPENDIX G
Request and Response Objects
Django uses request and response objects to pass state through the system. When a page is
requested, Django creates an DpplNamqaop object that contains metadata about the request.
Then Django loads the appropriate view, passing the DpplNamqaop as the first argument to the
view function. Each view is responsible for returning an DpplNaolkjoa object.
We’ve used these objects often throughout the book; this appendix explains the complete
APIs for DpplNamqaop and DpplNaolkjoa objects.
HttpRequest
DpplNamqaop represents a single HTTP request from some user-agent. Much of the important
information about the request is available as attributes on the DpplNamqaop instance (see Table
G-1). All attributes except oaooekj should be considered read-only.
Table G-1. Attributes of HttpRequest Objects
Attribute Description
l]pd A string representing the full path to the requested page, not including the
domain—for example, +iqoe_+^]j`o+pda[^a]phao+.
iapdk` A string representing the HTTP method used in the request. This is guaranteed to
be uppercase. For example:
ibnamqaop*iapdk`99#CAP#6
`k[okiapdejc$%
ahebnamqaop*iapdk`99#LKOP#6
`k[okiapdejc[ahoa$%
aj_k`ejc A string representing the current encoding used to decode form submission data
(or Jkja, which means the @AB=QHP[?D=NOAP setting is used).
You can write to this attribute to change the encoding used when accessing the
form data. Any subsequent attribute accesses (such as reading from CAP or LKOP)
will use the new aj_k`ejc value. Useful if you know the form data is not in the
@AB=QHP[?D=NOAP encoding.
Continued
469
APPENDIX G N REQUEST AND RESPONSE OBJECTS
470
Table G-1. Continued
Attribute Description
CAP A dictionary-like object containing all given DPPLCAP parameters. See the
“QueryDict Objects” section later in this appendix.
LKOP A dictionary-like object containing all given DPPLLKOP parameters. See the
“QueryDict Objects” section later in this appendix.
It’s possible that a request can come in via LKOP with an empty LKOP dictionary—
if, say, a form is requested via the LKOPDPPL method but does not include form
data. Therefore, you shouldn’t use ebnamqaop*LKOP to check for use of the LKOP
method; instead, use ebnamqaop*iapdk`99LKOP (see the iapdk` entry in
this table).
Note: LKOP does not include file-upload information. See BEHAO.
NAMQAOP For convenience, a dictionary-like object that searches LKOP first, and then CAP.
Inspired by PHP’s [NAMQAOP.
For example, if CAP9wj]ia6fkdjy and LKOP9w]ca6#/0#y,
NAMQAOPWj]iaY would be fkdj, and NAMQAOPW]caY would be /0.
It’s strongly suggested that you use CAP and LKOP instead of NAMQAOP, because the
former are more explicit.
?KKGEAO A standard Python dictionary containing all cookies. Keys and values are strings.
See Chapter 14 for more on using cookies.
BEHAO A dictionary-like object that maps file names to Qlhk]`a`Beha objects. See the
Django documentation for more.
IAP= A standard Python dictionary containing all available HTTP headers. Available
headers depend on the client and server, but here are some examples:
UÊÊ?KJPAJP[HAJCPD
UÊÊ?KJPAJP[PULA
UÊÊMQANU[OPNEJC: The raw unparsed query string
UÊÊNAIKPA[=@@N: The IP address of the client
UÊÊNAIKPA[DKOP: The hostname of the client
UÊÊOANRAN[J=IA: The hostname of the server
UÊÊOANRAN[LKNP: The port of the server
Any HTTP headers are available in IAP= as keys prefixed with DPPL[, converted to
uppercase, and substituting underscores for hyphens. For example:
UÊÊDPPL[=??ALP[AJ?K@EJC
UÊÊDPPL[=??ALP[H=JCQ=CA
UÊÊDPPL[DKOP: The HTTP Dkop header sent by the client
UÊÊDPPL[NABANAN: The referring page, if any
UÊÊDPPL[QOAN[=CAJP: The client’s user-agent string
UÊÊDPPL[T[>AJ@AN: The value of the T)>aj`an header, if set
APPENDIX G N REQUEST AND RESPONSE OBJECTS 471
Attribute Description
qoan A `f]jck*_kjpne^*]qpd*ik`aho*Qoan object representing the currently logged-
in user. If the user isn’t currently logged in, qoan will be set to an instance of
`f]jck*_kjpne^*]qpd*ik`aho*=jkjuikqoQoan. You can tell qoan and
=jkjuikqoQoan apart with eo[]qpdajpe_]pa`$%, like so:
ebnamqaop*qoan*eo[]qpdajpe_]pa`$%6
@kokiapdejcbknhkcca`)ejqoano*
ahoa6
@kokiapdejcbkn]jkjuikqoqoano*
qoan is available only if your Django installation has =qpdajpe_]pekjIe``has]na
activated.
For the complete details of authentication and users, see Chapter 14.
oaooekj A readable and writable dictionary-like object that represents the current session.
This is available only if your Django installation has session support activated.
See Chapter 14.
n]s[lkop[`]p] The raw DPPLLKOP data. This is useful for advanced processing.
Request objects also have a few useful methods, as shown in Table G-2.
Table G-2. HttpRequest Methods
Method Description
[[capepai[[$gau% Returns the CAP/LKOP value for the given key, checking LKOP first, and then
CAP. Raises GauAnnkn if the key doesn’t exist.
This lets you use dictionary-accessing syntax on an DpplNamqaop in-
stance. For example, namqaopWbkkY is the same as checking namqaop*
LKOPWbkkY and then namqaop*CAPWbkkY.
d]o[gau$% Returns Pnqa or B]hoa, designating whether namqaop*CAP or namqaop*LKOP
has the given key.
cap[dkop$% Returns the originating host of the request using information from the
DPPL[T[BKNS=N@A@[DKOP and DPPL[DKOP headers (in that order). If they
don’t provide a value, the method uses a combination of OANRAN[J=IA
and OANRAN[LKNP.
cap[bqhh[l]pd$% Returns the l]pd, plus an appended query string, if applicable. For example,
+iqoe_+^]j`o+pda[^a]phao+;lnejp9pnqa.
eo[oa_qna$% Returns Pnqa if the request is secure; that is, if it was made with HTTPS.
QueryDict Objects
In an DpplNamqaop object, the CAP and LKOP attributes are instances of `f]jck*dppl*Mqanu@e_p.
Mqanu@e_p is a dictionary-like class customized to deal with multiple values for the same key.
This is necessary because some HTML form elements, notably 8oaha_piqhpelha9iqhpelha:,
pass multiple values for the same key.
APPENDIX G N REQUEST AND RESPONSE OBJECTS
472
Mqanu@e_p instances are immutable, unless you create a _klu$% of them. That means you
can’t change attributes of namqaop*LKOP and namqaop*CAP directly.
Mqanu@e_p implements all standard dictionary methods because it’s a subclass of diction-
ary. Exceptions are outlined in Table G-3.
Table G-3. How QueryDicts Differ from Standard Dictionaries
Method Differences from Standard dict Implementation
[[capepai[[ Works just like a dictionary. However, if the key has more than one value,
[[capepai[[$% returns the last value.
[[oapepai[[ Sets the given key to Wr]hqaY (a Python list whose single element is r]hqa).
Note that this, as other dictionary functions that have side effects, can be called
only on a mutable Mqanu@e_p (one that was created via _klu$%).
cap$% If the key has more than one value, cap$% returns the last value just like
[[capepai[[.
ql`]pa$% Takes either a Mqanu@e_p or standard dictionary. Unlike the standard diction-
ary’s ql`]pa method, this method appends to the current dictionary items
rather than replacing them:
:::m9Mqanu@e_p$#]9-#%
:::m9m*_klu$%pki]gaepiqp]^ha
:::m*ql`]pa$w#]#6#.#y%
:::m*capheop$#]#%
W#-#(#.#Y
:::mW#]#Ynapqnjopdah]op
W#.#Y
epaio$% Just like the standard dictionary epaio$% method, except this uses the same
last-value logic as [[capepai$%[[:
:::m9Mqanu@e_p$#]9-"]9."]9/#%
:::m*epaio$%
W$#]#(#/#%Y
r]hqao$% Just like the standard dictionary r]hqao$% method, except this uses the same
last-value logic as [[capepai$%[[.
In addition, Mqanu@e_p has the methods shown in Table G-4.
Table G-4. Extra (Nondictionary) QueryDict Methods
Method Description
_klu$% Returns a copy of the object, using _klu*`aal_klu$% from the Python
standard library. The copy will be mutable—that is, you can change
its values.
capheop$gau% Returns the data with the requested key, as a Python list. Returns an
empty list if the key doesn’t exist. It’s guaranteed to return a list of
some sort.
oapheop$gau(heop[% Sets the given key to heop[ (unlike [[oapepai[[$%).
]llaj`heop$gau(epai% Appends an item to the internal list associated with gau.
APPENDIX G N REQUEST AND RESPONSE OBJECTS 473
Method Description
oapheop`ab]qhp$gau(]% Just like oap`ab]qhp, except it takes a list of values instead of a
single value.
heopo$% Like epaio$%, except it includes all values, as a list, for each member
of the dictionary. For example:
:::m9Mqanu@e_p$#]9-"]9."]9/#%
:::m*heopo$%
W$#]#(W#-#(#.#(#/#Y%Y
qnhaj_k`a$% Returns a string of the data in query-string format (e.g., ]9."^9/"^91).
A Complete Example
For example, given this HTML form
8bkni]_pekj9+bkk+^]n+iapdk`9lkop:
8ejlqppula9patpj]ia9ukqn[j]ia+:
8oaha_piqhpelha9iqhpelhaj]ia9^]j`o:
8klpekjr]hqa9^a]phao:Pda>a]phao8+klpekj:
8klpekjr]hqa9sdk:PdaSdk8+klpekj:
8klpekjr]hqa9vki^eao:PdaVki^eao8+klpekj:
8+oaha_p:
8ejlqppula9oq^iep+:
8+bkni:
if the user enters FkdjOiepd in the ukqn[j]ia field and selects both The Beatles and The
Zombies in the multiple-select box, here’s what Django’s request object would have:
:::namqaop*CAP
wy
:::namqaop*LKOP
w#ukqn[j]ia#6W#FkdjOiepd#Y(#^]j`o#6W#^a]phao#(#vki^eao#Yy
:::namqaop*LKOPW#ukqn[j]ia#Y
#FkdjOiepd#
:::namqaop*LKOPW#^]j`o#Y
#vki^eao#
:::namqaop*LKOP*capheop$#^]j`o#%
W#^a]phao#(#vki^eao#Y
:::namqaop*LKOP*cap$#ukqn[j]ia#(#=`ne]j#%
#FkdjOiepd#
:::namqaop*LKOP*cap$#jkjateopajp[beah`#(#JksdanaI]j#%
#JksdanaI]j#
NNote The CAP, LKOP, ?KKGEAO, BEHAO, IAP=, NAMQAOP, n]s[lkop[`]p], and qoan attributes are all
lazily loaded. That means Django doesn’t spend resources calculating the values of those attributes until your
code requests them.
APPENDIX G N REQUEST AND RESPONSE OBJECTS
474
HttpResponse
In contrast to DpplNamqaop objects, which are created automatically by Django, DpplNaolkjoa
objects are your responsibility. Each view you write is responsible for instantiating, populat-
ing, and returning an DpplNaolkjoa.
The DpplNaolkjoa class lives at `f]jck*dppl*DpplNaolkjoa.
Construction HttpResponses
Typically, you’ll construct an DpplNaolkjoa to pass the contents of the page, as a string, to the
DpplNaolkjoa constructor:
:::naolkjoa9DpplNaolkjoa$Dana#opdapatpkbpdaSa^l]ca*%
:::naolkjoa9DpplNaolkjoa$Patpkjhu(lha]oa*(ieiapula9patp+lh]ej%
But if you want to add content incrementally, you can use naolkjoa as a filelike object:
:::naolkjoa9DpplNaolkjoa$%
:::naolkjoa*snepa$8l:Dana#opdapatpkbpdaSa^l]ca*8+l:%
:::naolkjoa*snepa$8l:Dana#o]jkpdanl]n]cn]ld*8+l:%
You can pass DpplNaolkjoa an iterator rather than passing it hard-coded strings. If you use
this technique, follow these guidelines:
Ê UÊ /iÊÌiÀ>ÌÀÊÃÕ`ÊÀiÌÕÀÊÃÌÀ}ð
Ê UÊ vÊ>ÊDpplNaolkjoa has been initialized with an iterator as its content, you can’t use the
DpplNaolkjoa instance as a filelike object. Doing so will raise At_alpekj.
Finally, note that DpplNaolkjoa implements a snepa$% method, which makes it suitable for
use anywhere that Python expects a filelike object. See Chapter 8 for some examples of using
this technique.
Setting Headers
You can add and delete headers using dictionary syntax:
:::naolkjoa9DpplNaolkjoa$%
:::naolkjoaW#T)@F=JCK#Y9Ep#opda^aop*
:::`ahnaolkjoaW#T)LDL#Y
:::naolkjoaW#T)@F=JCK#Y
Ep#opda^aop*
You can also use d]o[da]`an$da]`an% to check for the existence of a header.
Avoid setting ?kkgea headers by hand; instead, see Chapter 14 for instructions on how
cookies work in Django.
HttpResponse Subclasses
Django includes a number of DpplNaolkjoa subclasses that handle different types of HTTP
responses (see Table G-5). Like DpplNaolkjoa, these subclasses live in `f]jck*dppl.
APPENDIX G N REQUEST AND RESPONSE OBJECTS 475
Table G-5. HttpResponse Subclasses
Class Description
DpplNaolkjoaNa`ena_p The constructor takes a single argument: the path to redirect
to. This can be a fully qualified URL (e.g., #dppl6++oa]n_d*
u]dkk*_ki+#) or an absolute URL with no domain (e.g.,
#+oa]n_d+#). Note that this returns an HTTP status code 302.
DpplNaolkjoaLani]jajpNa`ena_p Like DpplNaolkjoaNa`ena_p, but it returns a permanent
redirect (HTTP status code 301) instead of a “found” redirect
(status code 302).
DpplNaolkjoaJkpIk`ebea` The constructor doesn’t take any arguments. Use this to
designate that a page hasn’t been modified since the user’s
last request.
DpplNaolkjoa>]`Namqaop Acts just like DpplNaolkjoa but uses a 400 status code.
DpplNaolkjoaJkpBkqj` Acts just like DpplNaolkjoa but uses a 404 status code.
DpplNaolkjoaBkn^e``aj Acts just like DpplNaolkjoa but uses a 403 status code.
DpplNaolkjoaJkp=hhksa` Acts like DpplNaolkjoa but uses a 405 status code. It takes a
single, required argument: a list of permitted methods (e.g.,
W#CAP#(#LKOP#Y).
DpplNaolkjoaCkja Acts just like DpplNaolkjoa but uses a 410 status code.
DpplNaolkjoaOanranAnnkn Acts just like DpplNaolkjoa but uses a 500 status code.
You can, of course, define your own DpplNaolkjoa subclass to support different types of
responses not supported out of the box.
Returning Errors
Returning HTTP error codes in Django is easy. We’ve already mentioned the
DpplNaolkjoaJkpBkqj`, DpplNaolkjoaBkn^e``aj, DpplNaolkjoaOanranAnnkn, and other sub-
classes. Just return an instance of one of those subclasses instead of a normal DpplNaolkjoa
in order to signify an error, as in this example:
`abiu[reas$namqaop%6
***
ebbkk6
napqnjDpplNaolkjoaJkpBkqj`$#8d-:L]cajkpbkqj`8+d-:#%
ahoa6
napqnjDpplNaolkjoa$#8d-:L]cas]obkqj`8+d-:#%
Because a 404 error is by far the most common HTTP error, there’s an easier way to han-
dle it. When you return an error such as DpplNaolkjoaJkpBkqj`, you’re responsible for defining
the HTML of the resulting error page:
napqnjDpplNaolkjoaJkpBkqj`$#8d-:L]cajkpbkqj`8+d-:#%
For convenience, and because it’s a good idea to have a consistent 404 error page across
your site, Django provides an Dppl0,0 exception. If you raise Dppl0,0 at any point in a view
function, Django will catch it and return the standard error page for your application, along
with an HTTP error code 404. Here’s an example:
APPENDIX G N REQUEST AND RESPONSE OBJECTS
476
bnki`f]jck*dppleilknpDppl0,0
`ab`ap]eh$namqaop(lkhh[e`%6
pnu6
l9Lkhh*k^fa_po*cap$lg9lkhh[e`%
at_alpLkhh*@kaoJkpAteop6
n]eoaDppl0,0
napqnjnaj`an[pk[naolkjoa$#lkhho+`ap]eh*dpih#(w#lkhh#6ly%
In order to use the Dppl0,0 exception to its fullest, you should create a template that is
displayed when a 404 error is raised. This template should be called 0,0*dpih, and it should be
located in the top level of your template tree.
Customizing the 404 (Not Found) View
When you raise an Dppl0,0 exception, Django loads a special view devoted to handling 404
errors. By default, it’s the view `f]jck*reaso*`ab]qhpo*l]ca[jkp[bkqj`, which loads and ren-
ders the template 0,0*dpih.
This means you need to define a 0,0*dpih template in your root template directory. This
template will be used for all 404 errors.
This l]ca[jkp[bkqj` view should suffice for 99% of Web applications, but if you want to
override the 404 view, you can specify d]j`han0,0 in your URLconf, like so:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
qnhl]ppanjo9l]ppanjo$##(
***
%
d]j`han0,09#iuoepa*reaso*iu[_qopki[0,0[reas#
Behind the scenes, Django determines the 404 view by looking for d]j`han0,0. By default,
URLconfs contain the following line:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
That takes care of setting d]j`han0,0 in the current module. As you can see in `f]jck+
_kjb+qnho+`ab]qhpo*lu, d]j`han0,0 is set to #`f]jck*reaso*`ab]qhpo*l]ca[jkp[bkqj`# by
default.
There are three things to note about 404 views:
Ê UÊ /iÊ{ä{ÊÛiÜÊÃÊ>ÃÊV>i`ÊvÊ>}Ê`iÃ½ÌÊv`Ê>Ê>ÌVÊ>vÌiÀÊViV}ÊiÛiÀÞÊÀi}Õ>ÀÊ
expression in the URLconf.
Ê UÊ vÊÞÕÊ`½ÌÊ`iviÊÞÕÀÊÜÊ{ä{ÊÛiÜp>`ÊÃ«ÞÊÕÃiÊÌiÊ`iv>ÕÌ]ÊÜVÊÃÊÀiV-
mended—you still have one obligation: to create a 0,0*dpih template in the root of
your template directory. The default 404 view will use that template for all 404 errors.
Ê UÊ vÊ@A>QC is set to Pnqa (in your settings module), then your 404 view will never be used,
and the traceback will be displayed instead.
APPENDIX G N REQUEST AND RESPONSE OBJECTS 477
Customizing the 500 (Server Error) View
Similarly, Django executes special-case behavior in the case of runtime errors in view code.
If a view results in an exception, Django will, by default, call the view `f]jck*reaso*`ab]qhpo*
oanran[annkn, which loads and renders the template 1,,*dpih. This means you need to define
a 1,,*dpih template in your root template directory. This template will be used for all server
errors.
This oanran[annkn view should suffice for 99% of Web applications, but if you want to
override the view, you can specify d]j`han1,, in your URLconf, like so:
bnki`f]jck*_kjb*qnho*`ab]qhpoeilknp&
qnhl]ppanjo9l]ppanjo$##(
***
%
d]j`han1,,9#iuoepa*reaso*iu[_qopki[annkn[reas#
479
Index
Special Characters
% (percent sign), 383
* symbol, 26
.. (two periods), 347
[^/]+ symbol, 26
_ (underscore), 383
{ } (empty dictionary), 417
+ symbol, 26
{1,3} symbol, 26
. (dot) symbol, 26
'' (empty string) value, 418–419, 421, 423, 426
( ) (empty tuple) value, 418, 420, 422–423
? symbol, 26
Numerics
0 errors found message, 81
25 value, 421
404 (not found) view, 476
404 error message, 26, 476
404.html template, implementing, 214
500 (server error) view, 477
500.html template, implementing, 214–215
1209600 value, 424
A
a format character, 436
A format character, 436
-a option, 461
/about/ path, 163
ABSOLUTE_URL_OVERRIDES setting,
417–418
abstract meta option, 365
{{ account.delete }} variable, 49
/accounts/login/ directory, 162, 268
/accounts/logout/ directory, 268
acquired data management, 117
active flag, 116
add( ) method, 285
add permission, 274
add(obj1, obj2, ...) method, 389
addslashes filter, 57, 442
/admin/ file, 322
admin home page, 97
admin interface. See also admin site
manipulating flatpages via, 301
manipulating redirects via, 303
overview, 95
admin package, 291
admin site
activating, 96–97
advantages/disadvantages of, 117
django.contrib packages, 95–96
field labels, customizing, 105–106
fields, making optional, 103–105
function of, 103
groups, 116
ModelAdmin classes, custom
change lists, 106–112
edit forms, 112–115
overview, 106
models, adding to, 102
overview, 95, 97–100
permissions, 116
users, 116
ADMIN_MEDIA_PREFIX setting, 418
admin.autodiscover( ) statement, 103
admindocs package, 291
--adminmedia option, 462
admin.py file, 103
ADMINS setting, 215, 418
admin.site.register( ) function, 108
all( ) method, 84, 154, 373
--all option, 461
allow_empty argument, 395
allow_future argument, 402, 404–405,
407–408, 411
allow_lazy( ) decorator, 329–330
ALLOWED_INCLUDE_ROOTS setting, 418
ALTER TABLE statement, 196
alters_data attribute, 49
'America/Chicago' value, 427
and clause, 51
anonymous session support (django.contrib.
sessions), 95
AnonymousUser object, 264–265
Apache
deploying Django, 218–222
running Django on shared-hosting
provider with, 227
NINDEX
480
apnumber filter, 306
app names, 456
app variable, 169–170
APPEND_SLASH setting, 25, 313, 418
appendlist(key, item) method, 472
application/pdf MIME type, 241
applications (apps), overview, 76–77
arbitrary logic, 71
archive index, 402–403
archive_day view function, 408
archive_index view function, 402
archive_month view function, 404
archive_today view function, 409
archive_week view function, 406
archive_year view function, 403
args argument, 312
Article model, 294
article_detail view, 294
/articles/2006/03/ path, 149
assert False view, 37
Atom feeds, 242, 248
auth package, 291
auth_permission database table, 274
authenticate( ) method, 267, 319–320
authentication, 264
authentication data, using in templates,
273–274
enabling, 264–265
legacy system, integrating with, 319–321
limiting access
to logged-in users, 269
to users who pass test, 269–270
logging in and out, 267–268
overview, 264
passwords, changing, 271
registration, 272–273
users
creating, 271
using, 265–266
authentication support middleware, 313
AUTHENTICATION_BACKENDS setting, 319
AuthenticationMiddleware class, 313
/auth/groups/add/ path, 156
auth.logout( ) method, 267
Author object, 186
/auth/user/add/ path, 157
autoescape tag, 174, 429
AutoField field, 354
autoincrementing primary keys, 370–371
[A-Z] symbol, 26
[a-z] symbol, 26
[A-Za-z] symbol, 26
B
b format character, 436
<b>Hello!</b> string, 175
BankAccount object, 49
base template, 67
base_SECTION.html template, 69
base.html file, 68–69, 214, 431
Bash completion, 467
bind parameters, 343
bio variable, 57
blank field option, 360
blank=False value, 103
blank=True value, 103
block tag, 43, 68–69, 429
blocktrans tag, 328
BlogEntry objects, 153
Book objects, 124
book_set attribute name, 192
book_snippet.html file, 187
BookManager class, 198
Book.objects.all( ) method, 197
Book.objects.filter(title__icontains=q)
method, 124
books/views.py file, 130
BooleanField field, 354
broken link alerts, setting up, 215
browser-length sessions, 262–263
brute-force attacks, 272
built-in middleware, 313–315
business logic, 58, 73
C
cache object, 285
cache tag, 284
CACHE_BACKEND setting, 278–279, 281,
285, 418
cache_control( ) method, 288–289
CACHE_MIDDLEWARE_ANONYMOUS_
ONLY setting, 282
CACHE_MIDDLEWARE_KEY_PREFIX set-
ting, 282, 418
CACHE_MIDDLEWARE_SECONDS setting,
282
CACHE_MIDDLEWARE_SETTINGS setting,
289
cache_page decorator, 282–283
Cache-Control header, 282
cache.get( ) method, 285
caching
CACHE_BACKEND arguments, 281
controlling, 288–289
custom cache back-end, 280
database, 279
NINDEX 481
dummy, 280
filesystem, 279
local-memory, 280
low-level cache API, 284–286
Memcached, 278–279
MIDDLEWARE_CLASSES setting, 290
overview, 277
per-site, 281–282
per-view, 282–283
QuerySets and, 373
template fragment, 284
upstream, 286–287
Vary headers, 287–288
can_edit_home_page permission, 275
can_vote permission, 269
Canvas class, 241
capfirst filter, 442
capturing text, in URLs, 157–158
center filter, 442
CGI (Common Gateway Interface), 3, 5, 36
'/cgi-bin/' value, 422
chaining
filters, 374–375
lookups, 91
change lists, 98, 106–112
change permission, 274
changefreq( ) method, 251
changesets, 14
CharField object, 137, 354
charts, 242
check_password( ) method, 266, 271
.chi extension, 3
child templates, 67
chmod +x django-admin.py command, 18
Choice model, 274
choices field option, 360–361
class Meta class, 365
clean_message( ) method, 138–139
cleaned_data attribute, 135–136
cleanup subcommand, 456
clear( ) method, 390
closeblock argument, 441
closebrace argument, 441
closecomment argument, 441
closevariable argument, 441
cmemcache module, 278
comma-separated values (CSV), 238–239
CommaSeparatedIntegerField field, 354
comment tag, 56, 185, 429
CommentNode.render( ) method, 185
comments, template, 56
comments package, 291
COMMIT database, 315
Common Gateway Interface (CGI), 3, 5, 36
common middleware, 313–314
CommonMiddleware class, 215, 311, 313, 420
compilation function, 180–181
compilemessages subcommand, 456–457
compressed fixtures, 460
compression middleware, 314
conditional GET middleware, 314
ConditionalGetMiddleware class, 290, 314
configure( ) method, 417
confirm POST variable, 304
contact( ) view, 130, 136
contact form, 129–133
contact_form.html template, 129, 131, 139
ContactForm object, 137
contains field lookup, 382–383
content field, 300
Content-Disposition header, 239
Content-Length response header, 314
Content-Type header, 305
contenttypes package, 292
context, 41, 43, 168
Context( ) method, 49
Context class, 43–44
context function, 187
Context object, 45, 49–50, 63
context processors, 168–172
Context subclass, 168
context variable lookup, 46–49
context_instance argument, 170
context_processors argument, 395
context_processors.py file, 172
control structures, 8
Cookie value, 256
cookie-forging attack, 345
cookies, 255–258, 261
COOKIES object, 256, 470
copy( ) method, 472
count( ) method, 381
counter variable, 432
create( ) method, 84
CREATE TABLE statements, 82
create(**kwargs) method, 379, 389
create_user helper function, 271
createcachetable subcommand, 457
createsuperuser subcommand, 457
cross-site request forgery (CSRF), 304–306,
345
cross-site scripting (XSS), 173, 343–345
csrf object, 292, 309
CsrfMiddleware class, 305–306
csrfmiddlewaretoken field, 305
cStringIO library, 241
CSV (comma-separated values), 238–239
csv.writer function, 239
cull_percentage argument, 281
NINDEX
482
current_datetime view, 30–31, 34–35, 58,
61–63, 66
current_datetime.html file, 62, 66, 68
current_time variable, 183, 185–186
CurrentSiteManager model manager,
297–298
/current-time/ path, 31
CurrentTimeNode object, 181–183
CurrentTimeNode2 object, 183
currentuser variable, 55
custom cache back-end, 280
custom_proc function, 169
cut filter, 179, 442
cx_Oracle library, 17
cycle tag, 430
D
d format character, 436
D format character, 436
-d option, 461
\d symbol, 26
data access, 73, 83–84
data model inspection, 117
data preprocessing, 370
data structures, 8
database caching, 279. See also caching
DATABASE_ENGINE setting, 74, 317, 418
DATABASE_HOST setting, 75, 229, 317, 419
DATABASE_NAME setting, 28, 75, 317, 419
DATABASE_OPTIONS setting, 419
DATABASE_PASSWORD setting, 75, 317, 419
DATABASE_PORT setting, 317, 419
DATABASE_SERVER setting, 83
DATABASE_USER setting, 75, 317, 419
database-driven Web sites, 15, 70–71
databases
configuring, 74–76
legacy, integrating with, 317–319
schema, making changes to, 193–196
using Django with, 15–17
using Django without, 17
databrowse package, 292
data-management apps, 117
date fields, making optional, 104–105
date filter, 41, 57, 442–443
Date response header, 314
date_field argument, 402–403, 405, 407–408,
410
DATE_FORMAT setting, 419
date_hierarchy admin option, 111
date_joined field, 265
date_list variable, 403–404
date-based detail pages, 409–411
date-based generic views
archive index, 402–403
date-based detail pages, 409–411
day archives, 408–409
month archives, 404–406
overview, 401
today archives, 409
week archives, 406–407
year archives, 403–404
DateField field, 136, 355
dates(field, kind, order) method, 377
datetime module, 29, 45
DATETIME_FORMAT setting, 420
datetime.date object, 46, 136, 157, 355
datetime.datetime object, 30, 35
datetime.datetime.now( ) function, 29, 35
DateTimeField field, 355
datetime.timedelta function, 35–36
day archives, 408–409
day argument, 408–410
day attribute, 46, 153
day field lookup, 384
"day" value, 377
day_archive( ) function, 158
day_format argument, 408, 411
db_column field option, 318, 361
db_index field option, 361
db_table meta option, 365–366
db_tablespace field option, 361
db_tablespace meta option, 366
dbshell subcommand, 457
debug mode, 26, 148, 172, 213–214, 420, 456
debug tag, 431
debug variable, 171
/debuginfo/ path, 148
decimal_place argument, 355
decimal.Decimal instance, 355
DecimalField field, 355
default argument, 285
default field option, 361
default filter, 443
default view arguments, 155–156
DEFAULT_CHARSET setting, 190, 420
DEFAULT_CONTENT_TYPE setting, 420
DEFAULT_FROM_EMAIL setting, 420
default_if_none filter, 443
default.html file, 301
delete( ) method, 49, 285, 391–392
delete permission, 274
delete_first_token( ) method, 185
delete_test_cookie( ) method, 261
deleting
flatpages, 301
objects, 93–94, 391–392
redirects, 303
NINDEX 483
description( ) method, 246
description field, 299
detail views, 400–401
development server, running, 18–19
dictsort filter, 443
dictsortreversed filter, 444
diffsettings subcommand, 458
direct_to_template view, 204–205, 396
directory traversal, 205, 347–349
<Directory> directive, 219
DISALLOWED_USER_AGENTS setting, 313,
420
distinct( ) method, 376
<div> tag, 141
divisibleby filter, 444
Django
deploying
DJANGO_SETTINGS_MODULE,
217–218
overview, 213
performance tuning, 232–234
preparing codebase for, 213–215
scaling, 228–232
using different settings for, 216–217
using with Apache, 218–222
using with FastCGI, 222–227
help resources, 9
history of, 7–8
installing, 12–14
MVC design pattern, 5–6
overview, 3–11
projects, 17–19
Python, 8–9, 11–12
using with databases, 15–17
versions of, 9
Web frameworks, 3–5
#django channel, 9
'[Django] ' value, 421
django_flatpage command, 299
django_flatpage_sites command, 299
django_redirect table, 302
django_session table, 263
DJANGO_SETTINGS_MODULE variable, 42,
189, 217–218, 415–417
django_site table, 294
Django/<version> value, 427
Django-1.0.2-final.tar.gz file, 12
django-admin utility
Bash completion, 467
default options, 466
overview, 455
subcommands, 456–465
syntax coloring, 467
using, 455–456
django-admin.py compilemessages utility,
332
django-admin.py makemessages tool, 330,
334–335, 339
django-admin.py startproject command, 18,
21–22, 28, 213, 216–217, 310
django-admin.py startproject mysite com-
mand, 18, 317
django-admin.py utility, 13, 18, 217, 415
django/conf/global_settings.py file, 413
django.conf.settings object, 414
django.conf.settings.configure( ) method, 416
django.conf.urls.defaults module, 23
django.contrib package
CSRF protection, 304–306
flatpages application, 299–302
humanizing data, 306–307
markup filters, 307
overview, 95–96, 291
redirects framework, 302–303
sites framework, 293–299
django.contrib.auth (user-authentication
system), 95
django.contrib.auth.models parameter, 171,
275
django.contrib.auth.views.login view, 299
django.contrib.comments (user comment
system), 95
django.contrib.csrf package, 304–305
django.contrib.flatpages command, 299
django/contrib/flatpages/models.py file,
300–301
django.contrib.humanize package, 306
django.contrib.markup package, 307
django/contrib/markup/templatetags/
markup.py file, 307
django/contrib/redirects/models.py file, 303
django.contrib.sessions (anonymous session
support), 95
django.contrib.sessions.models parameter,
261
django.core.cache module, 285
django/core/cache/backends/ directory, 280
django.core.context_processors.auth context
processor, 171
django.core.context_processors.debug con-
text processor, 171–172
django.core.context_processors.i18n context
processor, 172
django.core.context_processors.request
context processor, 172
django.db.connection object, 200
django.db.connection.queries command,
213
django.forms library, 133
NINDEX
484
django.http module, 22
django.middleware.http template, 310
django.newforms library, 133
django.pth file, 13
django.template module, 42
django.views.decorators.cache, 282
djtrunk directory, 13–14
djtrunk/django/bin path, 13, 18
do_comment( ) method, 185
do_current_time( ) method, 184
DocumentRoot directive, 221
DoesNotExist exception, 90
domain field, 296, 298
--domain option, 461
domain parameter, 257
Don't Repeat Yourself (DRY) principle, 245
dot (.) symbol, 26
double-escaping data, 175
duck typing, 154
dummy caching, 280
dumpdata subcommand, 458
dynamic content, 28–30
dynamic images, 242
dynamic URLs, 31–35
dynamic Web pages, 28
E
-e option, 461
edit forms, 98, 100, 112–115
editable field option, 361
else tag, 50–52
--email argument, 457
e-mail field, 131, 135, 139, 265, 355
e-mail header injection, 347
e-mail security, 342
EMAIL_HOST setting, 215, 421
EMAIL_HOST_PASSWORD setting, 421
EMAIL_HOST_USER setting, 421
EMAIL_PORT setting, 421
EMAIL_SUBJECT_PREFIX setting, 215, 421
email_user(subj, msg) method, 266
empty dictionary ({ }), 417
empty string ('') value, 418–419, 421, 423, 426
empty tag, 53
empty tuple (( )) value, 418, 420, 422–423
enable_comments field, 300
enclosures, 247
encoding attribute, 469
endcomment tag, 185
endiftag, 50, 52
endifequal tag, 55
endswith field lookup, 384
enduppertag, 185
'en-us' value, 422
error alerts, setting up, 215
error handling, Apache, 221
error messages, exposed, 349
error pages, Django, 35–37
error variable, 125
error_log file, 221
errors attribute, 135
errors class, 141
escape( ) method, 362
escape filter, 173, 175, 444
escapejs filter, 444
escaping HTML, 444
Event objects, 153
exact field lookup, 382
Exception object, 312
exception postprocessor method, 312
exclude( ) method, 374, 376
--exclude option, 458
Expires header, 282
expires parameter, 257
exposed error messages, 349
extends tag, 68–69, 431
--extension option, 461
external data, 121
extra( ) method, 343
extra_context argument, 208, 210, 395
F
f format character, 436
F format character, 436
'F Y' value, 428
False object, 51
False value, 420, 424–425, 427, 453
FastCGI
lighttpd server, 225–227
overview, 222–223
running Django on shared-hosting pro-
vider with Apache, 227
running server, 223–224
using with Django and Apache, 224–225
FastCGIExternalServer directive, 224–225
fastcgi.server directive, 227
_fav_color session key, 259
'favicon.ico' value, 421
favorite_color cookie, 256
Feed class, 243
feed_dict argument, 243
FetchFromCacheMiddleware class, 281, 290,
315
Field class, 134
NINDEX 485
field lookups
contains, 382–383
day, 384
endswith, 384
exact, 382
gt, 383
gte, 383
icontains, 383
iendswith, 384
iexact, 382
in, 383
isnull, 385
istartswith, 384
lt, 383
lte, 383
month, 384
overview, 382
pk lookup shortcut, 385
range, 384
search, 385
startswith, 384
year, 384
fields
adding, 193–196
AutoField, 354
BooleanField, 354
CharField, 354
CommaSeparatedIntegerField, 354
DateField, 355
DateTimeField, 355
DecimalField, 355
EmailField, 355
FileField, 355–356
FilePathField, 357
FloatField, 357
ImageField, 357–358
IntegerField, 358
IPAddressField, 358
making optional, 103–105
NullBooleanField, 358
overview, 353–354
PositiveIntegerField, 358
PositiveSmallIntegerField, 358
removing, 196
removing many-to-many, 196
SlugField, 358
SmallIntegerField, 358
TextField, 358
TimeField, 358
URLField, 359
XMLField, 359
fields option, 112–113
file:// cache type, 279
FileField field, 355–356
FilePathField field, 357
FILES attribute, 470
filesizeformat filter, 444
filesystem caching, 279
filter( ) method, 88, 179, 374, 376
filter arguments, 57, 176
filter tag, 431
filter_horizontal argument, 113–114
filter_vertical option, 114
filtering
chaining filters, 374–375
limiting QuerySets, 375–376
overview, 88–89, 373–374
QuerySet methods
that do not return QuerySets, 379–382
that return new QuerySets, 376–379
with wrapper functions, 210
filters
addslashes, 442
capfirst, 442
center, 442
cut, 442
date, 442–443
default, 443
default_if_none, 443
defined, 41
dictsort, 443
dictsortreversed, 444
divisibleby, 444
escape, 444
escapejs, 444
filesizeformat, 444
first, 445
fix_ampersands, 445
floatformat, 445–446
force_escape, 446
get_digit, 446
iriencode, 446
join, 446
last, 447
length, 447
length_is, 447
linebreaks, 447
linebreaksbr, 447
linenumbers, 447
ljust, 447
lower, 448
make_list, 448
overview, 429, 442
phone2numeric, 448
pluralize, 448
pprint, 448
random, 449
removetags, 449
rjust, 449
safe, 449
NINDEX
486
safeseq, 449
slice, 449
slugify, 450
stringformat, 450
striptags, 450
template, 56–57
time, 450
timesince, 451
timeuntil, 451
title, 451
truncatewords, 451
truncatewords_html, 451
unordered_list, 452
upper, 452
urlencode, 452
urlize, 452
urlizetrunc, 453
wordcount, 453
wordwrap, 453
writing custom, 178–179
yesno, 453
first filter, 445
first variable, 432
first_name field, 265
firstof tag, 431
fix_ampersands filter, 445
FIXTURE_DIRS setting, 421
fixtures, 459–460
FlatPage model, 300
FlatpageFallbackMiddleware class, 299–301
flatpages application, 299–302
flatpages object, 309
flatpages package, 292
flatpages/default.html template, 300–302
FlatPageSitemap class, 251
FloatField field, 357
floatformat filter, 445–446
flush subcommand, 458
foo filter, 178
foo_view( ) function, 22
/foo/1/ directory, 283
/foo/23/ directory, 283
/foo/bar/hello/ file, 25
footer block, 68
for statement, 41
for tag, 41, 52–55, 185, 432–433
force_escape filter, 446
foreign keys, 102, 192, 387–388
ForeignKey class, 295, 298, 363–364
forloop variable, 54–55
forloop.counter attribute, 53, 432
forloop.first attribute, 54
forloop.last attribute, 54
forloop.parentloop attribute, 54–55
forloop.revcounter attribute, 54, 432
forloop.revcounter0 attribute, 54, 432
form redisplay, 131
<form> tag, 121, 134, 304
{{ form.as_table }} template, 140
{{ form.fieldname.errors }} template, 140
{{ form.message.errors }} template, 141
forms
contact form, 129–133
example
improving, 125–127
overview, 122–125
form class
custom validation rules, adding,
138–139
customizing form design, 139–141
field rendering, changing, 137
initial values, setting, 138
labels, specifying, 139
maximum length, setting, 137–138
overview, 133–136
tying form objects into views, 136–137
overview, 119
retrieving data from request object,
119–122
validation, 127–128
forms.py file, 133
formtools package, 292
fp.close( ) method, 59
fp.read( ) method, 59
Freenode IRC network, 9
G
g format character, 437
G format character, 437
generic views
arguments, 395
date-based
archive for today, 409
archive index, 402–403
day archives, 408–409
detail pages, 409–411
month archives, 404–406
overview, 401
week archives, 406–407
year archives, 403–404
extending
adding extra context, 208–209
complex filtering with wrapper func-
tions, 210
"friendly" template contexts, 207
overview, 207
performing extra work, 211–212
viewing subsets of objects, 209–210
NINDEX 487
list/detail generic views, 397–401
lists of objects, 397–399
of objects, 205–207
overview, 203, 395
"simple," 396–397
using, 204–205
GenericSitemap class, 252
Geographic Information Systems (GIS), 11
get( ) method, 89, 121–122, 131, 472
GET parameter, 124, 126, 158, 160, 256, 268,
304, 314, 470
get(**lookup) method, 379
get_absolute_url( ) method, 245, 417
get_all_permissions( ) method, 266
get_and_delete_messages( ) method, 266,
275–276
get_current( ) method, 295
get_decoded( ) method, 262
get_digit filter, 446
get_full_name( ) method, 265
get_full_path( ) method, 471
get_group_permissions( ) method, 266
get_host( ) method, 471
get_latest_by meta option, 366
get_list_or_404( ) function, 392
get_many( ) interface, 285
get_object( ) method, 246
get_object_or_404( ) function, 392
get_or_create(**kwargs) method, 380–381
get_template( ) function, 61–62, 64, 176
get_user( ) method, 319–320
__getitem__ method, 471–472
getlist(key) method, 472
gettext( ) function, 331, 338–340, 422
GIF images, 242
GIS (Geographic Information Systems), 11
gis package, 292
global_settings.py file, 413
Google, 253
greeting variable, 175
grouper attribute, 439
groups, 116, 264, 275
groups field, 266
gt field lookup, 383
gte field lookup, 383
GZipMiddleware class, 290, 305, 314
H
H format character, 437
h format character, 437
<h1> header, 67
has_commented variable, 260
has_header(header) method, 474
has_key( ) method, 471
has_module_perms(app_label) method, 266
has_next variable, 399
has_perm(perm) method, 266
has_perms(perm_list) method, 266
has_previous variable, 399
hashes, 272
HEAD request, 314
header.html file, 67
height_field argument, 357
hello( ) view, 22, 29, 119
/hello/ path, 24, 28
hello_wonderful_beautiful_world view func-
tion, 22
hello.html file, 21
help resources, 9
help_text field option, 361–362
History link, 100
hits variable, 399
home_link variable, 187
home_title variable, 187
/home/username/djcode/ directory, 17
host property, 223
hours parameter, 36
hours_ahead view, 33–35, 37, 66, 68
.htaccess file, 227
HTML escaping, automatic, 173–176
HTTP_REFERER key, 120
HTTP_USER_AGENT key, 120
HTTP_X_FORWARDED_FOR setting, 315
Http404 exception, 475–476
httpd.conf file, 227, 321
HttpRequest object
example, 473
overview, 469–471
QueryDict object, 471–473
HttpResponse object
404 (not found) view, 476
500 (server error) view, 477
constructors, 474
error returning, 475–476
headers, setting, 474
overview, 469–474
subclasses, 474–475
HttpResponseBadRequest class, 475
HttpResponseForbidden class, 475
HttpResponseGone class, 475
HttpResponseNotAllowed class, 475
HttpResponseNotFound class, 475
HttpResponseNotModified class, 475
HttpResponsePermanentRedirect class, 475
HttpResponseRedirect class, 131, 475
HttpResponseServerError class, 475
humanize package, 292
humanizing data, 306–307
NINDEX
488
I
i format character, 437
icontains field lookup, 124, 383
id keyword, 155
id primary-key fields, 318
iendswith field lookup, 384
iexact field lookup, 382
if tag, 50–52, 56, 185, 274, 433–434
ifchanged tag, 185, 434–435
ifconfig command, 19
ifequal tag, 55–56, 185, 435
ifnotequal tag, 55–56, 435
<iframe> tag, 304
IGNORABLE_404_ENDS setting, 421
IGNORABLE_404_STARTS setting, 422
ImageField field, 357–358
import datetime function, 30, 63
in field lookup, 383
in_bulk(id_list) method, 381
include( ) function, 163–165
include tag, 65–66, 175, 435–436
includes/nav.html template, 65
inclusion tags, 186
inclusion_tag( ) method, 187
inheritance, template, 66–69
__init__.py file, 18, 178
initial argument, 138
initial data, 138
initialization
sitemap framework, 250
syndication-feed framework, 243
initializer, 311
<input type="text"> tag, 137
inserting data, 86–87
inspectdb subcommand, 459
inspectdb utility, 317–318
INSTALLED_APPS setting, 80, 83, 177–178,
258–259, 264, 294, 306, 422
installing
Django, 12–14
middleware, 310–311
models, 80–83
Python, 12
ReportLab, 240
int( ) function, 34, 158
INT column, 318
intcomma filter, 306
IntegerField field, 136, 354, 358
INTERNAL_IPS setting, 172
internationalization
gettext, 339–340
JavaScript, 337–339
language files, creating, 330–332
language preference discovery, 333–335
overview, 323–324
set_language redirect view, 336
specifying translation strings, 324–330
introspecting, 78
intword filter, 306
invalid variable handling, 49
ip_address variable, 169–170
IPAddressField field, 358
iriencode filter, 446
is_active field, 265
is_anonymous( ) method, 265
is_authenticated( ) method, 162, 265, 269
is_paginated method, 399
is_secure( ) method, 471
is_staff field, 265
is_superuser field, 265
is_usable function, 188
is_valid( ) method, 135
isdigit( ) method, 47
isnull field lookup, 385
istartswith field lookup, 384
item_link( ) method, 245
items( ) method, 244, 259, 472
J
j format character, 437
JavaScript translations, 337–339
JavaScript validation, 127
javascript_catalog view, 337
join filter, 446
joining strings, 329
K
Keep-Alive feature, 233
KeyError class, 121, 123
keys( ) method, 122, 259
keyword arguments, 148–149, 161
kill command, 224
kwargs argument, 312
kwargs.pop( ) function, 161
L
L format character, 437
l format character, 437
-l option, 457, 461
<label> tags, 134
labels, specifying, 139
language, syndication-feed framework, 248
language codes, 331, 334
language files, creating, 330–332
NINDEX 489
language preference discovery, 333–335
LANGUAGE_BIDI variable, 328
LANGUAGE_CODE setting, 172, 328, 333, 422
LANGUAGE_COOKIE_NAME setting, 336
LANGUAGES setting, 172, 328, 334, 422
last filter, 447
last variable, 432
last_login field, 265
last_name field, 265
lastmod( ) method, 251
Last-Modified header, 282
latest variable, 403
latest_books( ) function, 6
latest_books.html file, 6
LatestEntries feed, 243
LatestEntriesByCategory feed, 243
latest(field_name=None) method, 381–382
lazy translation, 326–327, 329–330
ldconfig tool, 222
legacy database and application integration
authentication system, 319–321
databases, 317–319
overview, 317
Web applications, 321–322
len( ) method, 139
length filter, 57, 447
length_is filter, 447
Library instance, 179
Library.filter( )method, 179
lighttpd server, 225–227
limit_choices_to argument, 364
linebreaks filter, 447
linebreaksbr filter, 447
linenumbers filter, 447
link( ) method, 246
link.html template, 187
list( ) method, 374
list attribute, 439
list_display value, 108
list_filter value, 110
list/detail generic views
detail views, 400–401
lists of objects, 397–399
overview, 397
lists( ) method, 473
lists of objects, 397–399
ljust filter, 447
load balancer, 230
load balancing, implementing, 230–231
load tag, 178, 436
load_template_source template, 176–177,
189, 426
loaddata <fixture fixture...> subcommand,
459–460
loader.get_template( ) method, 170
loading templates
get_template( ) function, 64
locals( ) function, 63–64
overview, 60–62
render_to_response( ) function, 63
local checkout, 13
--locale option, 457–461
LocaleMiddleware class, 333, 335–336
localflavor package, 292
'localhost' value, 421
localization (L10N), 323
local-memory caching, 280
locals( ) function, 63–64
location( ) method, 251
Location blocks, 220
<Location> directive, 218, 321
<LocationMatch> directive, 220
'locmem://' value, 418
logging in and out, 267–268
login( ) method, 267
login screen, 97
login view, 268
login_url argument, 270
logout( ) method, 267
loosely coupled components, 6
lower filter, 448
low-level cache API, 284–286
lt field lookup, 383
lte field lookup, 383
M
m format character, 437
M format character, 437
'mail.cgi' value, 421
'mailform.cgi' value, 421
'mailform.pl' value, 421
'mail.pl' value, 421
make_list filter, 448
make_object_list argument, 404
makemessages subcommand, 461
managed meta option, 366–367
manage.py diffsettings command, 414
manage.py inspectdb command, 317
manage.py runfcgi command, 224
manage.py shell command, 42
manage.py sqlall books command, 195
manage.py sqlall command, 194
manage.py syncdb command, 264, 274, 294,
299, 302
manage.py utility, 18, 28, 217, 223, 415, 455
Manager object, 366, 372–373
NINDEX
490
managers
adding extra manager methods, 197–198
defined, 88
overview, 197
QuerySets, modifying initial, 198–199
MANAGERS setting, 215, 423
man-in-the-middle attacks, 258, 345–346
many-to-many fields, 113, 193, 196
many-to-many relationships, 102, 390–391
ManyToManyField class, 294, 298, 318,
364–365
markdown filter, 307
markup filters, 307
markup package, 292
match argument, 357
matching/grouping algorithm, 150
matplotlib library, 242
max_age parameter, 257
max_digits argument, 355
max_entries argument, 281
max_length argument, 137, 354
MaxRequestsPerChild 1 directive, 220
/media/ file, 225
media subdirectory, 220
'/media/' value, 418
MEDIA_ROOT setting, 355, 423
MEDIA_URL setting, 423
memcached back-end, 233–234
Memcached cache framework, 278–279
message field, 138
message files, 330–332
message system, 275–276
message template variable, 170
messages variable, 171
message.txt template, 297
META attribute, 470
method attribute, 469
method_splitter( ) function, 160
method-call behavior, 48–49
middleware
built-in, 313–315
defined, 309–310
installing, 310–311
methods, 311–313
overview, 309
MIDDLEWARE_CLASSES setting, 80, 258,
264, 281, 290, 301, 305, 310, 423
MiddlewareNotUsed class, 311
middleware.py file, 305
MIME types, 237–238
mimetype argument, 237, 395
min_length argument, 138
mod_* arrangements, 222
mod_access setting, 225
mod_accesslog setting, 225
mod_alias setting, 225
mod_fastcgi setting, 225
mod_proxy setting, 231
mod_python plug-in, 218–220, 416
mod_rewrite command, 224–225
mod_wsgi plug-in, 222
model definition reference
fields, 353–359
model metadata options, 365–368
overview, 353
relationships, 363–365
universal field options, 359–362
model metadata options, 365–368
model methods, 199–200
model parameter, 154
Model parent class, 79
ModelAdmin classes
change lists, 106–112
edit forms, 112–115
overview, 106
models
applications, 76–77
data access, 83–84
databases
configuring, 74–76
schema, making changes to, 193–196
defining in Python, 77–78
deleting objects, 93–94
inserting data, 86–87
installing, 80–83
managers, 197–199
model methods, 199–200
MTV and MVC development patterns,
72–74
related objects, 191–193
selecting objects
chaining lookups, 91
filtering data, 88–89
ordering data, 90–91
overview, 88
retrieving single objects, 89–90
slicing data, 92
updating multiple objects in one state-
ment, 92–93
SQL queries, 71–72, 200–201
string representations, 84–86
updating data, 86–87
models.py file, 6, 318, 363
Model-Template-View (MTV) development
pattern, 72–74
Model-View-Controller (MVC) development
pattern, 5–6, 72–74
month archives, 404–406
month argument, 405, 408, 410
month attribute, 46, 153
NINDEX 491
month field lookup, 384
"month" value, 377
month variable, 406
month_archive view, 150
MONTH_DAY_FORMAT setting, 423
month_format argument, 405, 408, 411
msgid line, 332
msgstr line, 332
MTV (Model-Template-View) development
pattern, 72–74
multiple view prefixes, 147
/music/ file, 302
MVC (Model-View-Controller) development
pattern, 5–6, 72–74
my_view( ) view, 152, 283
/myapp/ path, 158
/myblog/entries/add/path, 156
mypage.html file, 65
mysite directory, 18, 21, 42, 60, 218
mysite.fcgi file, 225, 227
mysite/myapp/models.py file, 318
mysite.settings setting, 219
mysite/settings.py project, 317
mysite/urls.py file, 28
mysite.views view, 58
mysite/views.py module, 24
mysite.zip_loader package, 189
MySpace, security, 344
MySQL, 17, 232, 460
mysql-python package, 17
mytemplate.html file, 59
N
n format character, 437
N format character, 437
'N j, Y, P' value, 420
'\n' string, 33
name argument, 179, 182
name field, 296, 298
__name__ attribute, 154
__name__.lower( ) function, 154
named groups, 148–150
named interpolation, 338
named pipe, 223
named regular expression groups, 148
named-string interpolation, 326
nav.html template, 65
never_cache view, 289
next field, 268
next variable, 399
next_day variable, 409
next_month variable, 406
ngettext interface, 338
Node class, 181–183
NodeList class, 184
nodes, 180
--noinput option, 458, 461–465
None value, 425, 453
non-HTML content generation
comma-separated values, 238–239
MIME types, 237–238
overview, 237
PDF, 239–241
sitemap framework, 249–253
syndication-feed framework, 242–248
views, 237–238
non-named regular expression groups, 148
--noreload option, 462
NOT NULL value, 104–105
now tag, 436–438
now variable, 30, 64
null field option, 359
NULL value, 104, 195
null=True option, 359
NullBooleanField field, 358
num value, 156
num_latest argument, 402
numeric fields, making optional, 104–105
O
O format character, 437
obj argument, 244, 246
object list view, 205
object variable, 401, 411
object_detail view function, 211, 400, 409
object_id argument, 400, 410
object_list variable, 154, 206, 210, 397, 399,
404, 406–407, 409
objects
creating, 370–371
deleting, 391–392
filtering
chaining filters, 374–375
limiting QuerySets, 375–376
overview, 373–374
QuerySet methods, 376–382
related, 387–391
retrieving, 372–373
saving changes to, 371–372
objects attribute, 88
official releases, 12–13
offset string, 34
offset variable, 34
one-to-many relationships, 388
OneToOneField relationship, 365
open( ) method, 59, 238
NINDEX
492
openblock argument, 441
openbrace argument, 441
opencomment argument, 441
openvariable argument, 441
or clause, 51
Oracle, 17
order_by( ) method, 90, 376
ordered_warranty variable, 41
ordering data, 90–91
ordering meta option, 367
ordering option, 91
ordinal filter, 307
os.environ['TZ'] variable, 427
P
P format character, 437
'P' value, 427
page( ) function, 156
page variable, 399
page_not_found view, 476
pages variable, 399
paginate_by argument, 398–399
pagination, 399
parent loop, 54
parentloop variable, 432
parse( ) method, 184–185
parser argument, 181
password argument, 267
password attribute, 271
password field, 265
passwords, changing, 271
patch_vary_headers decorator, 288
path argument, 357
path attribute, 257, 469
patterns( ) function, 23, 146
PDF (Portable Document Format), generat-
ing, 239–241
percent signs (%), 383
performance tuning, 232–234
permission_required( ) method, 270
permissions, 116, 264, 274–275
permissions field, 266
perms variable, 171
persistent sessions, 262–263
per-site cache, 281–282
{{ person.name.upper }} variable, 48
per-view cache, 282–283
phishing, 344
phone2numeric filter, 448
Photo.on_site.all( ) method, 297
'.php' value, 421
pickle module, 263, 279
$PIDFILE file, 224
pidfile option, 224
ping_google( ) method, 253
pinging Google, 253
pk lookup shortcut, 385
pkg_resources module, 188
--plain option, 463
"Please submit a search term." message, 125
plots, 242
plural tag, 328
pluralization, 327
pluralize filter, 125, 448
.po files, 331, 334, 337, 339
port daemon, 278
port property, 223
Portable Document Format (PDF), generat-
ing, 239–241
positional arguments, 161
positional interpolation, 326, 338
PositiveIntegerField field, 358
PositiveSmallIntegerField field, 358
POST attribute, 124, 131, 158, 160, 304–305,
470
post_save signal, 370
PostgreSQL, 15–16, 232
pprint filter, 448
pre_save signal, 370
PREPEND_WWW setting, 313, 424
presentation logic, 58, 73
previous variable, 399
previous_day variable, 409
previous_month variable, 406
primary keys, autoincrementing, 370–371
primary_key field option, 362
print statements, 37, 220
printing, 374
priority( ) method, 251
process_exception( ) method, 312
process_request(self, request) method, 311
process_response( ) method, 312
process_view(self, request, view, args,
kwargs), 311–312
processors argument, 169
project directory, 19
projects
defined, 76
overview, 17–18
running development server, 18–19
proxy cache, 286
proxy meta option, 368
psycopg package, 16
psycopg2 package, 16
psycopg2-python package, 16
publish_on field, 298
Publisher class, 79, 84
pyexpat module, 221
NINDEX 493
pygraphviz library, 242
pysqlite package, 16
Python
defining models in, 77–78
manipulating flatpages via, 301
manipulating redirects via, 303
overview, 11–12
programming language, 8–9
specifying translation strings in, 324–327
python command, 12, 14, 42
Python Imaging Library, 358
Python interactive interpreter program, 14
python manage.py dbshell command, 83
python manage.py runserver command, 22,
25, 28, 62
python manage.py shell command, 42, 83
python mysite/manage.py inspectdb com-
mand, 318
python mysite/manage.py startapp myapp
command, 318
python setup.py install command, 14
PythonAutoReload directive, 219
PythonDebug directive, 219
PythonInterpreter directive, 219
python-memcached module, 278
python-mysql package, 17
python-mysqldb package, 17
--pythonpath option, 466
python-postgresql package, 16
python-psycopg2 package, 16
python-sqlite3 package, 16
Q
Q objects, 385–386
q value, 123
QueryDict object, 471–473
queryset argument, 208–209, 395, 398, 400,
402–403, 405, 407–408, 410
QuerySet object
caching and, 373
limiting, 375–376
modifying initial, 198–199
QuerySet methods that do not return,
379–382
QuerySet methods that return new,
376–379
query-string parameters, 124
R
r format character, 437
rainbow tables, 272
RAM, performance tuning, 233
random filter, 449
range field lookup, 384
raw_id_fields option, 115
raw_post_data attribute, 471
raw_template variable, 44
recursive argument, 357
redirect_to view function, 397
RedirectFallbackMiddleware class, 302
redirects framework, 302–303
redirects object, 309
redirects package, 292
redundancy, 151, 230–231
Referer header, 263
register variable, 178
register.tag argument, 182
registration, 272–273
registration_required field, 300
registration/logged_out.html directory, 268
registration/login.html directory, 268
registration/register.html template, 273
regroup tag, 438–439
regular expression, 26
related objects
foreign-key relationships, 192, 387–388
lookups that span relationships, 387
many-to-many relationships, 193, 390–391
overview, 191–192, 387
queries over, 391
"reverse" foreign-key relationships,
388–390
related_name argument, 364
relationships
ForeignKey, 363–364
ManyToManyField, 364–365
OneToOneField, 365
REMOTE_ADDR key, 120
remove(obj1, obj2, ...) method, 390
removetags filter, 449
render( ) method, 41, 43, 45, 180, 182–183,
185
render_to_response( ) method, 63, 131,
169–170
ReportLab library, 239–241
repr( ) method, 374
request argument, 312
REQUEST attribute, 470
request object, 34, 119–122, 312
request parameter, 22
request preprocessor method, 311
request variable, 119
RequestContext class, 168–173, 300
request.GET attribute, 121–124, 131
request.get_full_path( ) method, 120
request.get_host( ) method, 120
request.is_secure( ) method, 120
NINDEX
494
request.META key, 120, 310
request.META['HTTP_X_FORWARDED_
FOR'] function, 314
request.META['REMOTE_ADDR'] function,
314
request.method attribute, 131, 160
request.path attribute, 120–121
request.POST attribute, 121–122, 124, 131
requests, processing, 28
request.session attribute, 259, 309
request.session.set_test_cookie( ) method,
261
request.session.test_cookie_worked( )
method, 261
request.user attribute, 269, 309, 313
requires_login function, 162
reset <appname appname ...> subcommand,
461
reset management command, 366
resource contention, 228
response object, 312
response postprocessor method, 312
restrictions, model field names, 353
restructuredtext filter, 307
results_per_page variable, 399
retrieving objects, 89–90, 372–373
"reverse" foreign-key relationships, 388–390
reverse proxy support (X-forwarded-for
middleware), 314–315
reverse relationships, 391
revision number, 14
rjust filter, 449
r'\n' string, 33
ROLLBACK database, 315
ROOT_URLCONF setting, 28, 60, 217, 424
row-level functionality, 197
RSS feeds, 242, 248
run_tests function, 426
runfcgi command, 223, 462
runserver command, 18–19, 30, 123, 213,
462–463
S
S format character, 437
s format character, 437
safe filter, 174, 176, 449
safeseq filter, 449
salted hashes, 271–272
save( ) method, 84, 87, 93, 241, 370–372
saving changes to objects, 371–372
scaling
load balancing, implementing, 230–231
overview, 228
redundancy, implementing, 230–231
running on single server, 228
running separate media server, 229–230
separating out database server, 229
schema_path argument, 359
<script> tags, 343
search( ) method, 125, 127, 130
search bar, 109
search field lookup, 385
/search/ file, 123, 126
search_form( ) method, 125–126
search_form.html template, 122, 125–126,
128, 130
search_results.html template, 124
SECRET_KEY setting, 424
/sections/arts/music/ file, 302
secure parameter, 257
security
cross-site request forgery, 345
cross-site scripting, 343–345
directory traversal, 347–349
e-mail header injection, 347
exposed error messages, 349
overview, 341–342
session forging/hijacking, 345–346
settings, 414
SQL injection, 342–343
segmentation fault handling, 221–222
select_related( ) method, 378–379
select_template(template_name_list) tem-
plate, 176
selecting objects
chaining lookups, 91
filtering data, 88–89
ordering data, 90–91
overview, 88
retrieving single objects, 89–90
slicing data, 92
updating multiple objects in one state-
ment, 92–93
self.cleaned_data argument, 139
SEND_BROKEN_LINK_EMAILS setting, 215,
424
send_mail( ) method, 137
SERIALIZATION_MODULES setting, 424
SERVER_EMAIL setting, 424
server_error view, 477
session attribute, 259, 471
session fixation, 346
session forging, 345–346
NINDEX 495
session hijacking, 345–346
session poisoning, 346
session riding (CSRF), 304–306, 345
session support middleware, 315
SESSION_COOKIE_AGE setting, 424
SESSION_COOKIE_DOMAIN setting, 263,
425
SESSION_COOKIE_NAME setting, 263, 425
SESSION_COOKIE_SECURE setting, 263, 425
SESSION_EXPIRE_AT_BROWSER_CLOSE
setting, 262, 425
SESSION_SAVE_EVERY_REQUEST setting,
262, 425
'sessionid' value, 425
SessionMiddleware class, 264, 305, 315
sessions
browser-length vs. persistent, 262–263
enabling, 258–259
overview, 258
saving, 262
setting test cookies, 261
using in views, 259–260
using outside of views, 261–262
sessions package, 292
set( ) method, 285
set_cookie( ) method, 256–257
set_language redirect view, 336
set_password( ) function, 271
set_password(passwd) method, 266
set_test_cookie( )method, 261
Set-Cookie header, 256
__setitem__ method, 472
setlistdefault(key, a) method, 473
setlist(key, list_) method, 472
SetRemoteAddrFromForwardedFor class,
314
settings
altering at runtime, 414
available, 417–428
creating, 415
default, 413–414
designating
with DJANGO_SETTINGS_MODULE,
415–416
without DJANGO_SETTINGS_
MODULE, 416–417
overview, 413
in Python code, 414
security, 414
settings command-line argument, 415
settings file, 28, 60
--settings option, 464, 466
settings_production.py file, 216–217
settings.py file, 18, 28, 30, 60–61, 213, 216, 320
settings.SITE_ID setting, 295
setup.py utility, 12, 18
shell subcommand, 463
showPage( ) method, 241
silent_variable_failure attribute, 48
"simple" generic views, 396–397
simple_tag function, 185–186
site context variable, 244
site field, 298, 300
Site object, 293, 295, 297, 299
site root, 27
SITE_ID setting, 293–294, 297–298, 300, 302,
425
Sitemap class, 250–251
sitemap framework
initialization, 250
installation, 249
overview, 249
pinging Google, 253
shortcuts, 251–252
Sitemap classes, 250–251
sitemap index, 252–253
sitemaps package, 292
sitemap.xml file, 250
site-packages directory, 13
sites framework
capabilities of, 294–297
CurrentSiteManager model manager,
297–298
how Django uses, 298–299
overview, 293
reusing data on multiple sites, 293
storing site name/domain in one place,
293
using, 293–294
sites package, 292
sitewide cache middleware, 315
slice filter, 449
slicing data, 92, 374
slug argument, 400, 410
slug_field argument, 400, 411
SlugField field, 358
slugify filter, 450
SmallIntegerField field, 358
snooping attacks, 258
socket module, 217
socket property, 223
some_page( ) function, 159
some_page_get( ) function, 160
some_page_post( ) function, 160
/somepage/ path, 159–160
spaceless tag, 440
special-casing URLs, 148
special-casing views, 156–157
NINDEX
496
split( ) method, 139
split_contents( ) method, 181
sql <appname appname ...> subcommand,
463
SQL injection, 342–343
SQL queries, 71–72, 200–201
SQL reserved words, 353
sql_queries variable, 171
sqlall <appname appname ...> subcommand,
463
sqlall command, 83
sqlclear <appname appname ...> subcom-
mand, 463
sqlcustom <appname appname ...> subcom-
mand, 464
sqlflush subcommand, 464
sqlindexes <appname appname ...> subcom-
mand, 464
SQLite, 16, 74
sqlite-python package, 16
sqlreset <appname appname ...> subcom-
mand, 464
sqlsequencereset <appname appname ...>
subcommand, 464
Squid, 277
ssi tag, 440
staff flag, 116
standalone mode, 189–190
standard library, 291–292
startapp <appname> subcommand, 464
startproject <projectname> subcommand,
464
startproject command, 18, 259
startswith field lookup, 384
stateless, defined, 255
storing templates in subdirectories, 64
strftime syntax, 180, 355
string literals, 176
string representations, 84–86
string_concat( ) function, 329
stringformat filter, 450
striptags filter, 450
subdirectories, storing templates in, 64
subject field, 138
subject.txt template, 297
superuser flag, 116
superusers, 96–97, 116
svn co command, 13
svn update command, 14
svn --version command, 13
symmetrical argument, 364
syncdb command, 83, 193, 464–465
syndication package, 292
syndication-feed framework
enclosures, 247
feeds, 244–247
initialization, 243
language, 248
overview, 242–243
publishing Atom and RSS feeds in tandem,
248
URLs, 248
syntax coloring, 467
T
t format character, 437
T format character, 437
table names, 82
<table> tag, 134
table-level functionality, 197
tablename database table, 279
tag( ) method, 182
tags
autoescape, 429
block, 429
comment, 429
cycle, 430
debug, 431
extends, 431
filter, 431
firstof, 431
for, 432–433
if, 433–434
ifchanged, 434–435
ifequal, 435
ifnotequal, 435
include, 435–436
inclusion, 186–188
load, 436
now, 436–438
overview, 429
parsing until another, 184–185
registering, 182
regroup, 438–439
shortcut for, 185–186
spaceless, 440
ssi, 440
template, 50–56, 65–66
templatetag, 440
url, 441
widthratio, 441
with, 442
writing custom, 180
takes_context option, 187
.tar.gz files, 12
NINDEX 497
Template( ) method, 43
template argument, 396
template fragment caching, 284
template inheritance, 59
template loading, 59, 176–177, 188–189
Template object, 41–43, 61
template tag, 41, 43, 167, 181
TEMPLATE_CONTEXT_PROCESSORS set-
ting, 170–172, 273, 425
TEMPLATE_DEBUG setting, 190, 214, 426
TEMPLATE_DIRS setting, 28, 60, 69, 176, 188,
190, 426
template_loader argument, 396
TEMPLATE_LOADERS setting, 176–177,
188–189, 249, 426
template_name argument, 65, 152, 156, 188,
300–301, 396
template_name_field argument, 400, 411
template_object_name argument, 207, 396
TEMPLATE_STRING_IF_INVALID setting,
426
TEMPLATE_ZIP_FILES setting, 188
TemplateDoesNotExist exception, 62, 66,
176, 205
template.Library directory, 178, 182
templates
authentication data, using in, 273–274
automatic HTML escaping, 173–176
comments, 56
configuring system in standalone mode,
189–190
Context objects, 49–50
context processors, 168–172
context variable lookup, 46–49
custom loaders, 188–189
extending system
creating library, 177–178
inclusion tags, 186–188
overview, 177
parsing until another template tag,
184–185
registering tags, 182
setting variable in context, 183–184
shortcut for tags, 185–186
writing compilation function, 180–181
writing custom filters, 178–179
writing custom tags, 180
writing node, 182
filters, 56–57
flatpages, 301–302
inheritance, 66–69
limitations, 57–58
loading, 60–64, 176–177
overview, 39–42, 167
philosophies, 57–58
rendering, 43–45
rendering multiple contexts through,
45–46
RequestContext subclass, 168–172
tags, 50–56, 65–66
Template objects, creating, 42–43
terminology, 167–168
using in views, 58–59
templates subdirectory, 177
TemplateSyntaxError class, 43, 47, 52
templatetag tag, 440
templatetags directory, 177–178
test subcommand, 465
test_cookie_worked( ) method, 261
TEST_DATABASE_NAME setting, 426
TEST_RUNNER setting, 426
testing Django installation, 14
testserver <fixture fixture ...> subcommand,
465
<textarea> tag, 137
TextField field, 358
'text/html' value, 420
textile filter, 307
through argument, 364
time filter, 450
/time/ path, 30–35
TIME_FORMAT setting, 427
TIME_ZONE setting, 427
TimeField field, 358
timeout argument, 281, 285
timeout_seconds argument, 285
/time/plus/1/ path, 31
/time/plus/2/ path, 31–32
/time/plus/3/ path, 31, 34–35
/time/plus/21/ path, 34
/time/plus/25/ path, 32
/time/plus/100000000000/ path, 32
/time/plus?hours=3 path, 32
timesince filter, 451
timeuntil filter, 451
TINYINT column, 354
title( ) method, 246
title field, 299–300
title filter, 451
<title> header, 67
today archives, 409
token argument, 181
token.contents string, 181
touch command, 227
--traceback option, 466
tracebacks, exposed, 349
trans tag, 327
transaction middleware, 315
NINDEX
498
TransactionMiddleware class, 315
translation strings, 323
True value, 418, 428, 453
truncatewords filter, 451
truncatewords_html filter, 451
trunk version, 12–14
two periods (..), 347
U
ugettext( ) function, 324–325, 334
ugettext_lazy( ) function, 326
ugettext_noop( ) function, 326
<ul class="errorlist"> tag, 140
<ul> tag, 134
underscores (_), 383
ungettext( ) function, 327
Unicode objects, 86
__unicode__( ) method, 85, 106
unique field option, 362
unique_for_date field option, 362
unique_for_month field option, 362
unique_for_year field option, 362
unique_together meta option, 368
universal field options, 359–362
unordered_list filter, 452
update( ) method, 93, 472
UpdateCacheMiddleware class, 281, 290, 315
upload_to option, 356
upper( ) method, 47
upper filter, 452
upper tag, 185
UpperNode.render( ) method, 185
upstream caches, 286–287
url argument, 397
url field, 300
url tag, 441
URL_VALIDATOR_USER_AGENT setting, 427
URLconfs
capturing text in URLs, 157–158
determining what URLconf searches
against, 158
Django error pages, 35–37
Django page, 21–27
include( ) method, 163–165
loose coupling, 31
matching/grouping algorithm, 150
named groups, 148–150
overview, 21, 145
request processing, 28
special-casing URLs in debug mode, 148
specifying in per-view cache, 283
view functions
higher-level abstractions of, 158–161
passing extra options to, 150–155
streamlining imports, 145–147
wrapping, 161–162
urlencode( ) method, 473
urlencode filter, 452
URLField field, 359
urlize filter, 452
urlizetrunc filter, 453
urlpatterns function, 24, 147–148
URLs
capturing text in, 157–158
special-casing in debug mode, 148
syndication-feed framework, 248
urls.py command, 6, 18, 28, 96
USE_ETAGS setting, 314, 427
USE_I18N setting, 324, 428
user attribute, 471
user change-list page, 99
user comment system (django.contrib.
comments), 95
user edit form, 99
User object, 266–267
user variable, 55, 169–171
user_add_stage view, 157
user_passes_test permission, 270
user-authentication system (django.contrib.
auth), 95
--username argument, 457
username field, 265
username variable, 164
users
admin site, 116
creating, 271
limiting access to, 269–270
using, 265–266
/usr/local/bin directory, 18
'utf-8' value, 420
V
validate command, 81, 465
validation, 127–128, 137–139
ValidationError argument, 139
ValueError class, 34, 158, 286
values( ) method, 122, 377, 472
varchar(100) columns, 357–358
variable tag, 174
variable value, 431
/var/tmp/django_cache directory, 279
Vary headers, 287–288
NINDEX 499
vary_on_cookie decorator, 288
vary_on_headers( ) method, 287–288
verbose_name option, 105–106, 139, 327, 362,
368
verbose_name_plural option, 327, 368
--verbosity option, 456, 466
verify_exists argument, 359
version determination, 456
--version option, 456
view argument, 312
view functions
higher-level abstractions of, 158–161
passing extra options to, 150–155
streamlining imports, 145–147
wrapping, 161–162
view preprocessor method, 311–312
views
Django error pages, 35–37
Django page, 21–27
non-HTML content generation, 237–241
overview, 21
second view, 28–30
third view, 31–35
using sessions in, 259–260
using sessions outside of, 261–262
using templates in, 58–59
views module, 123, 145
views.page view, 156
views.py file, 6, 21–22, 29, 35, 133
views.year_archive( ) function, 157
VirtualHost class, 219–220
'/_vti_bin' value, 422
'/_vti_inf' value, 422
W
w format character, 437
W format character, 437
Web applications, legacy, 321–322
Web frameworks, 3–5
webdesign package, 292
/weblog/2007/ path, 163
'webmaster@localhost' value, 420
week archives, 406–407
week argument, 407
where argument, 343
whitespace, 440, 450
width_field argument, 357
widthratio tag, 441
wildcard URLpatterns, 32
with tag, 442
wordcount filter, 453
wordwrap filter, 453
wrapper functions, 210
wrapping, 147, 161–162
X
X-Forwarded-For header, 309–310
X-forwarded-for middleware (reverse proxy
support), 314–315
XMLField field, 359
XSS (cross-site scripting), 173, 343–345
Y
y format character, 437
Y format character, 437
year archives, 403–404
year argument, 46, 157, 403–405, 407–408,
410
year field lookup, 384
"year" value, 377
YEAR_MONTH_FORMAT setting, 428
yesno filter, 453
Z
z format character, 437
Z format character, 437
ZIP files, 242

Navigation menu