~ubuntu-branches/ubuntu/jaunty/python-django/jaunty

« back to all changes in this revision

Viewing changes to docs/tutorial01.txt

  • Committer: Bazaar Package Importer
  • Author(s): Scott James Remnant, Eddy Mulyono
  • Date: 2008-09-16 12:18:47 UTC
  • mfrom: (1.1.5 upstream) (4.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080916121847-mg225rg5mnsdqzr0
Tags: 1.0-1ubuntu1
* Merge from Debian (LP: #264191), remaining changes:
  - Run test suite on build.

[Eddy Mulyono]
* Update patch to workaround network test case failures.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
=====================================
2
 
Writing your first Django app, part 1
3
 
=====================================
4
 
 
5
 
Let's learn by example.
6
 
 
7
 
Throughout this tutorial, we'll walk you through the creation of a basic
8
 
poll application.
9
 
 
10
 
It'll consist of two parts:
11
 
 
12
 
    * A public site that lets people view polls and vote in them.
13
 
    * An admin site that lets you add, change and delete poll.
14
 
 
15
 
We'll assume you have `Django installed`_ already. You can tell Django is
16
 
installed by running the Python interactive interpreter and typing
17
 
``import django``. If that command runs successfully, with no errors, Django is
18
 
installed.
19
 
 
20
 
.. _`Django installed`: ../install/
21
 
 
22
 
.. admonition:: Where to get help:
23
 
 
24
 
    If you're having trouble going through this tutorial, please post a message
25
 
    to `django-users`_ or drop by `#django`_ on ``irc.freenode.net`` and we'll 
26
 
    try to help.
27
 
 
28
 
.. _django-users: http://groups.google.com/group/django-users 
29
 
.. _#django: irc://irc.freenode.net/django
30
 
 
31
 
Creating a project
32
 
==================
33
 
 
34
 
If this is your first time using Django, you'll have to take care of some
35
 
initial setup. Namely, you'll need to auto-generate some code that establishes
36
 
a Django *project* -- a collection of settings for an instance of Django,
37
 
including database configuration, Django-specific options and
38
 
application-specific settings.
39
 
 
40
 
From the command line, ``cd`` into a directory where you'd like to store your
41
 
code, then run the command ``django-admin.py startproject mysite``. This
42
 
will create a ``mysite`` directory in your current directory.
43
 
 
44
 
.. note::
45
 
    
46
 
    You'll need to avoid naming projects after built-in Python or Django
47
 
    components. In particular, this means you should avoid using names like
48
 
    ``django`` (which will conflict with Django itself) or ``site`` (which
49
 
    conflicts with a built-in Python package).
50
 
 
51
 
(``django-admin.py`` should be on your system path if you installed Django via
52
 
``python setup.py``. If it's not on your path, you can find it in
53
 
``site-packages/django/bin``, where ``site-packages`` is a directory within
54
 
your Python installation. Consider symlinking to ``django-admin.py`` from some
55
 
place on your path, such as ``/usr/local/bin``.)
56
 
 
57
 
.. admonition:: Where should this code live?
58
 
 
59
 
    If your background is in PHP, you're probably used to putting code under the
60
 
    Web server's document root (in a place such as ``/var/www``). With Django,
61
 
    you don't do that. It's not a good idea to put any of this Python code within
62
 
    your Web server's document root, because it risks the possibility that
63
 
    people may be able to view your code over the Web. That's not good for
64
 
    security.
65
 
 
66
 
    Put your code in some directory **outside** of the document root, such as
67
 
    ``/home/mycode``.
68
 
 
69
 
Let's look at what ``startproject`` created::
70
 
 
71
 
    mysite/
72
 
        __init__.py
73
 
        manage.py
74
 
        settings.py
75
 
        urls.py
76
 
 
77
 
These files are:
78
 
 
79
 
    * ``__init__.py``: An empty file that tells Python that this directory
80
 
      should be considered a Python package. (Read `more about packages`_ in the
81
 
      official Python docs if you're a Python beginner.)
82
 
    * ``manage.py``: A command-line utility that lets you interact with this
83
 
      Django project in various ways.
84
 
    * ``settings.py``: Settings/configuration for this Django project.
85
 
    * ``urls.py``: The URL declarations for this Django project; a "table of
86
 
      contents" of your Django-powered site.
87
 
 
88
 
.. _more about packages: http://docs.python.org/tut/node8.html#packages
89
 
 
90
 
The development server
91
 
----------------------
92
 
 
93
 
Let's verify this worked. Change into the ``mysite`` directory, if you
94
 
haven't already, and run the command ``python manage.py runserver``. You'll see
95
 
the following output on the command line::
96
 
 
97
 
    Validating models...
98
 
    0 errors found.
99
 
 
100
 
    Django version 0.95, using settings 'mysite.settings'
101
 
    Development server is running at http://127.0.0.1:8000/
102
 
    Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows).
103
 
 
104
 
You've started the Django development server, a lightweight Web server written
105
 
purely in Python. We've included this with Django so you can develop things
106
 
rapidly, without having to deal with configuring a production server -- such as
107
 
Apache -- until you're ready for production.
108
 
 
109
 
Now's a good time to note: DON'T use this server in anything resembling a
110
 
production environment. It's intended only for use while developing. (We're in
111
 
the business of making Web frameworks, not Web servers.)
112
 
 
113
 
Now that the server's running, visit http://127.0.0.1:8000/ with your Web
114
 
browser. You'll see a "Welcome to Django" page, in pleasant, light-blue pastel.
115
 
It worked!
116
 
 
117
 
.. admonition:: Changing the port
118
 
 
119
 
    By default, the ``runserver`` command starts the development server on port
120
 
    8000. If you want to change the server's port, pass it as a command-line
121
 
    argument. For instance, this command starts the server on port 8080::
122
 
 
123
 
        python manage.py runserver 8080
124
 
 
125
 
    Full docs for the development server are at `django-admin documentation`_.
126
 
 
127
 
.. _django-admin documentation: ../django_admin/
128
 
 
129
 
Database setup
130
 
--------------
131
 
 
132
 
Now, edit ``settings.py``. It's a normal Python module with module-level
133
 
variables representing Django settings. Change these settings to match your
134
 
database's connection parameters:
135
 
 
136
 
    * ``DATABASE_ENGINE`` -- Either 'postgresql', 'mysql' or 'sqlite3'.
137
 
      More coming soon.
138
 
    * ``DATABASE_NAME`` -- The name of your database, or the full (absolute)
139
 
      path to the database file if you're using SQLite.
140
 
    * ``DATABASE_USER`` -- Your database username (not used for SQLite).
141
 
    * ``DATABASE_PASSWORD`` -- Your database password (not used for SQLite).
142
 
    * ``DATABASE_HOST`` -- The host your database is on. Leave this as an
143
 
      empty string if your database server is on the same physical machine
144
 
      (not used for SQLite).
145
 
 
146
 
.. admonition:: Note
147
 
 
148
 
    If you're using PostgreSQL or MySQL, make sure you've created a database by
149
 
    this point. Do that with "``CREATE DATABASE database_name;``" within your
150
 
    database's interactive prompt.
151
 
 
152
 
While you're editing ``settings.py``, take note of the ``INSTALLED_APPS``
153
 
setting towards the bottom of the file. That variable holds the names of all
154
 
Django applications that are activated in this Django instance. Apps can be
155
 
used in multiple projects, and you can package and distribute them for use
156
 
by others in their projects.
157
 
 
158
 
By default, ``INSTALLED_APPS`` contains the following apps, all of which come
159
 
with Django:
160
 
 
161
 
    * ``django.contrib.auth`` -- An authentication system.
162
 
    * ``django.contrib.contenttypes`` -- A framework for content types.
163
 
    * ``django.contrib.sessions`` -- A session framework.
164
 
    * ``django.contrib.sites`` -- A framework for managing multiple sites
165
 
      with one Django installation.
166
 
 
167
 
These applications are included by default as a convenience for the common
168
 
case.
169
 
 
170
 
Each of these applications makes use of at least one database table, though,
171
 
so we need to create the tables in the database before we can use them. To do
172
 
that, run the following command::
173
 
 
174
 
    python manage.py syncdb
175
 
 
176
 
The ``syncdb`` command looks at the ``INSTALLED_APPS`` setting and creates any
177
 
necessary database tables according to the database settings in your
178
 
``settings.py`` file. You'll see a message for each database table it creates,
179
 
and you'll get a prompt asking you if you'd like to create a superuser account
180
 
for the authentication system. Go ahead and do that.
181
 
 
182
 
If you're interested, run the command-line client for your database and type
183
 
``\dt`` (PostgreSQL), ``SHOW TABLES;`` (MySQL), or ``.schema`` (SQLite) to
184
 
display the tables Django created.
185
 
 
186
 
.. admonition:: For the minimalists
187
 
 
188
 
    Like we said above, the default applications are included for the common
189
 
    case, but not everybody needs them. If you don't need any or all of them,
190
 
    feel free to comment-out or delete the appropriate line(s) from
191
 
    ``INSTALLED_APPS`` before running ``syncdb``. The ``syncdb`` command will
192
 
    only create tables for apps in ``INSTALLED_APPS``.
193
 
 
194
 
Creating models
195
 
===============
196
 
 
197
 
Now that your environment -- a "project" -- is set up, you're set to start
198
 
doing work.
199
 
 
200
 
Each application you write in Django consists of a Python package, somewhere
201
 
on your `Python path`_, that follows a certain convention. Django comes with a
202
 
utility that automatically generates the basic directory structure of an app,
203
 
so you can focus on writing code rather than creating directories.
204
 
 
205
 
.. admonition:: Projects vs. apps
206
 
 
207
 
    What's the difference between a project and an app? An app is a Web
208
 
    application that does something -- e.g., a weblog system, a database of
209
 
    public records or a simple poll app. A project is a collection of
210
 
    configuration and apps for a particular Web site. A project can contain
211
 
    multiple apps. An app can be in multiple projects.
212
 
 
213
 
In this tutorial, we'll create our poll app in the ``mysite`` directory,
214
 
for simplicity. As a consequence, the app will be coupled to the project --
215
 
that is, Python code within the poll app will refer to ``mysite.polls``.
216
 
Later in this tutorial, we'll discuss decoupling your apps for distribution.
217
 
 
218
 
To create your app, make sure you're in the ``mysite`` directory and type
219
 
this command::
220
 
 
221
 
    python manage.py startapp polls
222
 
 
223
 
That'll create a directory ``polls``, which is laid out like this::
224
 
 
225
 
    polls/
226
 
        __init__.py
227
 
        models.py
228
 
        views.py
229
 
 
230
 
This directory structure will house the poll application.
231
 
 
232
 
The first step in writing a database Web app in Django is to define your models
233
 
 
234
 
.. admonition:: Philosophy
235
 
 
236
 
   A model is the single, definitive source of data about your
237
 
   data. It contains the essential fields and behaviors of the data you're
238
 
   storing. Django follows the `DRY Principle`_. The goal is to define your
239
 
   data model in one place and automatically derive things from it.
240
 
 
241
 
In our simple poll app, we'll create two models: polls and choices. A poll has
242
 
a question and a publication date. A choice has two fields: the text of the
243
 
choice and a vote tally. Each choice is associated with a poll.
244
 
 
245
 
These concepts are represented by simple Python classes. Edit the
246
 
``polls/models.py`` file so it looks like this::
247
 
 
248
 
    from django.db import models
249
 
 
250
 
    class Poll(models.Model):
251
 
        question = models.CharField(maxlength=200)
252
 
        pub_date = models.DateTimeField('date published')
253
 
 
254
 
    class Choice(models.Model):
255
 
        poll = models.ForeignKey(Poll)
256
 
        choice = models.CharField(maxlength=200)
257
 
        votes = models.IntegerField()
258
 
 
259
 
The code is straightforward. Each model is represented by a class that
260
 
subclasses ``django.db.models.Model``. Each model has a number of class
261
 
variables, each of which represents a database field in the model.
262
 
 
263
 
Each field is represented by an instance of a ``models.*Field`` class -- e.g.,
264
 
``models.CharField`` for character fields and ``models.DateTimeField`` for
265
 
datetimes. This tells Django what type of data each field holds.
266
 
 
267
 
The name of each ``models.*Field`` instance (e.g. ``question`` or ``pub_date`` )
268
 
is the field's name, in machine-friendly format. You'll use this value in your
269
 
Python code, and your database will use it as the column name.
270
 
 
271
 
You can use an optional first positional argument to a ``Field`` to designate a
272
 
human-readable name. That's used in a couple of introspective parts of Django,
273
 
and it doubles as documentation. If this field isn't provided, Django will use
274
 
the machine-readable name. In this example, we've only defined a human-readable
275
 
name for ``Poll.pub_date``. For all other fields in this model, the field's
276
 
machine-readable name will suffice as its human-readable name.
277
 
 
278
 
Some ``Field`` classes have required elements. ``CharField``, for example,
279
 
requires that you give it a ``maxlength``. That's used not only in the database
280
 
schema, but in validation, as we'll soon see.
281
 
 
282
 
Finally, note a relationship is defined, using ``models.ForeignKey``. That tells
283
 
Django each Choice is related to a single Poll. Django supports all the common
284
 
database relationships: many-to-ones, many-to-manys and one-to-ones.
285
 
 
286
 
.. _`Python path`: http://docs.python.org/tut/node8.html#SECTION008110000000000000000
287
 
.. _DRY Principle: http://c2.com/cgi/wiki?DontRepeatYourself
288
 
 
289
 
Activating models
290
 
=================
291
 
 
292
 
That small bit of model code gives Django a lot of information. With it, Django
293
 
is able to:
294
 
 
295
 
    * Create a database schema (``CREATE TABLE`` statements) for this app.
296
 
    * Create a Python database-access API for accessing Poll and Choice objects.
297
 
 
298
 
But first we need to tell our project that the ``polls`` app is installed.
299
 
 
300
 
.. admonition:: Philosophy
301
 
 
302
 
    Django apps are "pluggable": You can use an app in multiple projects, and
303
 
    you can distribute apps, because they don't have to be tied to a given
304
 
    Django installation.
305
 
 
306
 
Edit the ``settings.py`` file again, and change the ``INSTALLED_APPS`` setting
307
 
to include the string ``'mysite.polls'``. So it'll look like this::
308
 
 
309
 
    INSTALLED_APPS = (
310
 
        'django.contrib.auth',
311
 
        'django.contrib.contenttypes',
312
 
        'django.contrib.sessions',
313
 
        'django.contrib.sites',
314
 
        'mysite.polls'
315
 
    )
316
 
 
317
 
Now Django knows ``mysite`` includes the ``polls`` app. Let's run another command::
318
 
 
319
 
    python manage.py sql polls
320
 
 
321
 
You should see the following (the CREATE TABLE SQL statements for the polls app)::
322
 
 
323
 
    BEGIN;
324
 
    CREATE TABLE "polls_poll" (
325
 
        "id" serial NOT NULL PRIMARY KEY,
326
 
        "question" varchar(200) NOT NULL,
327
 
        "pub_date" timestamp with time zone NOT NULL
328
 
    );
329
 
    CREATE TABLE "polls_choice" (
330
 
        "id" serial NOT NULL PRIMARY KEY,
331
 
        "poll_id" integer NOT NULL REFERENCES "polls_poll" ("id"),
332
 
        "choice" varchar(200) NOT NULL,
333
 
        "votes" integer NOT NULL
334
 
    );
335
 
    COMMIT;
336
 
 
337
 
Note the following:
338
 
 
339
 
    * Table names are automatically generated by combining the name of the app
340
 
      (``polls``) and the lowercase name of the model -- ``poll`` and
341
 
      ``choice``. (You can override this behavior.)
342
 
 
343
 
    * Primary keys (IDs) are added automatically. (You can override this, too.)
344
 
 
345
 
    * By convention, Django appends ``"_id"`` to the foreign key field name.
346
 
      Yes, you can override this, as well.
347
 
 
348
 
    * The foreign key relationship is made explicit by a ``REFERENCES`` statement.
349
 
 
350
 
    * It's tailored to the database you're using, so database-specific field
351
 
      types such as ``auto_increment`` (MySQL), ``serial`` (PostgreSQL), or
352
 
      ``integer primary key`` (SQLite) are handled for you automatically. Same
353
 
      goes for quoting of field names -- e.g., using double quotes or single
354
 
      quotes. The author of this tutorial runs PostgreSQL, so the example
355
 
      output is in PostgreSQL syntax.
356
 
 
357
 
    * The `sql` command doesn't actually run the SQL in your database - it just
358
 
      prints it to the screen so that you can see what SQL Django thinks is required.
359
 
      If you wanted to, you could copy and paste this SQL into your database prompt.
360
 
      However, as we will see shortly, Django provides an easier way of committing
361
 
      the SQL to the database.
362
 
 
363
 
If you're interested, also run the following commands:
364
 
    * ``python manage.py validate polls`` -- Checks for any errors in the
365
 
      construction of your models.
366
 
 
367
 
    * ``python manage.py sqlinitialdata polls`` -- Outputs any initial data
368
 
      required for Django's admin framework and your models.
369
 
 
370
 
    * ``python manage.py sqlclear polls`` -- Outputs the necessary ``DROP
371
 
      TABLE`` statements for this app, according to which tables already exist
372
 
      in your database (if any).
373
 
 
374
 
    * ``python manage.py sqlindexes polls`` -- Outputs the ``CREATE INDEX``
375
 
      statements for this app.
376
 
 
377
 
    * ``python manage.py sqlall polls`` -- A combination of all the SQL from
378
 
      the 'sql', 'sqlinitialdata', and 'sqlindexes' commands.
379
 
 
380
 
Looking at the output of those commands can help you understand what's actually
381
 
happening under the hood.
382
 
 
383
 
Now, run ``syncdb`` again to create those model tables in your database::
384
 
 
385
 
    python manage.py syncdb
386
 
 
387
 
The ``syncdb`` command runs the sql from 'sqlall' on your database for all apps
388
 
in ``INSTALLED_APPS`` that don't already exist in your database. This creates
389
 
all the tables, initial data and indexes for any apps you have added to your
390
 
project since the last time you ran syncdb. ``syncdb`` can be called as often
391
 
as you like, and it will only ever create the tables that don't exist.
392
 
 
393
 
Read the `django-admin.py documentation`_ for full information on what the
394
 
``manage.py`` utility can do.
395
 
 
396
 
.. _django-admin.py documentation: ../django_admin/
397
 
 
398
 
Playing with the API
399
 
====================
400
 
 
401
 
Now, let's hop into the interactive Python shell and play around with the free
402
 
API Django gives you. To invoke the Python shell, use this command::
403
 
 
404
 
    python manage.py shell
405
 
 
406
 
We're using this instead of simply typing "python", because ``manage.py`` sets
407
 
up the project's environment for you. "Setting up the environment" involves two
408
 
things:
409
 
 
410
 
    * Putting ``mysite`` on ``sys.path``. For flexibility, several pieces of
411
 
      Django refer to projects in Python dotted-path notation (e.g.
412
 
      ``'mysite.polls.models'``). In order for this to work, the
413
 
      ``mysite`` package has to be on ``sys.path``.
414
 
 
415
 
      We've already seen one example of this: the ``INSTALLED_APPS`` setting is
416
 
      a list of packages in dotted-path notation.
417
 
 
418
 
    * Setting the ``DJANGO_SETTINGS_MODULE`` environment variable, which gives
419
 
      Django the path to your ``settings.py`` file.
420
 
 
421
 
.. admonition:: Bypassing manage.py
422
 
 
423
 
    If you'd rather not use ``manage.py``, no problem. Just make sure
424
 
    ``mysite`` is at the root level on the Python path (i.e.,
425
 
    ``import mysite`` works) and set the ``DJANGO_SETTINGS_MODULE``
426
 
    environment variable to ``mysite.settings``.
427
 
 
428
 
    For more information on all of this, see the `django-admin.py documentation`_.
429
 
 
430
 
Once you're in the shell, explore the database API::
431
 
 
432
 
    # Import the model classes we just wrote.
433
 
    >>> from mysite.polls.models import Poll, Choice
434
 
 
435
 
    # No polls are in the system yet.
436
 
    >>> Poll.objects.all()
437
 
    []
438
 
 
439
 
    # Create a new Poll.
440
 
    >>> from datetime import datetime
441
 
    >>> p = Poll(question="What's up?", pub_date=datetime.now())
442
 
 
443
 
    # Save the object into the database. You have to call save() explicitly.
444
 
    >>> p.save()
445
 
 
446
 
    # Now it has an ID. Note that this might say "1L" instead of "1", depending
447
 
    # on which database you're using. That's no biggie; it just means your
448
 
    # database backend prefers to return integers as Python long integer
449
 
    # objects.
450
 
    >>> p.id
451
 
    1
452
 
 
453
 
    # Access database columns via Python attributes.
454
 
    >>> p.question
455
 
    "What's up?"
456
 
    >>> p.pub_date
457
 
    datetime.datetime(2005, 7, 15, 12, 00, 53)
458
 
 
459
 
    # Change values by changing the attributes, then calling save().
460
 
    >>> p.pub_date = datetime(2005, 4, 1, 0, 0)
461
 
    >>> p.save()
462
 
 
463
 
    # objects.all() displays all the polls in the database.
464
 
    >>> Poll.objects.all()
465
 
    [<Poll: Poll object>]
466
 
 
467
 
 
468
 
Wait a minute. ``<Poll: Poll object>`` is, utterly, an unhelpful
469
 
representation of this object. Let's fix that by editing the polls model (in
470
 
the ``polls/models.py`` file) and adding a ``__str__()`` method to both
471
 
``Poll`` and ``Choice``::
472
 
 
473
 
    class Poll(models.Model):
474
 
        # ...
475
 
        def __str__(self):
476
 
            return self.question
477
 
 
478
 
    class Choice(models.Model):
479
 
        # ...
480
 
        def __str__(self):
481
 
            return self.choice
482
 
 
483
 
It's important to add ``__str__()`` methods to your models, not only for your
484
 
own sanity when dealing with the interactive prompt, but also because objects'
485
 
representations are used throughout Django's automatically-generated admin.
486
 
 
487
 
Note these are normal Python methods. Let's add a custom method, just for
488
 
demonstration::
489
 
 
490
 
    import datetime
491
 
    # ...
492
 
    class Poll(models.Model):
493
 
        # ...
494
 
        def was_published_today(self):
495
 
            return self.pub_date.date() == datetime.date.today()
496
 
 
497
 
Note the addition of ``import datetime`` to reference Python's standard
498
 
``datetime`` module.
499
 
 
500
 
Let's jump back into the Python interactive shell by running
501
 
``python manage.py shell`` again::
502
 
 
503
 
    >>> from mysite.polls.models import Poll, Choice
504
 
 
505
 
    # Make sure our __str__() addition worked.
506
 
    >>> Poll.objects.all()
507
 
    [<Poll: What's up?>]
508
 
 
509
 
    # Django provides a rich database lookup API that's entirely driven by
510
 
    # keyword arguments.
511
 
    >>> Poll.objects.filter(id=1)
512
 
    [<Poll: What's up?>]
513
 
    >>> Poll.objects.filter(question__startswith='What')
514
 
    [<Poll: What's up?>]
515
 
 
516
 
    # Get the poll whose year is 2005. Of course, if you're going through this
517
 
    # tutorial in another year, change as appropriate.
518
 
    >>> Poll.objects.get(pub_date__year=2005)
519
 
    <Poll: What's up?>
520
 
 
521
 
    >>> Poll.objects.get(id=2)
522
 
    Traceback (most recent call last):
523
 
        ...
524
 
    DoesNotExist: Poll matching query does not exist.
525
 
 
526
 
    # Lookup by a primary key is the most common case, so Django provides a
527
 
    # shortcut for primary-key exact lookups.
528
 
    # The following is identical to Poll.objects.get(id=1).
529
 
    >>> Poll.objects.get(pk=1)
530
 
    <Poll: What's up?>
531
 
 
532
 
    # Make sure our custom method worked.
533
 
    >>> p = Poll.objects.get(pk=1)
534
 
    >>> p.was_published_today()
535
 
    False
536
 
 
537
 
    # Give the Poll a couple of Choices. The create call constructs a new
538
 
    # choice object, does the INSERT statement, adds the choice to the set
539
 
    # of available choices and returns the new Choice object.
540
 
    >>> p = Poll.objects.get(pk=1)
541
 
    >>> p.choice_set.create(choice='Not much', votes=0)
542
 
    <Choice: Not much>
543
 
    >>> p.choice_set.create(choice='The sky', votes=0)
544
 
    <Choice: The sky>
545
 
    >>> c = p.choice_set.create(choice='Just hacking again', votes=0)
546
 
 
547
 
    # Choice objects have API access to their related Poll objects.
548
 
    >>> c.poll
549
 
    <Poll: What's up?>
550
 
 
551
 
    # And vice versa: Poll objects get access to Choice objects.
552
 
    >>> p.choice_set.all()
553
 
    [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
554
 
    >>> p.choice_set.count()
555
 
    3
556
 
 
557
 
    # The API automatically follows relationships as far as you need.
558
 
    # Use double underscores to separate relationships.
559
 
    # This works as many levels deep as you want. There's no limit.
560
 
    # Find all Choices for any poll whose pub_date is in 2005.
561
 
    >>> Choice.objects.filter(poll__pub_date__year=2005)
562
 
    [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
563
 
 
564
 
    # Let's delete one of the choices. Use delete() for that.
565
 
    >>> c = p.choice_set.filter(choice__startswith='Just hacking')
566
 
    >>> c.delete()
567
 
 
568
 
For full details on the database API, see our `Database API reference`_.
569
 
 
570
 
When you're comfortable with the API, read `part 2 of this tutorial`_ to get
571
 
Django's automatic admin working.
572
 
 
573
 
.. _Database API reference: ../db_api/
574
 
.. _part 2 of this tutorial: ../tutorial2/