The Django Book User Manual
User Manual: Pdf
Open the PDF directly: View PDF .
Page Count: 424
Download | |
Open PDF In Browser | View PDF |
The Django Book Release 2.0 Adrian Holovaty, Jacob Kaplan-Moss, et al. May 08, 2014 Contents 1 About this book 1.1 Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 About the Authors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3 About the Technical Reviewer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3 4 4 2 Introduction 5 3 Chapter 1: Introduction to Django 3.1 What Is a Web Framework? . 3.2 The MVC Design Pattern . . 3.3 Django’s History . . . . . . . 3.4 How to Read This Book . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 7 8 10 11 Chapter 2: Getting Started 4.1 Installing Python . . . . . . . 4.2 Installing Django . . . . . . . 4.3 Testing the Django installation 4.4 Setting Up a Database . . . . 4.5 Starting a Project . . . . . . . 4.6 What’s Next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 13 14 16 16 18 20 Chapter 3: Views and URLconfs 5.1 Your First Django-Powered Page: Hello World 5.2 How Django Processes a Request . . . . . . . 5.3 Your Second View: Dynamic Content . . . . . 5.4 URLconfs and Loose Coupling . . . . . . . . 5.5 Your Third View: Dynamic URLs . . . . . . . 5.6 Django’s Pretty Error Pages . . . . . . . . . . 5.7 What’s next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 21 27 27 29 30 33 34 Chapter 4: Templates 6.1 Template System Basics . . . . 6.2 Using the Template System . . 6.3 Basic Template Tags and Filters 6.4 Philosophies and Limitations . 6.5 Using Templates in Views . . . 6.6 Template Loading . . . . . . . 6.7 Template Inheritance . . . . . . 6.8 What’s next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 35 36 43 49 50 51 55 58 4 5 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i 7 Chapter 5: Models 7.1 The “Dumb” Way to Do Database Queries in Views 7.2 The MTV (or MVC) Development Pattern . . . . . 7.3 Configuring the Database . . . . . . . . . . . . . . 7.4 Your First App . . . . . . . . . . . . . . . . . . . . 7.5 Defining Models in Python . . . . . . . . . . . . . . 7.6 Your First Model . . . . . . . . . . . . . . . . . . . 7.7 Installing the Model . . . . . . . . . . . . . . . . . 7.8 Basic Data Access . . . . . . . . . . . . . . . . . . 7.9 Adding Model String Representations . . . . . . . . 7.10 Inserting and Updating Data . . . . . . . . . . . . . 7.11 Selecting Objects . . . . . . . . . . . . . . . . . . . 7.12 Deleting Objects . . . . . . . . . . . . . . . . . . . 7.13 What’s Next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Chapter 6: The Django Admin Site 8.1 The django.contrib packages . . . . . . . . . . . . . . . . . . . 8.2 Activating the Admin Interface . . . . . . . . . . . . . . . . . 8.3 Using the Admin Site . . . . . . . . . . . . . . . . . . . . . . 8.4 Adding Your Models to the Admin Site . . . . . . . . . . . . . 8.5 How the Admin Site Works . . . . . . . . . . . . . . . . . . . 8.6 Making Fields Optional . . . . . . . . . . . . . . . . . . . . . 8.7 Customizing Field Labels . . . . . . . . . . . . . . . . . . . . 8.8 Custom ModelAdmin classes . . . . . . . . . . . . . . . . . . 8.9 Users, Groups, and Permissions . . . . . . . . . . . . . . . . . 8.10 When and Why to Use the Admin Interface – And When Not to 8.11 What’s Next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 . 81 . 81 . 82 . 89 . 89 . 90 . 92 . 92 . 102 . 102 . 103 Chapter 7: Forms 9.1 Getting Data From the Request Object . . . . . 9.2 A Simple Form-Handling Example . . . . . . . 9.3 Improving Our Simple Form-Handling Example 9.4 Simple validation . . . . . . . . . . . . . . . . . 9.5 Making a Contact Form . . . . . . . . . . . . . 9.6 Your First Form Class . . . . . . . . . . . . . . 9.7 Tying Form Objects Into Views . . . . . . . . . 9.8 Changing How Fields Are Rendered . . . . . . . 9.9 Setting a Maximum Length . . . . . . . . . . . 9.10 Setting Initial Values . . . . . . . . . . . . . . . 9.11 Custom Validation Rules . . . . . . . . . . . . . 9.12 Specifying labels . . . . . . . . . . . . . . . . . 9.13 Customizing Form Design . . . . . . . . . . . . 9.14 What’s Next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105 105 107 110 111 113 116 118 119 120 120 120 121 121 123 10 Chapter 8: Advanced Views and URLconfs 10.1 URLconf Tricks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.2 Including Other URLconfs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10.3 What’s Next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125 125 139 142 11 Chapter 9: Advanced Templates 11.1 Template Language Review . . . . . . 11.2 RequestContext and Context Processors 11.3 Automatic HTML Escaping . . . . . . 11.4 Inside Template Loading . . . . . . . . 11.5 Extending the Template System . . . . 143 143 144 148 150 151 9 ii . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 61 62 63 65 66 67 68 71 72 73 74 79 80 . . . . . . . . . . . . . 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.6 Writing Custom Template Loaders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160 11.7 Configuring the Template System in Standalone Mode . . . . . . . . . . . . . . . . . . . . . . . . . 161 11.8 What’s Next . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 12 Chapter 10: Advanced Models 12.1 Related Objects . . . . . . . . . . . . . 12.2 Making Changes to a Database Schema 12.3 Managers . . . . . . . . . . . . . . . . 12.4 Model methods . . . . . . . . . . . . . 12.5 Executing Raw SQL Queries . . . . . . 12.6 What’s Next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163 163 165 167 170 171 171 13 Chapter 11: Generic Views 13.1 Using Generic Views . . . 13.2 Generic Views of Objects 13.3 Extending Generic Views 13.4 What’s Next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 173 174 176 180 14 Chapter 12: Deploying Django 14.1 Preparing Your Codebase for Production . . 14.2 Using Different Settings for Production . . . 14.3 DJANGO_SETTINGS_MODULE . . . . . 14.4 Using Django with Apache and mod_python 14.5 Using Django with FastCGI . . . . . . . . . 14.6 Scaling . . . . . . . . . . . . . . . . . . . . 14.7 Performance Tuning . . . . . . . . . . . . . 14.8 What’s Next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181 181 183 185 185 188 193 198 199 15 Chapter 13: Generating Non-HTML Content 15.1 The basics: views and MIME-types . . . 15.2 Producing CSV . . . . . . . . . . . . . . 15.3 Generating PDFs . . . . . . . . . . . . . 15.4 Other Possibilities . . . . . . . . . . . . 15.5 The Syndication Feed Framework . . . . 15.6 The Sitemap Framework . . . . . . . . . 15.7 What’s Next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 201 202 203 205 205 211 215 16 Chapter 14: Sessions, Users, and Registration 16.1 Cookies . . . . . . . . . . . . . . . . . . . 16.2 Django’s Session Framework . . . . . . . 16.3 Users and Authentication . . . . . . . . . 16.4 Permissions, Groups and Messages . . . . 16.5 What’s Next . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217 217 219 224 232 234 17 Chapter 15: Caching 17.1 Setting Up the Cache . . . . . . . . . . . 17.2 The Per-Site Cache . . . . . . . . . . . . 17.3 The Per-View Cache . . . . . . . . . . . 17.4 Template Fragment Caching . . . . . . . 17.5 The Low-Level Cache API . . . . . . . . 17.6 Upstream Caches . . . . . . . . . . . . . 17.7 Using Vary Headers . . . . . . . . . . . 17.8 Controlling Cache: Using Other Headers 17.9 Other Optimizations . . . . . . . . . . . 17.10 Order of MIDDLEWARE_CLASSES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235 235 238 239 240 241 242 243 244 245 245 . . . . . . . . . . iii 17.11 What’s Next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 246 18 Chapter 16: django.contrib 18.1 The Django Standard Library 18.2 Sites . . . . . . . . . . . . . 18.3 Flatpages . . . . . . . . . . . 18.4 Redirects . . . . . . . . . . . 18.5 CSRF Protection . . . . . . . 18.6 Humanizing Data . . . . . . . 18.7 Markup Filters . . . . . . . . 18.8 What’s Next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247 247 248 253 256 257 259 260 260 19 Chapter 17: Middleware 19.1 What’s Middleware? . . 19.2 Middleware Installation 19.3 Middleware Methods . . 19.4 Built-in Middleware . . 19.5 What’s Next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263 263 264 264 266 268 20 Chapter 18: Integrating with Legacy Databases and Applications 20.1 Integrating with a Legacy Database . . . . . . . . . . . . . . . 20.2 Integrating with an Authentication System . . . . . . . . . . . 20.3 Integrating with Legacy Web Applications . . . . . . . . . . . 20.4 What’s Next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269 269 271 272 273 21 Chapter 19: Internationalization 21.1 1. How to Specify Translation Strings . . . . . . 21.2 2. How to Create Language Files . . . . . . . . 21.3 3. How Django Discovers Language Preference . 21.4 Using Translations in Your Own Projects . . . . 21.5 The set_language Redirect View . . . . . . 21.6 Translations and JavaScript . . . . . . . . . . . 21.7 Notes for Users Familiar with gettext . . . . 21.8 gettext on Windows . . . . . . . . . . . . . 21.9 What’s Next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275 276 280 282 284 285 286 287 288 288 22 Chapter 20: Security 22.1 The Theme of Web Security 22.2 SQL Injection . . . . . . . 22.3 Cross-Site Scripting (XSS) . 22.4 Cross-Site Request Forgery 22.5 Session Forging/Hijacking . 22.6 E-mail Header Injection . . 22.7 Directory Traversal . . . . . 22.8 Exposed Error Messages . . 22.9 A Final Word on Security . 22.10 What’s Next? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289 289 289 291 292 292 294 294 295 296 296 23 Appendix A: Model Definition Reference 23.1 Fields . . . . . . . . . . . . . . . . . 23.2 Universal Field Options . . . . . . . 23.3 Relationships . . . . . . . . . . . . . 23.4 Model Metadata Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297 297 302 305 307 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 Appendix B: Database API Reference iv . . . . . . . . . . 311 24.1 24.2 24.3 24.4 24.5 24.6 24.7 24.8 24.9 24.10 24.11 Creating Objects . . . . . . . . . Saving Changes to Objects . . . . Retrieving Objects . . . . . . . . Caching and QuerySets . . . . . Filtering Objects . . . . . . . . . Field Lookups . . . . . . . . . . Complex Lookups with Q Objects Related Objects . . . . . . . . . . Deleting Objects . . . . . . . . . Shortcuts . . . . . . . . . . . . . Falling Back to Raw SQL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311 313 314 314 315 322 325 326 330 330 331 25 Appendix C: Generic View Reference 25.1 Common Arguments to Generic Views 25.2 “Simple” Generic Views . . . . . . . . 25.3 List/Detail Generic Views . . . . . . . 25.4 Date-Based Generic Views . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 333 333 334 335 338 26 Appendix D: Settings 26.1 What’s a Settings File? . . . . . . . . . . . . . . . . . . . . . . . . 26.2 Designating the Settings: DJANGO_SETTINGS_MODULE . . . . 26.3 Using Settings Without Setting DJANGO_SETTINGS_MODULE . 26.4 Available Settings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 349 349 350 351 353 27 Appendix E: Built-in Template Tags and Filters 365 27.1 Built-in Tag Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365 27.2 Built-in Filter Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376 28 Appendix F: The django-admin Utility 28.1 Usage . . . . . . . . . . . . . . . . 28.2 Available subcommands . . . . . . 28.3 Default options . . . . . . . . . . . 28.4 Extra niceties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389 389 390 398 399 29 Appendix G: Request and Response Objects 401 29.1 HttpRequest . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401 29.2 HttpResponse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406 30 License & Copyright 411 30.1 GNU Free Documentation License . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411 v vi The Django Book, Release 2.0 Welcome to the online version of The Django Book, a free book about the Django Web framework for the Python programming language. A warning about this edition The community edition of The Django Book is in transition. While the book mentions Django version 1.4 in places, the vast majority of the book is for Django version 1.0, which was released over four years ago. Therefore this resource is extremely out of date and, until the book is finished being updated, we ask that, at this time, djangobook.com not be used for educational purposes. This book was originally published by Apress in 2009 and covered Django version 1.0. Since then it has languished and, in places, is extremely out of date. We are working on getting the book updated to cover Django versions 1.4, 1.5, and beyond. But we need your help, we’re making this book — warts and all — open source in the hopes that it will find love as a community project. So, if you’d like to help out, hop on over to GitHub and send us a pull request! Contents 1 The Django Book, Release 2.0 2 Contents CHAPTER 1 About this book You’re reading The Django Book, first published in December 2007 (and updated in 2009) by Apress as The Definitive Guide to Django: Web Development Done Right. We’ve released this book freely for a couple of reasons. First, we love Django and we want it to be as accessible as possible. Many programmers learn their craft from well-written technical material, so we set out to create a top-notch guide and reference to Django. Second, it turns out that writing books about technology is fundamentally difficult: your words are often outdated before the book even reaches the printer. On the web, however, “the ink is never dry” — we can (and will!) keep the book updated. 1.1 Acknowledgements The most gratifying aspect of working on Django is the community. We’ve been especially lucky that Django has attracted such a smart, motivated, and friendly bunch. A segment of that community followed us over to the online “beta” release of this book. Their reviews and comments were indispensable; this book wouldn’t have been possible without all that wonderful peer review. Almost a thousand people left comments that helped us improve the clarity, quality, and flow of the final book; we’d like to thank each and every one of them. We’re especially grateful to those who took the time to review the book in depth and left dozens (sometimes hundreds) of comments apiece: Marty Alchin, Max Battcher, Oliver Beat- tie, Rod Begbie, Paul Bissex, Matt Boersma, Robbin Bonthond, Peter Bowyer, Nesta Campbell, Jon Colverson, Jeff Croft, Chris Dary, Alex Dong, Matt Drew, Robert Dzikowski, Nick Efford, Ludvig Ericson, Eric Floehr, Brad Fults, David Grant, Simon Greenhill, Robert Haveman, Kent Johnson, Andrew Kember, Marek Kubica, Eduard Kucera, Anand Kumria, Scott Lamb, Fredrik Lundh, Vadim Macagon, Markus Majer, Orestis Markou, R. Mason, Yasushi Masuda, Kevin Menard, Carlo Miron, James Mulholland, R.D. Nielsen, Michael O’Keefe, Lawrence Oluyede, Andreas Pfrengle, Frankie Robertson, Mike Robinson, Armin Ronacher, Daniel Roseman, Johan Samyn, Ross Shannon, Carolina F. Silva, Paul Smith, Björn Stabell, Bob Stepno, Graeme Stevenson, Justin Stockton, Kevin Teague, Daniel Tietze, Brooks Travis, Peter Tripp, Matthias Urlichs, Peter van Kampen, Alexandre Vassalotti, Jay Wang, Brian Will, and Joshua Works. Many thanks to our technical editor, Jeremy Dunck. Without Jeremy this book would be littered with errors, inaccuracies, and broken code. We feel very lucky that someone as talented as Jeremy found the time to help us out. Specials thanks go to Simon Willison for writing the chapter on form processing. We really appreciate the help, and we’re thrilled that Simon’s excellent writing can be part of this book. We’re grateful for all the hard work the folks at Apress put into this book. They’ve been amazingly supportive and patient; this book wouldn’t have come together without a lot of work on their part. We’re especially happy that Apress supported and even encouraged the free release of this book online; it’s wonderful seeing a publisher so embracing the spirit of open source. 3 The Django Book, Release 2.0 Finally, of course, thanks to our friends, families, and coworkers who’ve graciously tolerated our mental absence while we finished this work. 1.2 About the Authors Adrian Holovaty is a Web developer with a background in journalism. He’s known in journalism circles as one of the pioneers of “journalism via computer programming”, and in technical circles as “the guy who invented Django.” He was lead developer at World Online for 2.5 years, during which time Django was developed and implemented on World Online’s sites. He’s the founder of EveryBlock, a “news feed for your block”. Adrian lives in Chicago, USA. Jacob Kaplan-Moss is a partner at Revolution Systems which provides support services around Django and related open source technologies. Jacob previously worked at World Online, where Django was invented, where he was the lead developer of Ellington, a commercial Web publishing platform for media companies. Jacob lives in Lawrence, Kansas, USA. 1.3 About the Technical Reviewer Jeremy Dunck was rescued from corporate IT drudgery by Free Software and, in part, Django. Many of Jeremy’s interests center around access to information. Jeremy was the lead developer of Pegasus News, one of the first uses of Django outside World Online, and has since joined Votizen, a startup intent on reducing the influence of money in politics. He serves as DSF Secretary, organizes and helps organize sprints, cares about the health and equity of the Django community. He has gone an embarrassingly long time without a working blog. Jeremy lives in Mountain View, CA, USA. 4 Chapter 1. About this book CHAPTER 2 Introduction In the early days, Web developers wrote every page by hand. Updating a Web site meant editing 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, timeconsuming, 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 dynamically generate HTML. 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.) 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 programming 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. We wrote this book because we firmly believe that Django makes Web development better. 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. This book is open source and all are welcome to improve it. If you prefer to suggest changes, please drop us a line at feedback@djangobook.com. Either way, we’d love to hear from you! We’re glad you’re here, and we hope that you find Django as exciting, fun and useful as we do. 5 The Django Book, Release 2.0 6 Chapter 2. Introduction CHAPTER 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 applications with minimal fuss. At its best, Web development is an exciting, creative act; at its worst, it can be a repetitive, 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. 3.1 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 of getting 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 shortcuts 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: just create a Python script that outputs HTML, then save the script to a Web server with a ”.cgi” extension and visit the page in your Web browser. That’s it. Here’s an example 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: #!/usr/bin/env python import MySQLdb print print print print print "Content-Type: text/html\n" "Books " "" "Books
" "
- "
7
The Django Book, Release 2.0
connection = MySQLdb.connect(user=’me’, passwd=’letmein’, db=’my_db’)
cursor = connection.cursor()
cursor.execute("SELECT name FROM books ORDER BY pub_date DESC LIMIT 10")
for row in cursor.fetchall():
print "
- %s " % row[0] print "
Books
-
{% for book in book_list %}
- {{ book.name }} {% endfor %}
Ordering notice
35 The Django Book, Release 2.0Dear {{ person_name }},
Thanks for placing an order from {{ company }}. It’s scheduled to ship on {{ ship_date|date:"F j, Y" }}.
Here are the items you’ve ordered:
-
{% for item in item_list %}
- {{ item }} {% endfor %}
Your warranty information will be included in the packaging.
{% else %}You didn’t order a warranty, so you’re on your own when the products inevitably stop working.
{% endif %}Sincerely,
{{ company }}
Dear {{ person_name }},
... ...Thanks for placing an order from {{ company }}. It’s scheduled to ... ship on {{ ship_date|date:"F j, Y" }}.
... ... {% if ordered_warranty %} ...Your warranty information will be included in the packaging.
... {% else %} ...You didn’t order a warranty, so you’re on your own when ... the products inevitably stop working.
... {% endif %} ... ...Sincerely,
{{ company }}
Dear John Smith,
\n\nThanks for placing an order from Outdoor Equipment. It’s scheduled to\nship on April 2, 2009.
\n\n\nYou didn’t order a warranty, so you’re on your own when\nthe products inevitably stop working.
\n\n\nSincerely,
Outdoor Equipment
Welcome to the weekend!
{% endif %} An {% else %} tag is optional: {% if today_is_weekend %}Welcome to the weekend!
{% else %}Get back to work.
{% endif %} Python “Truthiness” In Python and in the Django template system, these objects evaluate to False in a Boolean context: • An empty list ([]) • An empty tuple (()) • An empty dictionary ({}) • An empty string (’’) • Zero (0) • The special object None • The object False (obviously) • Custom objects that define their own Boolean context behavior (this is advanced Python usage) Everything else evaluates to True. The {% if %} tag accepts and, or, or not for testing multiple variables, or to negate a given variable. For example: {% if athlete_list and coach_list %} Both athletes and coaches are available. {% endif %} {% if not athlete_list %} There are no athletes. {% endif %} {% if athlete_list or coach_list %} There are some athletes or some coaches. {% endif %} {% if not athlete_list or coach_list %} There are no athletes or there are some coaches. {% endif %} {% if athlete_list and not coach_list %} There are some athletes and absolutely no coaches. {% endif %} {% if %} tags don’t allow and and or clauses within the same tag, because the order of logic would be ambiguous. For example, this is invalid: {% if athlete_list and coach_list or cheerleader_list %} 44 Chapter 6. Chapter 4: Templates The Django Book, Release 2.0 The use of parentheses for controlling order of operations is not supported. If you find yourself needing parentheses, consider performing logic outside the template and passing the result of that as a dedicated template variable. Or, just use nested {% if %} tags, like this: {% if athlete_list %} {% if coach_list or cheerleader_list %} We have athletes, and either coaches or cheerleaders! {% endif %} {% endif %} Multiple uses of the same logical operator are fine, but you can’t combine different operators. For example, this is valid: {% if athlete_list or coach_list or parent_list or teacher_list %} There is no {% elif %} tag. Use nested {% if %} tags to accomplish the same thing: {% if athlete_list %}Here are the athletes: {{ athlete_list }}.
{% else %}No athletes are available.
{% if coach_list %}Here are the coaches: {{ coach_list }}.
{% endif %} {% endif %} Make sure to close each {% if %} with an {% endif %}. TemplateSyntaxError. Otherwise, Django will throw a for The {% for %} tag allows you to loop over each item in a sequence. As in Python’s for statement, the syntax is for X in Y, where Y is the sequence to loop over and X 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 {% for %} and {% endfor %}. For example, you could use the following to display a list of athletes given a variable athlete_list:-
{% for athlete in athlete_list %}
- {{ athlete.name }} {% endfor %}
{{ athlete.name }}
-
{% for sport in athlete.sports_played %}
- {{ sport }} {% endfor %} 6.3. Basic Template Tags and Filters 45 The Django Book, Release 2.0
{{ athlete.name }}
{% endfor %} {% else %}There are no athletes. Only computer programmers.
{% endif %} Because this pattern is so common, the for tag supports an optional {% empty %} clause that lets you define what to output if the list is empty. This example is equivalent to the previous one: {% for athlete in athlete_list %}{{ athlete.name }}
{% empty %}There are no athletes. Only computer programmers.
{% endfor %} There is no support for “breaking out” of a loop before the loop is finished. If you want to 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 “Philosophies and Limitations” later in this chapter for the reasoning behind this design decision.) Within each {% for %} loop, you get access to a template variable called forloop. This variable has a few attributes that give you information about the progress of the loop: • forloop.counter 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, forloop.counter will be set to 1. Here’s an example: {% for item in todo_list %}{{ forloop.counter }}: {{ item }}
{% endfor %} • forloop.counter0 is like forloop.counter, except it’s zero-indexed. Its value will be set to 0 the first time through the loop. • forloop.revcounter is always set to an integer representing the number of remaining items in the loop. The first time through the loop, forloop.revcounter will be set to the total number of items in the sequence you’re traversing. The last time through the loop, forloop.revcounter will be set to 1. • forloop.revcounter0 is like forloop.revcounter, except it’s zero-indexed. The first time through the loop, forloop.revcounter0 will be set to the number of elements in the sequence minus 1. The last time through the loop, it will be set to 0. • forloop.first is a Boolean value set to True if this is the first time through the loop. This is convenient for special-casing: {% for object in objects %} {% if forloop.first %}Country #{{ forloop.parentloop.counter }} | City #{{ forloop.counter }} | {{ city }} |
Welcome!
{% endifequal %} The arguments can be hard-coded strings, with either single or double quotes, so the following is valid: {% ifequal section ’sitenews’ %}Site News
{% endifequal %} 6.3. Basic Template Tags and Filters 47 The Django Book, Release 2.0 {% ifequal section "community" %}Community
{% endifequal %} Just like {% if %}, the {% ifequal %} tag supports an optional {% else %}: {% ifequal section ’sitenews’ %}Site News
{% else %}No News Here
{% endifequal %} Only template variables, strings, integers, and decimal numbers are allowed as arguments to {% ifequal %}. These are valid examples: {% {% {% {% ifequal ifequal ifequal ifequal variable variable variable variable 1 %} 1.23 %} ’foo’ %} "foo" %} Any other types of variables, such as Python dictionaries, lists, or Booleans, can’t be hard-coded in {% ifequal %}. These are invalid examples: {% ifequal variable True %} {% ifequal variable [1, 2, 3] %} {% ifequal variable {’key’: ’value’} %} If you need to test whether something is true or false, use the {% if %} tags instead of {% ifequal %}. Comments Just as in HTML or Python, the Django template language allows for comments. To designate a comment, use {# #}: {# This is a comment #} The comment will not be output when the template is rendered. Comments using this syntax cannot span multiple lines. This limitation improves template parsing performance. In the following template, the rendered output will look exactly the same as the template (i.e., the comment tag will not be parsed as a comment): This is a {# this is not a comment #} test. If you want to use multi-line comments, use the {% comment %} template tag, like this: {% comment %} This is a multi-line comment. {% endcomment %} 6.3.2 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: 48 Chapter 6. Chapter 4: Templates The Django Book, Release 2.0 {{ name|lower }} This displays the value of the {{ name }} variable after being filtered through the lower 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 takes the first element in a list and converts it to uppercase: {{ my_list|first|upper }} Some filters take arguments. A filter argument comes after a colon and is always in double quotes. For example: {{ bio|truncatewords:"30" }} This displays the first 30 words of the bio variable. The following are a few of the most important filters. Appendix E covers the rest. • addslashes: Adds a backslash before any backslash, single quote, or double quote. This is useful if the produced text is included in a JavaScript string. • date: Formats a date or datetime object according to a format string given in the parameter, for example: {{ pub_date|date:"F j, Y" }} Format strings are defined in Appendix E. • length: 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, take note that this works on any Python object that knows how to determine its length – i.e., any object that has a __len__() method.) 6.4 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. More than any other component of Web applications, template syntax is highly subjective, 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 likely created because its developer deemed all existing template languages inadequate. (In fact, it is said to be a rite of passage for a Python developer to write his or her own template language! If you haven’t done this yet, consider it. It’s a fun exercise.) With that in mind, you might be interested to know that Django doesn’t require that you use its template language. Because Django is intended to be a full-stack Web framework that provides all the pieces necessary for Web developers to be productive, many times it’s more 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. The template system has roots in how Web development is done at World Online and the combined experience of Django’s creators. Here are a few of those philosophies: • 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 do. It is possible to write custom template tags that 6.4. Philosophies and Limitations 49 The Django Book, Release 2.0 do arbitrary things, but the out-of-the-box Django template tags intentionally do not allow for arbitrary Python code execution. • 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 limitation. Requiring valid XML to write templates introduces a world of human mistakes and hardto-understand error messages, and using an XML engine to parse templates incurs an unacceptable level of overhead in template processing. • Designers are assumed to be comfortable with HTML code. The template system isn’t designed so that templates necessarily are displayed nicely in WYSIWYG editors such 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. • Designers are assumed not to be Python programmers. The template system authors recognize that Web page templates are most often written by designers, not programmers, and therefore should not assume Python knowledge. However, the system also intends to accommodate small teams in which the templates are created by Python programmers. It offers a way to extend the system’s syntax by writing raw Python code. (More on this in Chapter 9.) • The goal is not to invent a programming language. The goal is to offer just enough programming-esque functionality, such as branching and looping, that is essential for making presentation-related decisions. 6.5 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 current_datetime view in mysite.views, which we started in the previous chapter. Here’s what it looks like: from django.http import HttpResponse import datetime def current_datetime(request): now = datetime.datetime.now() html = "It is now %s." % now return HttpResponse(html) Let’s change this view to use Django’s template system. At first, you might think to do something like this: from django.template import Template, Context from django.http import HttpResponse import datetime def current_datetime(request): now = datetime.datetime.now() t = Template("It is now {{ current_date }}.") html = t.render(Context({’current_date’: now})) return HttpResponse(html) 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 50 Chapter 6. Chapter 4: Templates The Django Book, Release 2.0 as the file /home/djangouser/templates/mytemplate.html: from django.template import Template, Context from django.http import HttpResponse import datetime def current_datetime(request): now = datetime.datetime.now() # Simple way of using templates from the filesystem. # This is BAD because it doesn’t account for missing files! fp = open(’/home/djangouser/templates/mytemplate.html’) t = Template(fp.read()) fp.close() html = t.render(Context({’current_date’: now})) return HttpResponse(html) This approach, however, is inelegant for these reasons: • It doesn’t handle the case of a missing file. If the file mytemplate.html doesn’t exist or isn’t readable, the open() call will raise an IOError exception. • It hard-codes your template location. If you were to use this technique for every view function, you’d be duplicating the template locations. Not to mention it involves a lot of typing! • It includes a lot of boring boilerplate code. You’ve got better things to do than to write calls to open(), fp.read(), and fp.close() each time you load a template. To solve these issues, we’ll use template loading and template directories. 6.6 Template Loading Django provides a convenient and powerful API for loading templates from the filesystem, with the goal of removing redundancy both in your template-loading calls and in your templates themselves. In order to use this template-loading API, first you’ll need to tell the framework where you store your templates. The place to do this is in your settings file – the settings.py file that we mentioned last chapter, when we introduced the ROOT_URLCONF setting. If you’re following along, open your settings.py and find the TEMPLATE_DIRS setting. By default, it’s an empty tuple, likely containing some auto-generated comments: TEMPLATE_DIRS = ( # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". # Always use forward slashes, even on Windows. # Don’t forget to use absolute paths, not relative paths. ) 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 TEMPLATE_DIRS, like so: TEMPLATE_DIRS = ( ’/home/django/mysite/templates’, ) There are a few things to note: • You can specify any directory you want, as long as the directory and templates within that directory are readable by the user account under which your Web server runs. If you can’t think of an appropriate place to put 6.6. Template Loading 51 The Django Book, Release 2.0 your templates, we recommend creating a templates directory within your project (i.e., within the mysite directory you created in Chapter 2). • If your TEMPLATE_DIRS contains only one directory, don’t forget the comma at the end of the directory string! Bad: # Missing comma! TEMPLATE_DIRS = ( ’/home/django/mysite/templates’ ) Good: # Comma correctly in place. TEMPLATE_DIRS = ( ’/home/django/mysite/templates’, ) The reason for this is that Python requires commas within single-element tuples to disambiguate the tuple from a parenthetical expression. This is a common newbie gotcha. • If you’re on Windows, include your drive letter and use Unix-style forward slashes rather than backslashes, as follows: TEMPLATE_DIRS = ( ’C:/www/django/templates’, ) • It’s simplest to use absolute paths (i.e., directory paths that start at the root of the filesystem). If you want to be a bit more flexible and decoupled, though, you can take advantage of the fact that Django settings files are just Python code by constructing the contents of TEMPLATE_DIRS dynamically. For example: import os.path TEMPLATE_DIRS = ( os.path.join(os.path.dirname(__file__), ’templates’).replace(’\\’,’/’), ) This example uses the “magic” Python variable __file__, which is automatically set to the file name of the Python module in which the code lives. It gets the name of the directory that contains settings.py (os.path.dirname), then joins that with templates in a cross-platform way (os.path.join), then ensures that everything uses forward slashes instead of backslashes (in case of Windows). While we’re on the topic of dynamic Python code in settings files, we should point out that it’s very important to avoid Python errors in your settings file. If you introduce a syntax error, or a runtime error, your Django-powered site will likely crash. With TEMPLATE_DIRS 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 current_datetime view, let’s change it like so: from django.template.loader import get_template from django.template import Context from django.http import HttpResponse import datetime def current_datetime(request): now = datetime.datetime.now() t = get_template(’current_datetime.html’) html = t.render(Context({’current_date’: now})) return HttpResponse(html) 52 Chapter 6. Chapter 4: Templates The Django Book, Release 2.0 In this example, we’re using the function django.template.loader.get_template() rather than loading the template from the filesystem manually. The get_template() function takes a template name as its argument, figures out where the template lives on the filesystem, opens that file, and returns a compiled Template object. Our template in this example is current_datetime.html, but there’s nothing special about that .html extension. You can give your templates whatever extension makes sense for your application, or you can leave off extensions entirely. To determine the location of the template on your filesystem, get_template() combines your template directories from TEMPLATE_DIRS with the template name that you pass to get_template(). For example, if your TEMPLATE_DIRS is set to ’/home/django/mysite/templates’, the above get_template() call would look for the template /home/django/mysite/templates/current_datetime.html. If get_template() cannot find the template with the given name, it raises a TemplateDoesNotExist exception. To see what that looks like, fire up the Django development server again by running python manage.py runserver within your Django project’s directory. Then, point your browser at the page that activates the current_datetime view (e.g., http://127.0.0.1:8000/time/). Assuming your DEBUG setting is set to True and you haven’t yet created a current_datetime.html template, you should see a Django error page highlighting the TemplateDoesNotExist error. Figure 6.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 current_datetime.html file within your template directory using the following template code: It is now {{ current_date }}. Refresh the page in your Web browser, and you should see the fully rendered page. 6.6. Template Loading 53 The Django Book, Release 2.0 6.6.1 render() We’ve shown you how to load a template, fill a Context and return an HttpResponse object with the result of the rendered template. We’ve optimized it to use get_template() instead of hard-coding templates and template paths. But it still requires a fair amount of typing to do those things. Because this is such a common idiom, Django provides a shortcut that lets you load a template, render it and return an HttpResponse – all in one line of code. This shortcut is a function called render(), which lives in the module django.shortcuts. Most of the time, you’ll be using render() rather than loading templates and creating Context and HttpResponse objects manually – unless your employer judges your work by total lines of code written, that is. Here’s the ongoing current_datetime example rewritten to use render(): from django.shortcuts import render import datetime def current_datetime(request): now = datetime.datetime.now() return render(request, ’current_datetime.html’, {’current_date’: now}) What a difference! Let’s step through the code changes: • We no longer have to import get_template, Template, Context, or HttpResponse. Instead, we import django.shortcuts.render. The import datetime remains. • Within the current_datetime function, we still calculate now, but the template loading, context creation, template rendering, and HttpResponse creation are all taken care of by the render() call. Because render() returns an HttpResponse object, we can simply return that value in the view. The first argument to render() is the request, the second is the name of the template to use. The third argument, if given, should be a dictionary to use in creating a Context for that template. If you don’t provide a third argument, render() will use an empty dictionary. 6.6.2 Subdirectories in get_template() It can get unwieldy to store all of your templates in a single directory. You might like to store templates in subdirectories of your template directory, and that’s fine. In fact, we recommend 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. Storing templates in subdirectories of your template directory is easy. In your calls to get_template(), just include the subdirectory name and a slash before the template name, like so: t = get_template(’dateapp/current_datetime.html’) Because render() is a small wrapper around get_template(), you can do the same thing with the second argument to render(), like this: return render(request, ’dateapp/current_datetime.html’, {’current_date’: now}) There’s no limit to the depth of your subdirectory tree. Feel free to use as many subdirectories as you like. Note: Windows users, be sure to use forward slashes rather than backslashes. get_template() assumes a Unixstyle file name designation. 54 Chapter 6. Chapter 4: Templates The Django Book, Release 2.0 6.6.3 The include Template Tag Now that we’ve covered the template-loading mechanism, we can introduce a built-in template tag that takes advantage of it: {% include %}. 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 single or double quotes. Anytime you have the same code in multiple templates, consider using an {% include %} to remove the duplication. These two examples include the contents of the template nav.html. The examples are equivalent and illustrate that either single or double quotes are allowed: {% include ’nav.html’ %} {% include "nav.html" %} This example includes the contents of the template includes/nav.html: {% include ’includes/nav.html’ %} This example includes the contents of the template whose name is contained in the variable template_name: {% include template_name %} As in get_template(), the file name of the template is determined by adding the template directory from TEMPLATE_DIRS to the requested template name. Included templates are evaluated with the context of the template that’s including them. For example, consider these two templates: # mypage.html {% include "includes/nav.html" %}{{ title }}
# includes/nav.html If you render mypage.html with a context containing current_section, then the variable will be available in the “included” template, as you would expect. If, in an {% include %} tag, a template with the given name isn’t found, Django will do one of two things: • If DEBUG is set to True, you’ll see the TemplateDoesNotExist exception on a Django error page. • If DEBUG is set to False, the tag will fail silently, displaying nothing in the place of the tag. 6.7 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 Web development problem: across a Web site, how does one reduce the duplication and redundancy of common page areas, such as sitewide navigation? 6.7. Template Inheritance 55 The Django Book, Release 2.0 A classic way of solving this problem is to use server-side includes, directives you can embed within your HTML pages to “include” one Web page inside another. Indeed, Django supports that approach, with the {% include %} template tag just described. But the preferred way of solving this problem with Django is to use a more elegant strategy called template inheritance. In essence, template inheritance lets you build a base “skeleton” template that contains all the common parts of your site and defines “blocks” that child templates can override. Let’s see an example of this by creating a more complete template for our current_datetime view, by editing the current_datetime.html file:My helpful timestamp site
It is now {{ current_date }}.
Thanks for visiting my site.
That looks just fine, but what happens when we want to create a template for another view – say, the hours_ahead view from Chapter 3? If we want again to make a nice, valid, full HTML template, we’d create something like:My helpful timestamp site
In {{ hour_offset }} hour(s), it will be {{ next_time }}.
Thanks for visiting my site.
Clearly, we’ve just duplicated a lot of HTML. Imagine if we had a more typical site, including 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 template. Perhaps you’d store the top bit of the template in a file called header.html: And perhaps you’d store the bottom bit in a file called footer.html:Thanks for visiting my site.
56 Chapter 6. Chapter 4: Templates The Django Book, Release 2.0 With an include-based strategy, headers and footers are easy. It’s the middle ground that’s messy. In this example, both pages feature a title –My helpful timestamp site
– but that title can’t fit into header.html because the in the header, we’d have to include the
, 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 “inside-out” version of serverside includes. Instead of defining the snippets that are 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:
{% block title %}{% endblock %}
My helpful timestamp site
{% block content %}{% endblock %}
{% block footer %}
Thanks for visiting my site.
{% endblock %} This template, which we’ll call base.html, defines a simple HTML skeleton document that we’ll use for all the pages on the site. It’s the job of child templates to override, or add to, or leave alone the contents of the blocks. (If you’re following along, save this file to your template directory as base.html.) We’re using a template tag here that you haven’t seen before: the {% block %} tag. All the {% block %} tags do is tell the template engine that a child template may override those portions of the template. Now that we have this base template, we can modify our existing current_datetime.html template to use it: {% extends "base.html" %} {% block title %}The current time{% endblock %} {% block content %}It is now {{ current_date }}.
{% endblock %} While we’re at it, let’s create a template for the hours_ahead view from Chapter 3. (If you’re following along with code, we’ll leave it up to you to change hours_ahead to use the template system instead of hard-coded HTML.) Here’s what that could look like: {% extends "base.html" %} {% block title %}Future time{% endblock %} {% block content %}In {{ hour_offset }} hour(s), it will be {{ next_time }}.
{% endblock %} Isn’t this beautiful? Each template contains only the code that’s unique to that template. No redundancy needed. If you need to make a site-wide design change, just make the change to base.html, and all of the other templates will immediately reflect the change. Here’s how it works. When you load the template current_datetime.html, the template engine sees the {% 6.7. Template Inheritance 57 The Django Book, Release 2.0 extends %} tag, noting that this template is a child template. The engine immediately loads the parent template – in this case, base.html. At that point, the template engine notices the three {% block %} tags in base.html and replaces those blocks with the contents of the child template. So, the title we’ve defined in {% block title %} will be used, as will the {% block content %}. Note that since the child template doesn’t define the footer block, the template system uses the value from the parent template instead. Content within a {% block %} tag in a parent template is always used as a fallback. Inheritance doesn’t affect the template context. In other words, any template in the inheritance tree will have access to every one of your template variables from the context. You can use as many levels of inheritance as needed. One common way of using inheritance is the following three-level approach: 1. Create a base.html template that holds the main look and feel of your site. This is the stuff that rarely, if ever, changes. 2. Create a base_SECTION.html template for each “section” of your site (e.g., base_photos.html and base_forum.html). These templates extend base.html and include section-specific styles/design. 3. Create individual templates for each type of page, such as a forum page or a photo gallery. These templates extend the appropriate section template. This approach maximizes code reuse and makes it easy to add items to shared areas, such as section-wide navigation. Here are some guidelines for working with template inheritance: • If you use {% extends %} in a template, it must be the first template tag in that template. Otherwise, template inheritance won’t work. • Generally, the more {% block %} 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 templates. It’s better to have more hooks than fewer hooks. • If you find yourself duplicating code in a number of templates, it probably means you should move that code to a {% block %} in a parent template. • If you need to get the content of the block from the parent template, use {{ block.super }}, which is a “magic” variable providing the rendered text of the parent template. This is useful if you want to add to the contents of a parent block instead of completely overriding it. • You may not define multiple {% block %} tags with the same name in the same template. 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. If there were two similarly named {% block %} tags in a template, that template’s parent wouldn’t know which one of the blocks’ content to use. • The template name you pass to {% extends %} is loaded using the same method that get_template() uses. That is, the template name is appended to your TEMPLATE_DIRS setting. • In most cases, the argument to {% extends %} will be a string, but it can also be a variable, if you don’t know the name of the parent template until runtime. This lets you do some cool, dynamic stuff. 6.8 What’s next? You now have the basics of Django’s template system under your belt. What’s next? Many modern Web sites are database-driven: the content of the Web site is stored in a 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.) 58 Chapter 6. Chapter 4: Templates The Django Book, Release 2.0 The next chapter Chapter 5 covers the tools Django gives you to interact with a database. 6.8. What’s next? 59 The Django Book, Release 2.0 60 Chapter 6. Chapter 4: Templates CHAPTER 7 Chapter 5: Models In Chapter 3, we covered the fundamentals of building dynamic Web sites with Django: setting 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 calculate 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 functionality: Django’s database layer. (Note: 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.) 7.1 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. In this example view, we use the MySQLdb library (available via http://www.djangoproject.com/r/python-mysql/) to connect to a MySQL database, retrieve some records, and feed them to a template for display as a Web page: from django.shortcuts import render import MySQLdb def book_list(request): db = MySQLdb.connect(user=’me’, db=’mydb’, passwd=’secret’, host=’localhost’) cursor = db.cursor() cursor.execute(’SELECT name FROM books ORDER BY name’) names = [row[0] for row in cursor.fetchall()] db.close() return render(request, ’book_list.html’, {’names’: names}) This approach works, but some problems should jump out at you immediately: 61 The Django Book, Release 2.0 • We’re hard-coding the database connection parameters. Ideally, these parameters would be stored in the Django configuration. • We’re having to write a fair bit of boilerplate code: creating a connection, creating a cursor, executing a statement, and closing the connection. Ideally, all we’d have to do is specify which results we wanted. • It ties us to MySQL. If, down the road, we switch from MySQL to PostgreSQL, we’ll have to use a different database adapter (e.g., psycopg rather than MySQLdb), alter the connection 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 relevant 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: from django.shortcuts import render from mysite.books.models import Book def book_list(request): books = Book.objects.order_by(’name’) return render(request, ’book_list.html’, {’books’: books}) We’ll explain this code a little later in the chapter. For now, just get a feel for how it looks. 7.2 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. 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 applying 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 developers. 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: • M, the data-access portion, is handled by Django’s database layer, which is described in this chapter. • V, the portion that selects which data to display and how to display it, is handled by views and templates. • 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 function for the given URL. 62 Chapter 7. Chapter 5: Models The Django Book, Release 2.0 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, • M stands for “Model,” the data access layer. This layer contains anything and everything about the data: how to access it, how to validate it, which behaviors it has, and the relationships between the data. • 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. • V stands for “View,” the business logic layer. This layer contains the logic that access 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. 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 understand the underlying concepts. 7.3 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 CREATE DATABASE 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 TEMPLATE_DIRS in the previous chapter, database configuration lives in the Django settings file, called settings.py by default. Edit that file and look for the database settings: DATABASES = { ’default’: { ’ENGINE’: ’django.db.backends.’, ’NAME’: ’’, ’USER’: ’’, ’PASSWORD’: ’’, ’HOST’: ’’, ’PORT’: ’’, } } # # # # # # Add ’postgresql_psycopg2’, ’mysql’, ’sqlite3’ or ’oracle’. Or path to database file if using sqlite3. Not used with sqlite3. Not used with sqlite3. Set to empty string for localhost. Not used with sqlite3. Set to empty string for default. Not used with sqlite3. Here’s a rundown of each setting. • ENGINE tells Django which database engine to use. If you’re using a database with Django, ENGINE must be set to one of the strings shown in Table 5-1. 7.3. Configuring the Database 63 The Django Book, Release 2.0 Table 7.1: Table 5-1. Database Engine Settings Setting Database Required Adapter django.db.backends.postgresql_psycopg2 Postpsycopg version 2.x, greSQL http://www.djangoproject.com/r/python-pgsql/. django.db.backends.mysql MySQL MySQLdb, http://www.djangoproject.com/r/python-mysql/. django.db.backends.sqlite3 SQLite No adapter needed. django.db.backends.oracle Oracle cx_Oracle, http://www.djangoproject.com/r/python-oracle/. Note that for whichever database back-end you use, you’ll need to download and 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 python-postgresql or python-psycopg, for example.) Example: ’ENGINE’: ’django.db.backends.postgresql_psycopg2’, • NAME tells Django the name of your database. For example: ’NAME’: ’mydb’, If you’re using SQLite, specify the full filesystem path to the database file on your filesystem. For example: ’NAME’: ’/home/django/mydata.db’, As for where you put that SQLite database, we’re using the /home/django directory in this example, but you should pick a directory that works best for you. • USER tells Django which username to use when connecting to your database. For example: If you’re using SQLite, leave this blank. • PASSWORD tells Django which password to use when connecting to your database. If you’re using SQLite or have an empty password, leave this blank. • HOST 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: ’HOST’: ’/var/run/mysql’, • PORT tells Django which port to use when connecting to your database. If you’re using SQLite, leave this blank. Otherwise, if you leave this blank, the underlying database adapter will use whichever port is default for your given database server. In most cases, the default port is fine, so you can leave this blank. Once you’ve entered those settings and saved settings.py, it’s a good idea to test your configuration. To do this, run python manage.py shell as in the last chapter, from within the mysite project directory. (As we pointed out last chapter manage.py shell 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 connection information.) In the shell, type these commands to test your database configuration: >>> from django.db import connection >>> cursor = connection.cursor() 64 Chapter 7. Chapter 5: Models The Django Book, Release 2.0 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. Table 7.2: Table 5-2. Database Configuration Error Messages Error Message You haven’t set the ENGINE setting yet. Environment variable DJANGO_SETTINGS_MODULE is undefined. Error loading _____ module: No module named _____. _____ isn’t an available database backend. database _____ does not exist role _____ does not exist could not connect to server Solution Set the ENGINE setting to something other than an empty string. Valid values are in Table 5-1. Run the command python manage.py shell rather than python. You haven’t installed the appropriate database-specific adapter (e.g., psycopg or MySQLdb). Adapters are not bundled with Django, so it’s your responsibility to download and install them on your own. Set your ENGINE setting to one of the valid engine settings described previously. Perhaps you made a typo? Change the NAME setting to point to a database that exists, or execute the appropriate CREATE DATABASE statement in order to create it. Change the USER setting to point to a user that exists, or create the user in your database. Make sure HOST and PORT are set correctly, and make sure the database server is running. 7.4 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’d 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: • A project is an instance of a certain set of Django apps, plus the configuration for those apps. Technically, the only requirement of a project is that it supplies a settings file, which defines the database connection information, the list of installed apps, the TEMPLATE_DIRS, and so forth. • An app is a portable set of Django functionality, usually including models and views, that lives together in a single Python package. For example, Django comes with a number of apps, such as a commenting system and an automatic admin interface. A key thing to note about these apps is that they’re portable and reusable across multiple projects. 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 message 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 views.py, 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 mysite project directory, type this command to create a books app: 7.4. Your First App 65 The Django Book, Release 2.0 python manage.py startapp books This command does not produce any output, but it does create a books directory within the mysite directory. Let’s look at the contents of that directory: books/ __init__.py models.py tests.py views.py These files will contain the models and views for this app. Have a look at models.py and views.py in your favorite text editor. Both files are empty, except for comments and an import in models.py. This is the blank slate for your Django app. 7.5 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 layout – the equivalent of your SQL CREATE TABLE statements – except it’s in Python instead of SQL, and it includes more than just database column definitions. Django uses a model to execute 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: • Introspection requires overhead and is imperfect. In order to provide convenient data-access APIs, Django needs to know the database layout somehow, and there are two ways of accomplishing this. The first way would be to explicitly describe the data in Python, and the second way would be to introspect the database at runtime to determine the data models. This second way seems cleaner, because the metadata about your tables lives in only 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. • Writing Python is fun, and keeping everything in Python limits the number of times 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. • Having data models stored as code rather than in your database makes it easier to keep your models under version control. This way, you can easily keep track of changes to your data layouts. • SQL allows for only a certain level of metadata about a data layout. Most database systems, for example, do not provide a specialized data type for representing email addresses or URLs. Django models do. The advantage of higher-level data types is higher productivity and more reusable code. • SQL is inconsistent across database platforms. If you’re distributing a Web application, for example, it’s much more pragmatic to distribute a Python module that describes your data layout than separate sets of CREATE TABLE 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 66 Chapter 7. Chapter 5: Models The Django Book, Release 2.0 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 introspecting an existing database. This is useful for quickly getting up and running with legacy data. We’ll cover this in Chapter 18. 7.6 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 relationships 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! We’ll suppose the following concepts, fields, and relationships: • An author has a first name, a last name and an email address. • A publisher has a name, a street address, a city, a state/province, a country, and a Web site. • A book has a title and a publication date. It also has one or more authors (a many-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 models.py file that was created by the startapp command, enter the following: from django.db import models class Publisher(models.Model): name = models.CharField(max_length=30) address = models.CharField(max_length=50) city = models.CharField(max_length=60) state_province = models.CharField(max_length=30) country = models.CharField(max_length=50) website = models.URLField() class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField() class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher) publication_date = models.DateField() 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 django.db.models.Model. The parent class, Model, 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 corresponds to the column’s name, and the type of field (e.g., CharField) corresponds to the database column type (e.g., varchar). For example, the Publisher model is equivalent to the following table (assuming PostgreSQL CREATE TABLE syntax): 7.6. Your First Model 67 The Django Book, Release 2.0 CREATE TABLE "books_publisher" ( "id" serial NOT NULL PRIMARY KEY, "name" varchar(30) NOT NULL, "address" varchar(50) NOT NULL, "city" varchar(60) NOT NULL, "state_province" varchar(30) NOT NULL, "country" varchar(50) NOT NULL, "website" varchar(200) NOT NULL ); Indeed, Django can generate that CREATE TABLE 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 relationships. In our example models, Book has a ManyToManyField called authors. This designates that a book has one or many authors, but the Book database table doesn’t get an authors column. Rather, Django creates an additional table – a manyto-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 auto-incrementing integer primary key field called id. Each Django model is required to have a single-column primary key. 7.7 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 books app to the list of “installed apps” in the settings file. Edit the settings.py file again, and look for the INSTALLED_APPS setting. INSTALLED_APPS tells Django which apps are activated for a given project. By default, it looks something like this: INSTALLED_APPS = ( ’django.contrib.auth’, ’django.contrib.contenttypes’, ’django.contrib.sessions’, ’django.contrib.sites’, ’django.contrib.messages’, ’django.contrib.staticfiles’, ) Temporarily comment out all six 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 MIDDLEWARE_CLASSES setting, too; the default values in MIDDLEWARE_CLASSES depend on some of the apps we just commented out. Then, add ’books’ to the INSTALLED_APPS list, so the setting ends up looking like this: MIDDLEWARE_CLASSES = ( # ’django.middleware.common.CommonMiddleware’, # ’django.contrib.sessions.middleware.SessionMiddleware’, # ’django.middleware.csrf.CsrfViewMiddleware’, # ’django.contrib.auth.middleware.AuthenticationMiddleware’, # ’django.contrib.messages.middleware.MessageMiddleware’, ) INSTALLED_APPS = ( # ’django.contrib.auth’, # ’django.contrib.contenttypes’, 68 Chapter 7. Chapter 5: Models The Django Book, Release 2.0 # ’django.contrib.sessions’, # ’django.contrib.sites’, ’books’, ) (As we mentioned last chapter when setting TEMPLATE_DIRS, you’ll need to be sure to include the trailing comma in INSTALLED_APPS, 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.) ’mysite.books’ refers to the books app we’re working on. Each app in INSTALLED_APPS 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 database tables in our database. First, let’s validate the models by running this command: python manage.py validate The validate command checks whether your models’ syntax and logic are correct. If all is well, you’ll see the message 0 errors found. 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 python manage.py validate. It tends to catch all the common model problems. If your models are valid, run the following command for Django to generate CREATE TABLE statements for your models in the books app (with colorful syntax highlighting available, if you’re using Unix): python manage.py sqlall books In this command, books is the name of the app. It’s what you specified when you ran the command manage.py startapp. When you run the command, you should see something like this: BEGIN; CREATE TABLE "books_publisher" ( "id" serial NOT NULL PRIMARY KEY, "name" varchar(30) NOT NULL, "address" varchar(50) NOT NULL, "city" varchar(60) NOT NULL, "state_province" varchar(30) NOT NULL, "country" varchar(50) NOT NULL, "website" varchar(200) NOT NULL ) ; CREATE TABLE "books_author" ( "id" serial NOT NULL PRIMARY KEY, "first_name" varchar(30) NOT NULL, "last_name" varchar(40) NOT NULL, "email" varchar(75) NOT NULL ) ; CREATE TABLE "books_book" ( "id" serial NOT NULL PRIMARY KEY, "title" varchar(100) NOT NULL, "publisher_id" integer NOT NULL REFERENCES "books_publisher" ("id") DEFERRABLE INITIALLY DEFERRED "publication_date" date NOT NULL ) ; CREATE TABLE "books_book_authors" ( "id" serial NOT NULL PRIMARY KEY, 7.7. Installing the Model 69 The Django Book, Release 2.0 "book_id" integer NOT NULL REFERENCES "books_book" ("id") DEFERRABLE INITIALLY DEFERRED, "author_id" integer NOT NULL REFERENCES "books_author" ("id") DEFERRABLE INITIALLY DEFERRED, UNIQUE ("book_id", "author_id") ) ; CREATE INDEX "books_book_publisher_id" ON "books_book" ("publisher_id"); COMMIT; Note the following: • Table names are automatically generated by combining the name of the app (books) and the lowercase name of the model (publisher, book, and author). You can override this behavior, as detailed in Appendix B. • As we mentioned earlier, Django adds a primary key for each table automatically – the id fields. You can override this, too. • By convention, Django appends "_id" to the foreign key field name. As you might have guessed, you can override this behavior, too. • The foreign key relationship is made explicit by a REFERENCES statement. • These CREATE TABLE statements are tailored to the database you’re using, so database-specific field types such as auto_increment (MySQL), serial (PostgreSQL), or integer primary key (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. The sqlall command doesn’t actually create the tables or otherwise touch your database – 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., python manage.py sqlall books | psql mydb). However, Django provides an easier way of committing the SQL to the database: the syncdb command: python manage.py syncdb Run that command, and you’ll see something like this: Creating table books_publisher Creating table books_author Creating table books_book Installing index for books.Book model The syncdb command is a simple “sync” of your models to your database. It looks at all of the models in each app in your INSTALLED_APPS setting, checks the database to see whether the appropriate tables exist yet, and creates the tables if they don’t yet exist. Note that syncdb does not sync changes in models or deletions of models; if you make a change to a model or delete a model, and you want to update the database, syncdb will not handle that. (More on this in the “Making Changes to a Database Schema” section toward the end of this chapter.) If you run python manage.py syncdb again, nothing happens, because you haven’t added any models to the books app or added any apps to INSTALLED_APPS. Ergo, it’s always safe to run python manage.py syncdb – 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., psql for PostgreSQL) or you can run the command python manage.py dbshell, which will figure out which command-line client to run, depending on your DATABASE_SERVER setting. The latter is almost always more convenient. 70 Chapter 7. Chapter 5: Models The Django Book, Release 2.0 7.8 Basic Data Access Once you’ve created a model, Django automatically provides a high-level Python API for working with those models. Try it out by running python manage.py shell and typing the following: >>> from books.models import Publisher >>> p1 = Publisher(name=’Apress’, address=’2855 Telegraph Avenue’, ... city=’Berkeley’, state_province=’CA’, country=’U.S.A.’, ... website=’http://www.apress.com/’) >>> p1.save() >>> p2 = Publisher(name="O’Reilly", address=’10 Fawcett St.’, ... city=’Cambridge’, state_province=’MA’, country=’U.S.A.’, ... website=’http://www.oreilly.com/’) >>> p2.save() >>> publisher_list = Publisher.objects.all() >>> publisher_list [