1
0
mirror of https://github.com/django/django.git synced 2025-07-05 02:09:13 +00:00

magic-removal: Fixed #1464 -- Updated tutorial01 for magic-removal. Thanks, Jeremy D.

git-svn-id: http://code.djangoproject.com/svn/django/branches/magic-removal@2527 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Adrian Holovaty 2006-03-17 05:43:37 +00:00
parent fd00f02ce0
commit 404421895a
3 changed files with 107 additions and 84 deletions

View File

@ -96,7 +96,7 @@ Also removes the content from any response to a HEAD request and sets the
``Date`` and ``Content-Length`` response-headers. ``Date`` and ``Content-Length`` response-headers.
django.contrib.sessions.middleware.SessionMiddleware django.contrib.sessions.middleware.SessionMiddleware
-------------------------------------------- ----------------------------------------------------
Enables session support. See the `session documentation`_. Enables session support. See the `session documentation`_.

View File

@ -256,7 +256,7 @@ Using a ``Context`` as a stack comes in handy in some custom template tags, as
you'll see below. you'll see below.
Subclassing Context: RequestContext Subclassing Context: RequestContext
---------------------------------- -----------------------------------
Django comes with a special ``Context`` class, Django comes with a special ``Context`` class,
``django.template.RequestContext``, that acts slightly differently than ``django.template.RequestContext``, that acts slightly differently than

View File

@ -72,8 +72,8 @@ command line::
Validating models... Validating models...
0 errors found. 0 errors found.
Starting server on port 8000 with settings module 'myproject.settings'. Django version 0.92, using settings 'myproject.settings'
Go to http://127.0.0.1:8000/ for Django. Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows). Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows).
(If you get an error about ``DATABASE_ENGINE``, edit your ``settings.py`` file (If you get an error about ``DATABASE_ENGINE``, edit your ``settings.py`` file
@ -124,30 +124,51 @@ database's connection parameters:
point. Do that with "``CREATE DATABASE database_name;``" within your point. Do that with "``CREATE DATABASE database_name;``" within your
database's interactive prompt. database's interactive prompt.
Run the following command to initialize your database with Django's core While you're editing ``settings.py``, take note of the ``INSTALLED_APPS``
database tables:: setting. That variable holds the names of all Django applications that are
activated in this Django instance. Apps can be used in multiple projects,
and you can distribute them.
python manage.py init By default, ``INSTALLED_APPS`` contains the following apps, all of which come
with Django::
If you don't see any errors, it worked. * ``django.contrib.auth`` -- An authentication system.
* ``django.contrib.contenttypes`` -- A framework for content types.
* ``django.contrib.sessions`` -- A session framework.
* ``django.contrib.sites`` -- A framework for managing multiple sites
with one Django installation.
These applications are included by default as a convenience for the common case.
Each of these applications makes use of at least one database table, though,
so we need to create the tables in the database before we can use them. To do
that, run the following command::
python manage.py syncdb
The ``syncdb`` command looks at the ``INSTALLED_APPS`` setting and creates any
necessary database tables according to the database settings in your
``settings.py`` file. You'll see a message for each database table it creates,
and you'll get a prompt asking you if you'd like to create a superuser account
for the authentication system. Go ahead and do that.
If you're interested, run the command-line client for your database and type If you're interested, run the command-line client for your database and type
``\dt`` (PostgreSQL), ``SHOW TABLES;`` (MySQL), or ``.schema`` (SQLite) to ``\dt`` (PostgreSQL), ``SHOW TABLES;`` (MySQL), or ``.schema`` (SQLite) to
display the tables Django created. display the tables Django created.
.. admonition:: About those database tables .. admonition:: For the minimalists
The tables created by ``manage.py init`` are for sessions, authentication Like we said above, the default applications are included for the common
and other features Django provides. The next release of Django will have case, but not everybody needs them. If you don't need any or all of them,
a "lite" version of the ``init`` command that won't install any database feel free to comment-out or delete the appropriate line(s) from
tables if you don't want them. ``INSTALLED_APPS`` before running ``syncdb``. The ``syncdb`` command will
only create tables for apps in ``INSTALLED_APPS``.
Creating models Creating models
=============== ===============
Now that your environment -- a "project" -- is set up, you're set to start Now that your environment -- a "project" -- is set up, you're set to start
doing work. (You won't have to take care of that boring administrative stuff doing work.
again.)
Each application you write in Django consists of a Python package, somewhere Each application you write in Django consists of a Python package, somewhere
on your `Python path`_, that follows a certain convention. Django comes with a on your `Python path`_, that follows a certain convention. Django comes with a
@ -176,9 +197,7 @@ That'll create a directory ``polls``, which is laid out like this::
polls/ polls/
__init__.py __init__.py
models/ models.py
__init__.py
polls.py
views.py views.py
This directory structure will house the poll application. This directory structure will house the poll application.
@ -198,28 +217,28 @@ a question and a publication date. A choice has two fields: the text of the
choice and a vote tally. Each choice is associated with a poll. choice and a vote tally. Each choice is associated with a poll.
These concepts are represented by simple Python classes. Edit the These concepts are represented by simple Python classes. Edit the
``polls/models/polls.py`` file so it looks like this:: ``polls/models.py`` file so it looks like this::
from django.core import meta from django.db import models
class Poll(meta.Model): class Poll(models.Model):
question = meta.CharField(maxlength=200) question = models.CharField(maxlength=200)
pub_date = meta.DateTimeField('date published') pub_date = models.DateTimeField('date published')
class Choice(meta.Model): class Choice(models.Model):
poll = meta.ForeignKey(Poll) poll = models.ForeignKey(Poll)
choice = meta.CharField(maxlength=200) choice = models.CharField(maxlength=200)
votes = meta.IntegerField() votes = models.IntegerField()
The code is straightforward. Each model is represented by a class that The code is straightforward. Each model is represented by a class that
subclasses ``django.core.meta.Model``. Each model has a number of class subclasses ``django.db.models.Model``. Each model has a number of class
variables, each of which represents a database field in the model. variables, each of which represents a database field in the model.
Each field is represented by an instance of a ``meta.*Field`` class -- e.g., Each field is represented by an instance of a ``models.*Field`` class -- e.g.,
``meta.CharField`` for character fields and ``meta.DateTimeField`` for ``models.CharField`` for character fields and ``models.DateTimeField`` for
datetimes. This tells Django what type of data each field holds. datetimes. This tells Django what type of data each field holds.
The name of each ``meta.*Field`` instance (e.g. ``question`` or ``pub_date`` ) The name of each ``models.*Field`` instance (e.g. ``question`` or ``pub_date`` )
is the field's name, in machine-friendly format. You'll use this value in your is the field's name, in machine-friendly format. You'll use this value in your
Python code, and your database will use it as the column name. Python code, and your database will use it as the column name.
@ -230,11 +249,11 @@ the machine-readable name. In this example, we've only defined a human-readable
name for ``Poll.pub_date``. For all other fields in this model, the field's name for ``Poll.pub_date``. For all other fields in this model, the field's
machine-readable name will suffice as its human-readable name. machine-readable name will suffice as its human-readable name.
Some ``meta.*Field`` classes have required elements. ``meta.CharField``, for Some ``Field`` classes have required elements. ``CharField``, for example,
example, requires that you give it a ``maxlength``. That's used not only in the requires that you give it a ``maxlength``. That's used not only in the database
database schema, but in validation, as we'll soon see. schema, but in validation, as we'll soon see.
Finally, note a relationship is defined, using ``meta.ForeignKey``. That tells Finally, note a relationship is defined, using ``models.ForeignKey``. That tells
Django each Choice is related to a single Poll. Django supports all the common Django each Choice is related to a single Poll. Django supports all the common
database relationships: many-to-ones, many-to-manys and one-to-ones. database relationships: many-to-ones, many-to-manys and one-to-ones.
@ -262,6 +281,10 @@ Edit the ``settings.py`` file again, and change the ``INSTALLED_APPS`` setting
to include the string ``'myproject.polls'``. So it'll look like this:: to include the string ``'myproject.polls'``. So it'll look like this::
INSTALLED_APPS = ( INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'myproject.polls', 'myproject.polls',
) )
@ -275,12 +298,12 @@ Now Django knows ``myproject`` includes the ``polls`` app. Let's run another com
You should see the following (the CREATE TABLE SQL statements for the polls app):: You should see the following (the CREATE TABLE SQL statements for the polls app)::
BEGIN; BEGIN;
CREATE TABLE "polls_polls" ( CREATE TABLE "polls_poll" (
"id" serial NOT NULL PRIMARY KEY, "id" serial NOT NULL PRIMARY KEY,
"question" varchar(200) NOT NULL, "question" varchar(200) NOT NULL,
"pub_date" timestamp with time zone NOT NULL "pub_date" timestamp with time zone NOT NULL
); );
CREATE TABLE "polls_choices" ( CREATE TABLE "polls_choice" (
"id" serial NOT NULL PRIMARY KEY, "id" serial NOT NULL PRIMARY KEY,
"poll_id" integer NOT NULL REFERENCES "polls_polls" ("id"), "poll_id" integer NOT NULL REFERENCES "polls_polls" ("id"),
"choice" varchar(200) NOT NULL, "choice" varchar(200) NOT NULL,
@ -291,12 +314,12 @@ You should see the following (the CREATE TABLE SQL statements for the polls app)
Note the following: Note the following:
* Table names are automatically generated by combining the name of the app * Table names are automatically generated by combining the name of the app
(``polls``) with a plural version of the object name (polls and choices). (``polls``) and the lowercase name of the model -- ``poll`` and
(You can override this behavior.) ``choice``. (You can override this behavior.)
* Primary keys (IDs) are added automatically. (You can override this, too.) * Primary keys (IDs) are added automatically. (You can override this, too.)
* Django appends ``"_id"`` to the foreign key field name, by convention. * By convention, Django appends ``"_id"`` to the foreign key field name.
Yes, you can override this, as well. Yes, you can override this, as well.
* The foreign key relationship is made explicit by a ``REFERENCES`` statement. * The foreign key relationship is made explicit by a ``REFERENCES`` statement.
@ -310,8 +333,8 @@ Note the following:
If you're interested, also run the following commands: If you're interested, also run the following commands:
* ``python manage.py sqlinitialdata polls`` -- Outputs the initial-data * ``python manage.py sqlinitialdata polls`` -- Outputs any initial data
inserts required for Django's admin framework. required for Django's admin framework and your models.
* ``python manage.py sqlclear polls`` -- Outputs the necessary ``DROP * ``python manage.py sqlclear polls`` -- Outputs the necessary ``DROP
TABLE`` statements for this app, according to which tables already exist TABLE`` statements for this app, according to which tables already exist
@ -326,14 +349,13 @@ If you're interested, also run the following commands:
Looking at the output of those commands can help you understand what's actually Looking at the output of those commands can help you understand what's actually
happening under the hood. happening under the hood.
Now, run this command to create the database tables for the polls app Now, run ``syncdb`` again to create those model tables in your database::
automatically::
python manage.py install polls python manage.py syncdb
Behind the scenes, all that command does is take the output of As a review, the ``syncdb`` command creates the tables for all apps in
``python manage.py sqlall polls`` and execute it in the database pointed-to by ``INSTALLED_APPS`` that don't already exist in your database. So you can run it
your Django settings file. again and again, and it'll always just create the tables that don't exist.
Read the `django-admin.py documentation`_ for full information on what the Read the `django-admin.py documentation`_ for full information on what the
``manage.py`` utility can do. ``manage.py`` utility can do.
@ -374,17 +396,16 @@ things:
Once you're in the shell, explore the database API:: Once you're in the shell, explore the database API::
# Modules are dynamically created within django.models. # Import the model classes we just wrote.
# Their names are plural versions of the model class names. >>> from myproject.polls.models import Poll, Choice
>>> from django.models.polls import polls, choices
# No polls are in the system yet. # No polls are in the system yet.
>>> polls.get_list() >>> Poll.objects.all()
[] []
# Create a new Poll. # Create a new Poll.
>>> from datetime import datetime >>> from datetime import datetime
>>> p = polls.Poll(question="What's up?", pub_date=datetime.now()) >>> p = Poll(question="What's up?", pub_date=datetime.now())
# Save the object into the database. You have to call save() explicitly. # Save the object into the database. You have to call save() explicitly.
>>> p.save() >>> p.save()
@ -407,20 +428,21 @@ Once you're in the shell, explore the database API::
>>> p.save() >>> p.save()
# get_list() displays all the polls in the database. # get_list() displays all the polls in the database.
>>> polls.get_list() >>> Poll.objects.all()
[<Poll object>] [<Poll object>]
Wait a minute. ``<Poll object>`` is, utterly, an unhelpful representation of Wait a minute. ``<Poll object>`` is, utterly, an unhelpful representation of
this object. Let's fix that by editing the polls model this object. Let's fix that by editing the polls model
(in the ``polls/models/polls.py`` file) and adding a ``__repr__()`` method to (in the ``polls/models.py`` file) and adding a ``__repr__()`` method to
both ``Poll`` and ``Choice``:: both ``Poll`` and ``Choice``::
class Poll(meta.Model): class Poll(models.Model):
# ... # ...
def __repr__(self): def __repr__(self):
return self.question return self.question
class Choice(meta.Model): class Choice(models.Model):
# ... # ...
def __repr__(self): def __repr__(self):
return self.choice return self.choice
@ -432,81 +454,82 @@ representations are used throughout Django's automatically-generated admin.
Note these are normal Python methods. Let's add a custom method, just for Note these are normal Python methods. Let's add a custom method, just for
demonstration:: demonstration::
class Poll(meta.Model): class Poll(models.Model):
# ... # ...
def was_published_today(self): def was_published_today(self):
import datetime
return self.pub_date.date() == datetime.date.today() return self.pub_date.date() == datetime.date.today()
Note ``import datetime`` wasn't necessary. Each model method has access to Note the addition of ``import datetime`` to reference Python's standard
a handful of commonly-used variables for convenience, including the ``datetime`` module.
``datetime`` module from the Python standard library.
Let's jump back into the Python interactive shell by running Let's jump back into the Python interactive shell by running
``python manage.py shell`` again:: ``python manage.py shell`` again::
>>> from django.models.polls import polls, choices >>> from myproject.polls.models import Poll, Choice
# Make sure our __repr__() addition worked. # Make sure our __repr__() addition worked.
>>> polls.get_list() >>> Poll.objects.all()
[What's up?] [What's up?]
# Django provides a rich database lookup API that's entirely driven by # Django provides a rich database lookup API that's entirely driven by
# keyword arguments. # keyword arguments.
>>> polls.get_object(id__exact=1) >>> Poll.objects.filter(id=1)
What's up? [What's up?]
>>> polls.get_object(question__startswith='What') >>> Poll.objects.filter(question__startswith='What')
What's up? [What's up?]
# Get the poll whose year is 2005. Of course, if you're going through this # Get the poll whose year is 2005. Of course, if you're going through this
# tutorial in another year, change as appropriate. # tutorial in another year, change as appropriate.
>>> polls.get_object(pub_date__year=2005) >>> Poll.objects.get(pub_date__year=2005)
What's up? What's up?
>>> polls.get_object(id__exact=2) >>> Poll.objects.get(id=2)
Traceback (most recent call last): Traceback (most recent call last):
... ...
PollDoesNotExist: Poll does not exist for {'id__exact': 2} DoesNotExist: Poll does not exist for {'id': 2}
>>> polls.get_list(question__startswith='What') >>> Poll.objects.filter(question__startswith='What')
[What's up?] [What's up?]
# Lookup by a primary key is the most common case, so Django provides a # Lookup by a primary key is the most common case, so Django provides a
# shortcut for primary-key exact lookups. # shortcut for primary-key exact lookups.
# The following is identical to polls.get_object(id__exact=1). # The following is identical to Poll.objects.get(id=1).
>>> polls.get_object(pk=1) >>> Poll.objects.get(pk=1)
What's up? What's up?
# Make sure our custom method worked. # Make sure our custom method worked.
>>> p = polls.get_object(pk=1) >>> p = Poll.objects.get(pk=1)
>>> p.was_published_today() >>> p.was_published_today()
False False
# Give the Poll a couple of Choices. Each one of these method calls does an # Give the Poll a couple of Choices. Each one of these method calls does an
# INSERT statement behind the scenes and returns the new Choice object. # INSERT statement behind the scenes and returns the new Choice object.
>>> p = polls.get_object(pk=1) >>> p = Poll.objects.get(pk=1)
>>> p.add_choice(choice='Not much', votes=0) >>> p.choice_set.add(choice='Not much', votes=0)
Not much Not much
>>> p.add_choice(choice='The sky', votes=0) >>> p.choice_set.add(choice='The sky', votes=0)
The sky The sky
>>> c = p.add_choice(choice='Just hacking again', votes=0) >>> c = p.choice_set.add(choice='Just hacking again', votes=0)
# Choice objects have API access to their related Poll objects. # Choice objects have API access to their related Poll objects.
>>> c.get_poll() >>> c.poll
What's up? What's up?
# And vice versa: Poll objects get access to Choice objects. # And vice versa: Poll objects get access to Choice objects.
>>> p.get_choice_list() >>> p.choice_set.all()
[Not much, The sky, Just hacking again] [Not much, The sky, Just hacking again]
>>> p.get_choice_count() >>> p.choice_set.all().count()
3 3
# The API automatically follows relationships as far as you need. # The API automatically follows relationships as far as you need.
# Use double underscores to separate relationships. # Use double underscores to separate relationships.
# This works as many levels deep as you want. There's no limit. # This works as many levels deep as you want. There's no limit.
# Find all Choices for any poll whose pub_date is in 2005. # Find all Choices for any poll whose pub_date is in 2005.
>>> choices.get_list(poll__pub_date__year=2005) >>> Choice.objects.filter(poll__pub_date__year=2005)
[Not much, The sky, Just hacking again] [Not much, The sky, Just hacking again]
# Let's delete one of the choices. Use delete() for that. # Let's delete one of the choices. Use delete() for that.
>>> c = p.get_choice(choice__startswith='Just hacking') >>> c = p.choice_set.filter(choice__startswith='Just hacking')
>>> c.delete() >>> c.delete()
For full details on the database API, see our `Database API reference`_. For full details on the database API, see our `Database API reference`_.