Django

Code

root/django/branches/0.90-bugfixes/docs/tutorial01.txt

Revision 1258, 16.2 kB (checked in by adrian, 3 years ago)

Changed 'django-admin.py startapp' application template to use views.py instead of views package, for simplicity. Updated tutorial to reflect the change.

Line 
1 =====================================
2 Writing your first Django app, part 1
3 =====================================
4
5 By Adrian Holovaty <holovaty@gmail.com>
6
7 Let's learn by example.
8
9 Throughout this tutorial, we'll walk you through the creation of a simple Web
10 poll application.
11
12 It'll consist of two parts:
13
14 * A public site that lets people vote in polls and view poll results.
15 * An admin site that lets you add, change and delete polls behind the scenes.
16
17 We'll assume you have `Django installed`_ already.
18
19 .. _`Django installed`: http://www.djangoproject.com/documentation/install/
20
21 Initial setup
22 =============
23
24 If this is your first time using Django, you'll have to take care of some
25 initial setup.
26
27 Run the command ``django-admin.py startproject myproject``. That'll create a
28 ``myproject`` directory in your current directory.
29
30 (``django-admin.py`` should be on your system path if you installed Django via
31 its setup.py utility. If it's not on your path, you can find it in
32 ``site-packages/django/bin``; consider symlinking to it from some place
33 on your path, such as /usr/local/bin.)
34
35 A project is a collection of settings for an instance of Django -- including
36 database configuration, Django-specific options and application-specific
37 settings. Let's look at what ``startproject`` created::
38
39     myproject/
40         __init__.py
41         apps/
42             __init__.py
43         settings.py
44         urls.py
45
46 First, edit ``myproject/settings.py``. It's a normal Python module with
47 module-level variables representing Django settings. Edit the file and change
48 these settings to match your database's connection parameters:
49
50     * ``DATABASE_ENGINE`` -- Either 'postgresql', 'mysql' or 'sqlite3'.
51       More coming soon.
52     * ``DATABASE_NAME`` -- The name of your database, or the full (absolute)
53       path to the database file if you're using sqlite.
54     * ``DATABASE_USER`` -- Your database username (not used for sqlite).
55     * ``DATABASE_PASSWORD`` -- Your database password (not used for sqlite).
56     * ``DATABASE_HOST`` -- The host your database is on. Leave this as an
57       empty string if your database server is on the same physical machine
58       (not used for sqlite).
59
60 .. admonition:: Note
61
62     Make sure you've created a database within PostgreSQL or MySQL by this
63     point. Do that with "``CREATE DATABASE database_name;``" within your
64     database's interactive prompt.
65
66 Now, take a second to make sure ``myproject`` is on your Python path. You
67 can do this by copying ``myproject`` to Python's ``site-packages`` directory,
68 or you can do it by altering the ``PYTHONPATH`` environment variable. See the
69 `Python path documentation`_ for more information. If you opt to set the
70 ``PYTHONPATH`` environment variable, note that you'll need to set it to the
71 *parent* directory of ``myproject``. (You can test this by typing
72 "import myproject" into the Python interactive prompt.)
73
74 Run the following command::
75
76     django-admin.py init --settings=myproject.settings
77
78 The ``django-admin.py`` utility generally needs to know which settings module
79 you're using. Here, we're doing that by specifying ``settings=`` on the command
80 line, but that can get tedious. If you don't want to type ``settings=`` each
81 time, you can set the ``DJANGO_SETTINGS_MODULE`` environment variable. Here's
82 how you do that in the Bash shell on Unix::
83
84     export DJANGO_SETTINGS_MODULE=myproject.settings
85
86 On Windows, you'd use ``set`` instead::
87
88     set DJANGO_SETTINGS_MODULE=myproject.settings
89
90 If you don't see any errors after running ``django-admin.py init``, you know it
91 worked. That command initialized your database with Django's core database
92 tables. If you're interested, run the command-line client for your database and
93 type ``\dt`` (PostgreSQL), ``SHOW TABLES;`` (MySQL), or ``.schema`` (SQLite) to
94 display the tables.
95
96 .. _`Python path documentation`: http://docs.python.org/tut/node8.html#SECTION008110000000000000000
97 .. _Django's ticket system: http://code.djangoproject.com/report/1
98
99 Creating models
100 ===============
101
102 Now that your environment -- a "project" -- is set up, you're set to start
103 doing work. (You won't have to take care of this boring administrative stuff
104 again.)
105
106 Each application you write in Django -- e.g., a weblog system, a database of
107 public records or a simple poll app -- consists of a Python package, somewhere
108 on your Python path, that follows a certain convention. Django comes with a
109 utility that automatically generates the basic directory structure of an app,
110 so you can focus on writing code rather than creating directories.
111
112 In this tutorial, we'll create our poll app in the ``myproject/apps``
113 directory, for simplicity. As a consequence, the app will be coupled to the
114 project -- that is, Python code within the poll app will refer to
115 ``myproject.apps.polls``. Later in this tutorial, we'll discuss decoupling
116 your apps for distribution.
117
118 To create your app, change into the ``myproject/apps`` directory and type this
119 command::
120
121     django-admin.py startapp polls
122
123 (From now on, this tutorial will leave out the ``--settings`` parameter and
124 will assume you've either set your ``DJANGO_SETTINGS_MODULE`` environment
125 variable or included the ``--settings`` option in your call to the command.)
126
127 That'll create a directory structure like this::
128
129     polls/
130         __init__.py
131         models/
132             __init__.py
133             polls.py
134         views.py
135
136 This directory structure will house the poll application.
137
138 The first step in writing a database Web app in Django is to define your models
139 -- essentially, your database layout, with additional metadata.
140
141 .. admonition:: Philosophy
142
143    A model is the single, definitive source of data about your
144    data. It contains the essential fields and behaviors of the data you're
145    storing. Django follows the `DRY Principle`_. The goal is to define your
146    data model in one place and automatically derive things from it.
147
148 In our simple poll app, we'll create two models: polls and choices. A poll has
149 a question and a publication date. A choice has two fields: the text of the
150 choice and a vote tally. Each choice is associated with a poll.
151
152 These concepts are represented by simple Python classes. Edit the
153 ``polls/models/polls.py`` file so it looks like this::
154
155     from django.core import meta
156
157     class Poll(meta.Model):
158         question = meta.CharField(maxlength=200)
159         pub_date = meta.DateTimeField('date published')
160
161     class Choice(meta.Model):
162         poll = meta.ForeignKey(Poll)
163         choice = meta.CharField(maxlength=200)
164         votes = meta.IntegerField()
165
166 The code is straightforward. Each model is represented by a class that
167 subclasses ``django.core.meta.Model``. Each model has a number of class
168 variables, each of which represents a database field in the model.
169
170 Each field is represented by an instance of a ``meta.*Field`` class -- e.g.,
171 ``meta.CharField`` for character fields and ``meta.DateTimeField`` for
172 datetimes. This tells Django what type of data each field holds.
173
174 The name of each ``meta.*Field`` instance (e.g. ``question`` or ``pub_date`` )
175 is the field's name, in machine-friendly format. You'll use this value in your
176 Python code, and your database will use it as the column name.
177
178 You can use an optional first positional argument to a ``Field`` to designate a
179 human-readable name. That's used in a couple of introspective parts of Django,
180 and it doubles as documentation. If this field isn't provided, Django will use
181 the machine-readable name. In this example, we've only defined a human-readable
182 name for ``Poll.pub_date``. For all other fields in this model, the field's
183 machine-readable name will suffice as its human-readable name.
184
185 Some ``meta.*Field`` classes have required elements. ``meta.CharField``, for
186 example, requires that you give it a ``maxlength``. That's used not only in the
187 database schema, but in validation, as we'll soon see.
188
189 Finally, note a relationship is defined, using ``meta.ForeignKey``. That tells
190 Django each Choice is related to a single Poll. Django supports all the common
191 database relationships: many-to-ones, many-to-manys and one-to-ones.
192
193 .. _DRY Principle: http://c2.com/cgi/wiki?DontRepeatYourself
194
195 Activating models
196 =================
197
198 That small bit of model code gives Django a lot of information. With it, Django
199 is able to:
200
201 * Create a database schema (``CREATE TABLE`` statements) for this app.
202 * Create a Python database-access API for accessing Poll and Choice objects.
203
204 But first we need to tell our project that the ``polls`` app is installed.
205
206 .. admonition:: Philosophy
207
208    Django apps are "pluggable": You can use an app in multiple
209    projects, and you can distribute apps, because they don't have to be tied to
210    a given Django installation.
211
212 Edit the myproject/settings.py file again, and change the ``INSTALLED_APPS``
213 setting to include the string "myproject.apps.polls". So it'll look like this::
214
215     INSTALLED_APPS = (
216         'myproject.apps.polls',
217     )
218
219 (Don't forget the trailing comma because of Python's rules about single-value
220 tuples.)
221
222 Now Django knows myproject includes the polls app. Let's run another command::
223
224     django-admin.py sql polls
225
226 (Note that it doesn't matter which directory you're in when you run this command.)
227
228 You should see the following (the CREATE TABLE SQL statements for the polls app)::
229
230     BEGIN;
231     CREATE TABLE polls_polls (
232         id serial NOT NULL PRIMARY KEY,
233         question varchar(200) NOT NULL,
234         pub_date timestamp with time zone NOT NULL
235     );
236     CREATE TABLE polls_choices (
237         id serial NOT NULL PRIMARY KEY,
238         poll_id integer NOT NULL REFERENCES polls_polls (id),
239         choice varchar(200) NOT NULL,
240         votes integer NOT NULL
241     );
242     COMMIT;
243
244 Note the following:
245
246     * Table names are automatically generated by combining the name of the app
247       (polls) with a plural version of the object name (polls and choices). (You
248       can override this behavior.)
249
250     * Primary keys (IDs) are added automatically. (You can override this, too.)
251
252     * Django appends ``"_id"`` to the foreign key field name, by convention.
253       Yes, you can override this, as well.
254
255     * The foreign key relationship is made explicit by a ``REFERENCES`` statement.
256
257     * It's tailored to the database you're using, so database-specific field types
258       such as ``auto_increment`` (MySQL), ``serial`` (PostgreSQL), or ``integer
259       primary key`` (SQLite) are handled for you automatically. The author of
260       this tutorial runs PostgreSQL, so the example output is in PostgreSQL
261       syntax.
262
263 If you're interested, also run the following commands:
264
265     * ``django-admin.py sqlinitialdata polls`` -- Outputs the initial-data
266       inserts required for Django's admin framework.
267
268     * ``django-admin.py sqlclear polls`` -- Outputs the necessary ``DROP
269       TABLE`` statements for this app, according to which tables already exist
270       in your database (if any).
271
272     * ``django-admin.py sqlindexes polls`` -- Outputs the ``CREATE INDEX``
273       statements for this app.
274
275     * ``django-admin.py sqlall polls`` -- A combination of 'sql' and
276       'sqlinitialdata'.
277
278 Looking at the output of those commands can help you understand what's actually
279 happening under the hood.
280
281 Now, run this command to create the database tables for the polls app
282 automatically::
283
284     django-admin.py install polls
285
286 Behind the scenes, all that command does is take the output of
287 ``django-admin.py sqlall polls`` and execute it in the database pointed-to by
288 your Django settings file.
289
290 Read the `django-admin.py documentation`_ for full information on what this
291 utility can do.
292
293 .. _django-admin.py documentation: http://www.djangoproject.com/documentation/django_admin/
294
295 Playing with the API
296 ====================
297
298 Now, make sure your DJANGO_SETTINGS_MODULE environment variable is set (as
299 explained above), and open the Python interactive shell to play around with the
300 free Python API Django gives you::
301
302     # Modules are dynamically created within django.models.
303     # Their names are plural versions of the model class names.
304     >>> from django.models.polls import polls, choices
305
306     # No polls are in the system yet.
307     >>> polls.get_list()
308     []
309
310     # Create a new Poll.
311     >>> from datetime import datetime
312     >>> p = polls.Poll(question="What's up?", pub_date=datetime.now())
313
314     # Save the object into the database. You have to call save() explicitly.
315     >>> p.save()
316
317     # Now it has an ID.
318     >>> p.id
319     1
320
321     # Access database columns via Python attributes.
322     >>> p.question
323     "What's up?"
324     >>> p.pub_date
325     datetime.datetime(2005, 7, 15, 12, 00, 53)
326
327     # Change values by changing the attributes, then calling save().
328     >>> p.pub_date = datetime(2005, 4, 1, 0, 0)
329     >>> p.save()
330
331     # get_list() displays all the polls in the database.
332     >>> polls.get_list()
333     [<Poll object>]
334
335 Wait a minute. ``<Poll object>`` is, utterly, an unhelpful representation of
336 this object. Let's fix that by editing the polls model
337 (in the ``polls/models/polls.py`` file) and adding a ``__repr__()`` method to
338 both ``Poll`` and ``Choice``::
339
340     class Poll(meta.Model):
341         # ...
342         def __repr__(self):
343             return self.question
344
345     class Choice(meta.Model):
346         # ...
347         def __repr__(self):
348             return self.choice
349
350 It's important to add ``__repr__()`` methods to your models, not only for your
351 own sanity when dealing with the interactive prompt, but also because objects'
352 representations are used throughout Django's automatically-generated admin.
353
354 Note these are normal Python methods. Let's add a custom method, just for
355 demonstration::
356
357     class Poll(meta.Model):
358         # ...
359         def was_published_today(self):
360             return self.pub_date.date() == datetime.date.today()
361
362 Note ``import datetime`` wasn't necessary. Each model method has access to
363 a handful of commonly-used variables for convenience, including the
364 ``datetime`` module from the Python standard library.
365
366 Let's jump back into the Python interactive shell::
367
368     >>> from django.models.polls import polls, choices
369     # Make sure our __repr__() addition worked.
370     >>> polls.get_list()
371     [What's up?]
372
373     # Django provides a rich database lookup API that's entirely driven by
374     # keyword arguments.
375     >>> polls.get_object(id__exact=1)
376     What's up?
377     >>> polls.get_object(question__startswith='What')
378     What's up?
379     >>> polls.get_object(pub_date__year=2005)
380     What's up?
381     >>> polls.get_object(id__exact=2)
382     Traceback (most recent call last):
383         ...
384     PollDoesNotExist: Poll does not exist for {'id__exact': 2}
385     >>> polls.get_list(question__startswith='What')
386     [What's up?]
387
388     # Lookup by a primary key is the most common case, so Django provides a
389     # shortcut for primary-key exact lookups.
390     # The following is identical to polls.get_object(id__exact=1).
391     >>> polls.get_object(pk=1)
392     What's up?
393
394     # Make sure our custom method worked.
395     >>> p = polls.get_object(pk=1)
396     >>> p.was_published_today()
397     False
398
399     # Give the Poll a couple of Choices. Each one of these method calls does an
400     # INSERT statement behind the scenes and returns the new Choice object.
401     >>> p = polls.get_object(pk=1)
402     >>> p.add_choice(choice='Not much', votes=0)
403     Not much
404     >>> p.add_choice(choice='The sky', votes=0)
405     The sky
406     >>> c = p.add_choice(choice='Just hacking again', votes=0)
407
408     # Choice objects have API access to their related Poll objects.
409     >>> c.get_poll()
410     What's up?
411
412     # And vice versa: Poll objects get access to Choice objects.
413     >>> p.get_choice_list()
414     [Not much, The sky, Just hacking again]
415     >>> p.get_choice_count()
416     3
417
418     # The API automatically follows relationships as far as you need.
419     # Use double underscores to separate relationships.
420     # This works as many levels deep as you want. There's no limit.
421     # Find all Choices for any poll whose pub_date is in 2005.
422     >>> choices.get_list(poll__pub_date__year=2005)
423     [Not much, The sky, Just hacking again]
424
425     # Let's delete one of the choices. Use delete() for that.
426     >>> c = p.get_choice(choice__startswith='Just hacking')
427     >>> c.delete()
428
429 For full details on the database API, see our `Database API reference`_.
430
431 When you're comfortable with the API, read `part 2 of this tutorial`_ to get
432 Django's automatic admin working.
433
434 .. _Database API reference: http://www.djangoproject.com/documentation/db_api/
435 .. _part 2 of this tutorial: http://www.djangoproject.com/documentation/tutorial2/
Note: See TracBrowser for help on using the browser.