|
1 ================== |
|
2 Django at a glance |
|
3 ================== |
|
4 |
|
5 Because Django was developed in a fast-paced newsroom environment, it was |
|
6 designed to make common Web-development tasks fast and easy. Here's an informal |
|
7 overview of how to write a database-driven Web app with Django. |
|
8 |
|
9 The goal of this document is to give you enough technical specifics to |
|
10 understand how Django works, but this isn't intended to be a tutorial or |
|
11 reference -- but we've got both! When you're ready to start a project, you can |
|
12 :doc:`start with the tutorial </intro/tutorial01>` or :doc:`dive right into more |
|
13 detailed documentation </topics/index>`. |
|
14 |
|
15 Design your model |
|
16 ================= |
|
17 |
|
18 Although you can use Django without a database, it comes with an |
|
19 object-relational mapper in which you describe your database layout in Python |
|
20 code. |
|
21 |
|
22 The :doc:`data-model syntax </topics/db/models>` offers many rich ways of |
|
23 representing your models -- so far, it's been solving two years' worth of |
|
24 database-schema problems. Here's a quick example, which might be saved in |
|
25 the file ``mysite/news/models.py``:: |
|
26 |
|
27 class Reporter(models.Model): |
|
28 full_name = models.CharField(max_length=70) |
|
29 |
|
30 def __unicode__(self): |
|
31 return self.full_name |
|
32 |
|
33 class Article(models.Model): |
|
34 pub_date = models.DateTimeField() |
|
35 headline = models.CharField(max_length=200) |
|
36 content = models.TextField() |
|
37 reporter = models.ForeignKey(Reporter) |
|
38 |
|
39 def __unicode__(self): |
|
40 return self.headline |
|
41 |
|
42 Install it |
|
43 ========== |
|
44 |
|
45 Next, run the Django command-line utility to create the database tables |
|
46 automatically: |
|
47 |
|
48 .. code-block:: bash |
|
49 |
|
50 manage.py syncdb |
|
51 |
|
52 The :djadmin:`syncdb` command looks at all your available models and creates |
|
53 tables in your database for whichever tables don't already exist. |
|
54 |
|
55 Enjoy the free API |
|
56 ================== |
|
57 |
|
58 With that, you've got a free, and rich, :doc:`Python API </topics/db/queries>` to |
|
59 access your data. The API is created on the fly, no code generation necessary:: |
|
60 |
|
61 # Import the models we created from our "news" app |
|
62 >>> from news.models import Reporter, Article |
|
63 |
|
64 # No reporters are in the system yet. |
|
65 >>> Reporter.objects.all() |
|
66 [] |
|
67 |
|
68 # Create a new Reporter. |
|
69 >>> r = Reporter(full_name='John Smith') |
|
70 |
|
71 # Save the object into the database. You have to call save() explicitly. |
|
72 >>> r.save() |
|
73 |
|
74 # Now it has an ID. |
|
75 >>> r.id |
|
76 1 |
|
77 |
|
78 # Now the new reporter is in the database. |
|
79 >>> Reporter.objects.all() |
|
80 [<Reporter: John Smith>] |
|
81 |
|
82 # Fields are represented as attributes on the Python object. |
|
83 >>> r.full_name |
|
84 'John Smith' |
|
85 |
|
86 # Django provides a rich database lookup API. |
|
87 >>> Reporter.objects.get(id=1) |
|
88 <Reporter: John Smith> |
|
89 >>> Reporter.objects.get(full_name__startswith='John') |
|
90 <Reporter: John Smith> |
|
91 >>> Reporter.objects.get(full_name__contains='mith') |
|
92 <Reporter: John Smith> |
|
93 >>> Reporter.objects.get(id=2) |
|
94 Traceback (most recent call last): |
|
95 ... |
|
96 DoesNotExist: Reporter matching query does not exist. |
|
97 |
|
98 # Create an article. |
|
99 >>> from datetime import datetime |
|
100 >>> a = Article(pub_date=datetime.now(), headline='Django is cool', |
|
101 ... content='Yeah.', reporter=r) |
|
102 >>> a.save() |
|
103 |
|
104 # Now the article is in the database. |
|
105 >>> Article.objects.all() |
|
106 [<Article: Django is cool>] |
|
107 |
|
108 # Article objects get API access to related Reporter objects. |
|
109 >>> r = a.reporter |
|
110 >>> r.full_name |
|
111 'John Smith' |
|
112 |
|
113 # And vice versa: Reporter objects get API access to Article objects. |
|
114 >>> r.article_set.all() |
|
115 [<Article: Django is cool>] |
|
116 |
|
117 # The API follows relationships as far as you need, performing efficient |
|
118 # JOINs for you behind the scenes. |
|
119 # This finds all articles by a reporter whose name starts with "John". |
|
120 >>> Article.objects.filter(reporter__full_name__startswith="John") |
|
121 [<Article: Django is cool>] |
|
122 |
|
123 # Change an object by altering its attributes and calling save(). |
|
124 >>> r.full_name = 'Billy Goat' |
|
125 >>> r.save() |
|
126 |
|
127 # Delete an object with delete(). |
|
128 >>> r.delete() |
|
129 |
|
130 A dynamic admin interface: it's not just scaffolding -- it's the whole house |
|
131 ============================================================================ |
|
132 |
|
133 Once your models are defined, Django can automatically create a professional, |
|
134 production ready :doc:`administrative interface </ref/contrib/admin/index>` -- a Web |
|
135 site that lets authenticated users add, change and delete objects. It's as easy |
|
136 as registering your model in the admin site:: |
|
137 |
|
138 # In models.py... |
|
139 |
|
140 from django.db import models |
|
141 |
|
142 class Article(models.Model): |
|
143 pub_date = models.DateTimeField() |
|
144 headline = models.CharField(max_length=200) |
|
145 content = models.TextField() |
|
146 reporter = models.ForeignKey(Reporter) |
|
147 |
|
148 |
|
149 # In admin.py in the same directory... |
|
150 |
|
151 import models |
|
152 from django.contrib import admin |
|
153 |
|
154 admin.site.register(models.Article) |
|
155 |
|
156 The philosophy here is that your site is edited by a staff, or a client, or |
|
157 maybe just you -- and you don't want to have to deal with creating backend |
|
158 interfaces just to manage content. |
|
159 |
|
160 One typical workflow in creating Django apps is to create models and get the |
|
161 admin sites up and running as fast as possible, so your staff (or clients) can |
|
162 start populating data. Then, develop the way data is presented to the public. |
|
163 |
|
164 Design your URLs |
|
165 ================ |
|
166 |
|
167 A clean, elegant URL scheme is an important detail in a high-quality Web |
|
168 application. Django encourages beautiful URL design and doesn't put any cruft |
|
169 in URLs, like ``.php`` or ``.asp``. |
|
170 |
|
171 To design URLs for an app, you create a Python module called a :doc:`URLconf |
|
172 </topics/http/urls>`. A table of contents for your app, it contains a simple mapping |
|
173 between URL patterns and Python callback functions. URLconfs also serve to |
|
174 decouple URLs from Python code. |
|
175 |
|
176 Here's what a URLconf might look like for the ``Reporter``/``Article`` |
|
177 example above:: |
|
178 |
|
179 from django.conf.urls.defaults import * |
|
180 |
|
181 urlpatterns = patterns('', |
|
182 (r'^articles/(\d{4})/$', 'news.views.year_archive'), |
|
183 (r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'), |
|
184 (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'), |
|
185 ) |
|
186 |
|
187 The code above maps URLs, as simple regular expressions, to the location of |
|
188 Python callback functions ("views"). The regular expressions use parenthesis to |
|
189 "capture" values from the URLs. When a user requests a page, Django runs |
|
190 through each pattern, in order, and stops at the first one that matches the |
|
191 requested URL. (If none of them matches, Django calls a special-case 404 view.) |
|
192 This is blazingly fast, because the regular expressions are compiled at load |
|
193 time. |
|
194 |
|
195 Once one of the regexes matches, Django imports and calls the given view, which |
|
196 is a simple Python function. Each view gets passed a request object -- |
|
197 which contains request metadata -- and the values captured in the regex. |
|
198 |
|
199 For example, if a user requested the URL "/articles/2005/05/39323/", Django |
|
200 would call the function ``news.views.article_detail(request, |
|
201 '2005', '05', '39323')``. |
|
202 |
|
203 Write your views |
|
204 ================ |
|
205 |
|
206 Each view is responsible for doing one of two things: Returning an |
|
207 :class:`~django.http.HttpResponse` object containing the content for the |
|
208 requested page, or raising an exception such as :class:`~django.http.Http404`. |
|
209 The rest is up to you. |
|
210 |
|
211 Generally, a view retrieves data according to the parameters, loads a template |
|
212 and renders the template with the retrieved data. Here's an example view for |
|
213 ``year_archive`` from above:: |
|
214 |
|
215 def year_archive(request, year): |
|
216 a_list = Article.objects.filter(pub_date__year=year) |
|
217 return render_to_response('news/year_archive.html', {'year': year, 'article_list': a_list}) |
|
218 |
|
219 This example uses Django's :doc:`template system </topics/templates>`, which has |
|
220 several powerful features but strives to stay simple enough for non-programmers |
|
221 to use. |
|
222 |
|
223 Design your templates |
|
224 ===================== |
|
225 |
|
226 The code above loads the ``news/year_archive.html`` template. |
|
227 |
|
228 Django has a template search path, which allows you to minimize redundancy among |
|
229 templates. In your Django settings, you specify a list of directories to check |
|
230 for templates. If a template doesn't exist in the first directory, it checks the |
|
231 second, and so on. |
|
232 |
|
233 Let's say the ``news/article_detail.html`` template was found. Here's what that |
|
234 might look like: |
|
235 |
|
236 .. code-block:: html+django |
|
237 |
|
238 {% extends "base.html" %} |
|
239 |
|
240 {% block title %}Articles for {{ year }}{% endblock %} |
|
241 |
|
242 {% block content %} |
|
243 <h1>Articles for {{ year }}</h1> |
|
244 |
|
245 {% for article in article_list %} |
|
246 <p>{{ article.headline }}</p> |
|
247 <p>By {{ article.reporter.full_name }}</p> |
|
248 <p>Published {{ article.pub_date|date:"F j, Y" }}</p> |
|
249 {% endfor %} |
|
250 {% endblock %} |
|
251 |
|
252 Variables are surrounded by double-curly braces. ``{{ article.headline }}`` |
|
253 means "Output the value of the article's headline attribute." But dots aren't |
|
254 used only for attribute lookup: They also can do dictionary-key lookup, index |
|
255 lookup and function calls. |
|
256 |
|
257 Note ``{{ article.pub_date|date:"F j, Y" }}`` uses a Unix-style "pipe" (the "|" |
|
258 character). This is called a template filter, and it's a way to filter the value |
|
259 of a variable. In this case, the date filter formats a Python datetime object in |
|
260 the given format (as found in PHP's date function; yes, there is one good idea |
|
261 in PHP). |
|
262 |
|
263 You can chain together as many filters as you'd like. You can write custom |
|
264 filters. You can write custom template tags, which run custom Python code behind |
|
265 the scenes. |
|
266 |
|
267 Finally, Django uses the concept of "template inheritance": That's what the |
|
268 ``{% extends "base.html" %}`` does. It means "First load the template called |
|
269 'base', which has defined a bunch of blocks, and fill the blocks with the |
|
270 following blocks." In short, that lets you dramatically cut down on redundancy |
|
271 in templates: each template has to define only what's unique to that template. |
|
272 |
|
273 Here's what the "base.html" template might look like: |
|
274 |
|
275 .. code-block:: html+django |
|
276 |
|
277 <html> |
|
278 <head> |
|
279 <title>{% block title %}{% endblock %}</title> |
|
280 </head> |
|
281 <body> |
|
282 <img src="sitelogo.gif" alt="Logo" /> |
|
283 {% block content %}{% endblock %} |
|
284 </body> |
|
285 </html> |
|
286 |
|
287 Simplistically, it defines the look-and-feel of the site (with the site's logo), |
|
288 and provides "holes" for child templates to fill. This makes a site redesign as |
|
289 easy as changing a single file -- the base template. |
|
290 |
|
291 It also lets you create multiple versions of a site, with different base |
|
292 templates, while reusing child templates. Django's creators have used this |
|
293 technique to create strikingly different cell-phone editions of sites -- simply |
|
294 by creating a new base template. |
|
295 |
|
296 Note that you don't have to use Django's template system if you prefer another |
|
297 system. While Django's template system is particularly well-integrated with |
|
298 Django's model layer, nothing forces you to use it. For that matter, you don't |
|
299 have to use Django's database API, either. You can use another database |
|
300 abstraction layer, you can read XML files, you can read files off disk, or |
|
301 anything you want. Each piece of Django -- models, views, templates -- is |
|
302 decoupled from the next. |
|
303 |
|
304 This is just the surface |
|
305 ======================== |
|
306 |
|
307 This has been only a quick overview of Django's functionality. Some more useful |
|
308 features: |
|
309 |
|
310 * A :doc:`caching framework </topics/cache>` that integrates with memcached |
|
311 or other backends. |
|
312 |
|
313 * A :doc:`syndication framework </ref/contrib/syndication>` that makes |
|
314 creating RSS and Atom feeds as easy as writing a small Python class. |
|
315 |
|
316 * More sexy automatically-generated admin features -- this overview barely |
|
317 scratched the surface. |
|
318 |
|
319 The next obvious steps are for you to `download Django`_, read :doc:`the |
|
320 tutorial </intro/tutorial01>` and join `the community`_. Thanks for your |
|
321 interest! |
|
322 |
|
323 .. _download Django: http://www.djangoproject.com/download/ |
|
324 .. _the community: http://www.djangoproject.com/community/ |