| 19 | | Start by describing your database layout in Python code. Django's data-model API |
|---|
| 20 | | offers many rich ways of representing your models -- so far, it's been |
|---|
| 21 | | solving two years' worth of database-schema problems. Here's a quick example:: |
|---|
| 22 | | |
|---|
| 23 | | class Reporter(meta.Model): |
|---|
| 24 | | full_name = meta.CharField(maxlength=70) |
|---|
| 25 | | |
|---|
| 26 | | def __repr__(self): |
|---|
| | 19 | Although you can use Django without a database, it comes with an |
|---|
| | 20 | object-relational mapper in which you describe your database layout in Python |
|---|
| | 21 | code. |
|---|
| | 22 | |
|---|
| | 23 | The data-model syntax offers many rich ways of representing your models -- so |
|---|
| | 24 | far, it's been solving two years' worth of database-schema problems. Here's a |
|---|
| | 25 | quick example:: |
|---|
| | 26 | |
|---|
| | 27 | class Reporter(models.Model): |
|---|
| | 28 | full_name = models.CharField(maxlength=70) |
|---|
| | 29 | |
|---|
| | 30 | def __str__(self): |
|---|
| 29 | | class Article(meta.Model): |
|---|
| 30 | | pub_date = meta.DateTimeField() |
|---|
| 31 | | headline = meta.CharField(maxlength=200) |
|---|
| 32 | | article = meta.TextField() |
|---|
| 33 | | reporter = meta.ForeignKey(Reporter) |
|---|
| 34 | | |
|---|
| 35 | | def __repr__(self): |
|---|
| | 33 | class Article(models.Model): |
|---|
| | 34 | pub_date = models.DateTimeField() |
|---|
| | 35 | headline = models.CharField(maxlength=200) |
|---|
| | 36 | article = models.TextField() |
|---|
| | 37 | reporter = models.ForeignKey(Reporter) |
|---|
| | 38 | |
|---|
| | 39 | def __str__(self): |
|---|
| 41 | | Next, run the Django command-line utility. It'll create the database tables for |
|---|
| 42 | | you automatically, in the database specified in your Django settings. Django |
|---|
| 43 | | works best with PostgreSQL, although we've recently added beta MySQL |
|---|
| 44 | | support and other database adapters are on the way:: |
|---|
| 45 | | |
|---|
| 46 | | django-admin.py install news |
|---|
| | 45 | Next, run the Django command-line utility to create the database tables |
|---|
| | 46 | automatically:: |
|---|
| | 47 | |
|---|
| | 48 | manage.py syncdb |
|---|
| | 49 | |
|---|
| | 50 | The ``syncdb`` command looks at all your available models and creates tables |
|---|
| | 51 | in your database for whichever tables don't already exist. |
|---|
| 131 | | Once your models are defined, Django can automatically create an administrative |
|---|
| 132 | | interface -- a Web site that lets authenticated users add, change and |
|---|
| 133 | | delete objects. It's as easy as adding an extra ``admin`` attribute to your |
|---|
| 134 | | model classes:: |
|---|
| 135 | | |
|---|
| 136 | | class Article(meta.Model): |
|---|
| 137 | | pub_date = meta.DateTimeField() |
|---|
| 138 | | headline = meta.CharField(maxlength=200) |
|---|
| 139 | | article = meta.TextField() |
|---|
| 140 | | reporter = meta.ForeignKey(Reporter) |
|---|
| 141 | | class Meta: |
|---|
| 142 | | admin = meta.Admin() |
|---|
| | 130 | Once your models are defined, Django can automatically create a professional, |
|---|
| | 131 | production ready administrative interface -- a Web site that lets authenticated |
|---|
| | 132 | users add, change and delete objects. It's as easy as adding a line of code to |
|---|
| | 133 | your model classes:: |
|---|
| | 134 | |
|---|
| | 135 | class Article(models.Model): |
|---|
| | 136 | pub_date = models.DateTimeField() |
|---|
| | 137 | headline = models.CharField(maxlength=200) |
|---|
| | 138 | article = models.TextField() |
|---|
| | 139 | reporter = models.ForeignKey(Reporter) |
|---|
| | 140 | class Admin: pass |
|---|
| 156 | | application. Django lets you design URLs however you want, with no framework |
|---|
| 157 | | limitations. |
|---|
| 158 | | |
|---|
| 159 | | To design URLs for an app, you create a Python module. For the above |
|---|
| 160 | | Reporter/Article example, here's what that might look like:: |
|---|
| | 154 | application. Django encourages beautiful URL design and doesn't put any cruft |
|---|
| | 155 | in URLs, like ``.php`` or ``.asp``. |
|---|
| | 156 | |
|---|
| | 157 | To design URLs for an app, you create a Python module called a URLconf. A table |
|---|
| | 158 | of contents for your app, it contains a simple mapping between URL patterns and |
|---|
| | 159 | Python callback functions. URLconfs also serve to decouple URLs from Python |
|---|
| | 160 | code. |
|---|
| | 161 | |
|---|
| | 162 | Here's what a URLconf might look like for the above ``Reporter``/``Article`` |
|---|
| | 163 | example above:: |
|---|
| 165 | | (r'^/articles/(?P<year>\d{4})/$', 'myproject.news.views.year_archive'), |
|---|
| 166 | | (r'^/articles/(?P<year>\d{4})/(?P<month>\d{2})/$', 'myproject.news.views.month_archive'), |
|---|
| 167 | | (r'^/articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<article_id>\d+)/$', 'myproject.news.views.article_detail'), |
|---|
| | 168 | (r'^/articles/(\d{4})/$', 'mysite.views.year_archive'), |
|---|
| | 169 | (r'^/articles/(\d{4})/(\d{2})/$', 'mysite.views.month_archive'), |
|---|
| | 170 | (r'^/articles/(\d{4})/(\d{2})/(\d+)/$', 'mysite.views.article_detail'), |
|---|
| 170 | | The code above maps URLs, as regular expressions, to the location of Python |
|---|
| 171 | | callback functions (views). The regular expressions use parenthesis to "capture" |
|---|
| 172 | | values from the URLs. When a user requests a page, Django runs through each |
|---|
| 173 | | regular expression, in order, and stops at the first one that matches the |
|---|
| 174 | | requested URL. (If none of them matches, Django calls a special 404 view.) This |
|---|
| 175 | | is blazingly fast, because the regular expressions are compiled at load time. |
|---|
| | 173 | The code above maps URLs, as simple regular expressions, to the location of |
|---|
| | 174 | Python callback functions ("views"). The regular expressions use parenthesis to |
|---|
| | 175 | "capture" values from the URLs. When a user requests a page, Django runs |
|---|
| | 176 | through each pattern, in order, and stops at the first one that matches the |
|---|
| | 177 | requested URL. (If none of them matches, Django calls a special-case 404 view.) |
|---|
| | 178 | This is blazingly fast, because the regular expressions are compiled at load |
|---|
| | 179 | time. |
|---|
| 196 | | article_detail from above:: |
|---|
| 197 | | |
|---|
| 198 | | def article_detail(request, year, month, article_id): |
|---|
| 199 | | # Use the Django API to find an object matching the URL criteria. |
|---|
| 200 | | a = get_object_or_404(articles, pub_date__year=year, pub_date__month=month, pk=article_id) |
|---|
| 201 | | return render_to_response('news/article_detail.html', {'article': a}) |
|---|
| 202 | | |
|---|
| 203 | | This example uses Django's template system, which has several key features. |
|---|
| | 198 | ``year_archive`` from above:: |
|---|
| | 199 | |
|---|
| | 200 | def year_archive(request, year): |
|---|
| | 201 | a_list = Article.objects.filter(pub_date__year=year) |
|---|
| | 202 | return render_to_response('news/year_archive.html', {'article_list': a_list}) |
|---|
| | 203 | |
|---|
| | 204 | This example uses Django's template system, which has several powerful |
|---|
| | 205 | features but strives to stay simple enough for non-programmers to use. |
|---|
| 229 | | |
|---|
| 230 | | It should look straightforward. Variables are surrounded by double-curly braces. |
|---|
| 231 | | ``{{ article.headline }}`` means "Output the value of the article's headline |
|---|
| 232 | | attribute." But dots aren't used only for attribute lookup: They also can do |
|---|
| 233 | | dictionary-key lookup, index lookup and function calls (as is the case with |
|---|
| 234 | | ``article.get_reporter``). |
|---|
| | 231 | Variables are surrounded by double-curly braces. ``{{ article.headline }}`` |
|---|
| | 232 | means "Output the value of the article's headline attribute." But dots aren't |
|---|
| | 233 | used only for attribute lookup: They also can do dictionary-key lookup, index |
|---|
| | 234 | lookup and function calls (as is the case with ``article.get_reporter``). |
|---|
| 246 | | Finally, Django uses the concept of template inheritance: That's what the ``{% |
|---|
| 247 | | extends "base" %}`` does. It means "First load the template called 'base', which |
|---|
| 248 | | has defined a bunch of blocks, and fill the blocks with the following blocks." |
|---|
| 249 | | In short, that lets you dramatically cut down on redundancy in templates: Each |
|---|
| 250 | | template has to define only what's unique to that template. |
|---|
| 251 | | |
|---|
| 252 | | Here's what the "base" template might look like:: |
|---|
| | 246 | Finally, Django uses the concept of "template inheritance": That's what the |
|---|
| | 247 | ``{% extends "base.html" %}`` does. It means "First load the template called |
|---|
| | 248 | 'base', which has defined a bunch of blocks, and fill the blocks with the |
|---|
| | 249 | following blocks." In short, that lets you dramatically cut down on redundancy |
|---|
| | 250 | in templates: Each template has to define only what's unique to that template. |
|---|
| | 251 | |
|---|
| | 252 | Here's what the "base.html" template might look like:: |
|---|
| 271 | | have to use Django's API, either. You can use another database abstraction |
|---|
| 272 | | layer, you can read XML files, you can read files off disk, or anything you |
|---|
| 273 | | want. Each piece of Django -- models, views, templates -- is decoupled |
|---|
| 274 | | from the next. |
|---|
| | 276 | have to use Django's database API, either. You can use another database |
|---|
| | 277 | abstraction layer, you can read XML files, you can read files off disk, or |
|---|
| | 278 | anything you want. Each piece of Django -- models, views, templates -- is |
|---|
| | 279 | decoupled from the next. |
|---|