thirdparty/google_appengine/lib/django/docs/tutorial01.txt
changeset 109 620f9b141567
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/thirdparty/google_appengine/lib/django/docs/tutorial01.txt	Tue Aug 26 21:49:54 2008 +0000
@@ -0,0 +1,575 @@
+=====================================
+Writing your first Django app, part 1
+=====================================
+
+Let's learn by example.
+
+Throughout this tutorial, we'll walk you through the creation of a basic
+poll application.
+
+It'll consist of two parts:
+
+    * A public site that lets people view polls and vote in them.
+    * An admin site that lets you add, change and delete poll.
+
+We'll assume you have `Django installed`_ already. You can tell Django is
+installed by running the Python interactive interpreter and typing
+``import django``. If that command runs successfully, with no errors, Django is
+installed.
+
+.. _`Django installed`: ../install/
+
+.. admonition:: Where to get help:
+
+    If you're having trouble going through this tutorial, please post a message
+    to `django-users`_ or drop by `#django`_ on ``irc.freenode.net`` and we'll 
+    try to help.
+
+.. _django-users: http://groups.google.com/group/django-users 
+.. _#django: irc://irc.freenode.net/django
+
+Creating a project
+==================
+
+If this is your first time using Django, you'll have to take care of some
+initial setup. Namely, you'll need to auto-generate some code that establishes
+a Django *project* -- a collection of settings for an instance of Django,
+including database configuration, Django-specific options and
+application-specific settings.
+
+From the command line, ``cd`` into a directory where you'd like to store your
+code, then run the command ``django-admin.py startproject mysite``. This
+will create a ``mysite`` directory in your current directory.
+
+.. note::
+    
+    You'll need to avoid naming projects after built-in Python or Django
+    components. In particular, this means you should avoid using names like
+    ``django`` (which will conflict with Django itself) or ``site`` (which
+    conflicts with a built-in Python package).
+
+(``django-admin.py`` should be on your system path if you installed Django via
+``python setup.py``. If it's not on your path, you can find it in
+``site-packages/django/bin``, where ``site-packages`` is a directory within
+your Python installation. Consider symlinking to ``django-admin.py`` from some
+place on your path, such as ``/usr/local/bin``.)
+
+.. admonition:: Where should this code live?
+
+    If your background is in PHP, you're probably used to putting code under the
+    Web server's document root (in a place such as ``/var/www``). With Django,
+    you don't do that. It's not a good idea to put any of this Python code within
+    your Web server's document root, because it risks the possibility that
+    people may be able to view your code over the Web. That's not good for
+    security.
+
+    Put your code in some directory **outside** of the document root, such as
+    ``/home/mycode``.
+
+Let's look at what ``startproject`` created::
+
+    mysite/
+        __init__.py
+        manage.py
+        settings.py
+        urls.py
+
+These files are:
+
+    * ``__init__.py``: An empty file that tells Python that this directory
+      should be considered a Python package. (Read `more about packages`_ in the
+      official Python docs if you're a Python beginner.)
+    * ``manage.py``: A command-line utility that lets you interact with this
+      Django project in various ways.
+    * ``settings.py``: Settings/configuration for this Django project.
+    * ``urls.py``: The URL declarations for this Django project; a "table of
+      contents" of your Django-powered site.
+
+.. _more about packages: http://docs.python.org/tut/node8.html#packages
+
+The development server
+----------------------
+
+Let's verify this worked. Change into the ``mysite`` directory, if you
+haven't already, and run the command ``python manage.py runserver``. You'll see
+the following output on the command line::
+
+    Validating models...
+    0 errors found.
+
+    Django version 0.95, using settings 'mysite.settings'
+    Development server is running at http://127.0.0.1:8000/
+    Quit the server with CONTROL-C (Unix) or CTRL-BREAK (Windows).
+
+You've started the Django development server, a lightweight Web server written
+purely in Python. We've included this with Django so you can develop things
+rapidly, without having to deal with configuring a production server -- such as
+Apache -- until you're ready for production.
+
+Now's a good time to note: DON'T use this server in anything resembling a
+production environment. It's intended only for use while developing. (We're in
+the business of making Web frameworks, not Web servers.)
+
+Now that the server's running, visit http://127.0.0.1:8000/ with your Web
+browser. You'll see a "Welcome to Django" page, in pleasant, light-blue pastel.
+It worked!
+
+.. admonition:: Changing the port
+
+    By default, the ``runserver`` command starts the development server on port
+    8000. If you want to change the server's port, pass it as a command-line
+    argument. For instance, this command starts the server on port 8080::
+
+        python manage.py runserver 8080
+
+    Full docs for the development server are at `django-admin documentation`_.
+
+.. _django-admin documentation: ../django_admin/
+
+Database setup
+--------------
+
+Now, edit ``settings.py``. It's a normal Python module with module-level
+variables representing Django settings. Change these settings to match your
+database's connection parameters:
+
+    * ``DATABASE_ENGINE`` -- Either 'postgresql', 'mysql' or 'sqlite3'.
+      More coming soon.
+    * ``DATABASE_NAME`` -- The name of your database, or the full (absolute)
+      path to the database file if you're using SQLite.
+    * ``DATABASE_USER`` -- Your database username (not used for SQLite).
+    * ``DATABASE_PASSWORD`` -- Your database password (not used for SQLite).
+    * ``DATABASE_HOST`` -- The host your database is on. Leave this as an
+      empty string if your database server is on the same physical machine
+      (not used for SQLite).
+
+.. admonition:: Note
+
+    If you're using PostgreSQL or MySQL, make sure you've created a database by
+    this point. Do that with "``CREATE DATABASE database_name;``" within your
+    database's interactive prompt.
+
+While you're editing ``settings.py``, take note of the ``INSTALLED_APPS``
+setting towards the bottom of the file. 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 package and distribute them for use
+by others in their projects.
+
+By default, ``INSTALLED_APPS`` contains the following apps, all of which come
+with Django:
+
+    * ``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
+``\dt`` (PostgreSQL), ``SHOW TABLES;`` (MySQL), or ``.schema`` (SQLite) to
+display the tables Django created.
+
+.. admonition:: For the minimalists
+
+    Like we said above, the default applications are included for the common
+    case, but not everybody needs them. If you don't need any or all of them,
+    feel free to comment-out or delete the appropriate line(s) from
+    ``INSTALLED_APPS`` before running ``syncdb``. The ``syncdb`` command will
+    only create tables for apps in ``INSTALLED_APPS``.
+
+Creating models
+===============
+
+Now that your environment -- a "project" -- is set up, you're set to start
+doing work.
+
+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
+utility that automatically generates the basic directory structure of an app,
+so you can focus on writing code rather than creating directories.
+
+.. admonition:: Projects vs. apps
+
+    What's the difference between a project and an app? An app is a Web
+    application that does something -- e.g., a weblog system, a database of
+    public records or a simple poll app. A project is a collection of
+    configuration and apps for a particular Web site. A project can contain
+    multiple apps. An app can be in multiple projects.
+
+In this tutorial, we'll create our poll app in the ``mysite`` directory,
+for simplicity. As a consequence, the app will be coupled to the project --
+that is, Python code within the poll app will refer to ``mysite.polls``.
+Later in this tutorial, we'll discuss decoupling your apps for distribution.
+
+To create your app, make sure you're in the ``mysite`` directory and type
+this command::
+
+    python manage.py startapp polls
+
+That'll create a directory ``polls``, which is laid out like this::
+
+    polls/
+        __init__.py
+        models.py
+        views.py
+
+This directory structure will house the poll application.
+
+The first step in writing a database Web app in Django is to define your models
+-- essentially, your database layout, with additional metadata.
+
+.. admonition:: Philosophy
+
+   A model is the single, definitive source of data about your
+   data. It contains the essential fields and behaviors of the data you're
+   storing. Django follows the `DRY Principle`_. The goal is to define your
+   data model in one place and automatically derive things from it.
+
+In our simple poll app, we'll create two models: polls and choices. A poll has
+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.
+
+These concepts are represented by simple Python classes. Edit the
+``polls/models.py`` file so it looks like this::
+
+    from django.db import models
+
+    class Poll(models.Model):
+        question = models.CharField(maxlength=200)
+        pub_date = models.DateTimeField('date published')
+
+    class Choice(models.Model):
+        poll = models.ForeignKey(Poll)
+        choice = models.CharField(maxlength=200)
+        votes = models.IntegerField()
+
+The code is straightforward. Each model is represented by a class that
+subclasses ``django.db.models.Model``. Each model has a number of class
+variables, each of which represents a database field in the model.
+
+Each field is represented by an instance of a ``models.*Field`` class -- e.g.,
+``models.CharField`` for character fields and ``models.DateTimeField`` for
+datetimes. This tells Django what type of data each field holds.
+
+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
+Python code, and your database will use it as the column name.
+
+You can use an optional first positional argument to a ``Field`` to designate a
+human-readable name. That's used in a couple of introspective parts of Django,
+and it doubles as documentation. If this field isn't provided, Django will use
+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
+machine-readable name will suffice as its human-readable name.
+
+Some ``Field`` classes have required elements. ``CharField``, for example,
+requires that you give it a ``maxlength``. That's used not only in the database
+schema, but in validation, as we'll soon see.
+
+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
+database relationships: many-to-ones, many-to-manys and one-to-ones.
+
+.. _`Python path`: http://docs.python.org/tut/node8.html#SECTION008110000000000000000
+.. _DRY Principle: http://c2.com/cgi/wiki?DontRepeatYourself
+
+Activating models
+=================
+
+That small bit of model code gives Django a lot of information. With it, Django
+is able to:
+
+    * Create a database schema (``CREATE TABLE`` statements) for this app.
+    * Create a Python database-access API for accessing Poll and Choice objects.
+
+But first we need to tell our project that the ``polls`` app is installed.
+
+.. admonition:: Philosophy
+
+    Django apps are "pluggable": You can use an app in multiple projects, and
+    you can distribute apps, because they don't have to be tied to a given
+    Django installation.
+
+Edit the ``settings.py`` file again, and change the ``INSTALLED_APPS`` setting
+to include the string ``'mysite.polls'``. So it'll look like this::
+
+    INSTALLED_APPS = (
+        'django.contrib.auth',
+        'django.contrib.contenttypes',
+        'django.contrib.sessions',
+        'django.contrib.sites',
+        'mysite.polls'
+    )
+
+Now Django knows ``mysite`` includes the ``polls`` app. Let's run another command::
+
+    python manage.py sql polls
+
+You should see the following (the CREATE TABLE SQL statements for the polls app)::
+
+    BEGIN;
+    CREATE TABLE "polls_poll" (
+        "id" serial NOT NULL PRIMARY KEY,
+        "question" varchar(200) NOT NULL,
+        "pub_date" timestamp with time zone NOT NULL
+    );
+    CREATE TABLE "polls_choice" (
+        "id" serial NOT NULL PRIMARY KEY,
+        "poll_id" integer NOT NULL REFERENCES "polls_poll" ("id"),
+        "choice" varchar(200) NOT NULL,
+        "votes" integer NOT NULL
+    );
+    COMMIT;
+
+Note the following:
+
+    * Table names are automatically generated by combining the name of the app
+      (``polls``) and the lowercase name of the model -- ``poll`` and
+      ``choice``. (You can override this behavior.)
+
+    * Primary keys (IDs) are added automatically. (You can override this, too.)
+
+    * By convention, Django appends ``"_id"`` to the foreign key field name.
+      Yes, you can override this, as well.
+
+    * The foreign key relationship is made explicit by a ``REFERENCES`` statement.
+
+    * It's tailored to the database you're using, so database-specific field
+      types such as ``auto_increment`` (MySQL), ``serial`` (PostgreSQL), or
+      ``integer primary key`` (SQLite) are handled for you automatically. Same
+      goes for quoting of field names -- e.g., using double quotes or single
+      quotes. The author of this tutorial runs PostgreSQL, so the example
+      output is in PostgreSQL syntax.
+
+    * The `sql` command doesn't actually run the SQL in your database - it just
+      prints it to the screen so that you can see what SQL Django thinks is required.
+      If you wanted to, you could copy and paste this SQL into your database prompt.
+      However, as we will see shortly, Django provides an easier way of committing
+      the SQL to the database.
+
+If you're interested, also run the following commands:
+    * ``python manage.py validate polls`` -- Checks for any errors in the
+      construction of your models.
+
+    * ``python manage.py sqlinitialdata polls`` -- Outputs any initial data
+      required for Django's admin framework and your models.
+
+    * ``python manage.py sqlclear polls`` -- Outputs the necessary ``DROP
+      TABLE`` statements for this app, according to which tables already exist
+      in your database (if any).
+
+    * ``python manage.py sqlindexes polls`` -- Outputs the ``CREATE INDEX``
+      statements for this app.
+
+    * ``python manage.py sqlall polls`` -- A combination of all the SQL from
+      the 'sql', 'sqlinitialdata', and 'sqlindexes' commands.
+
+Looking at the output of those commands can help you understand what's actually
+happening under the hood.
+
+Now, run ``syncdb`` again to create those model tables in your database::
+
+    python manage.py syncdb
+
+The ``syncdb`` command runs the sql from 'sqlall' on your database for all apps
+in ``INSTALLED_APPS`` that don't already exist in your database. This creates
+all the tables, initial data and indexes for any apps you have added to your
+project since the last time you ran syncdb. ``syncdb`` can be called as often
+as you like, and it will only ever create the tables that don't exist.
+
+Read the `django-admin.py documentation`_ for full information on what the
+``manage.py`` utility can do.
+
+.. _django-admin.py documentation: ../django_admin/
+
+Playing with the API
+====================
+
+Now, let's hop into the interactive Python shell and play around with the free
+API Django gives you. To invoke the Python shell, use this command::
+
+    python manage.py shell
+
+We're using this instead of simply typing "python", because ``manage.py`` sets
+up the project's environment for you. "Setting up the environment" involves two
+things:
+
+    * Putting ``mysite`` on ``sys.path``. For flexibility, several pieces of
+      Django refer to projects in Python dotted-path notation (e.g.
+      ``'mysite.polls.models'``). In order for this to work, the
+      ``mysite`` package has to be on ``sys.path``.
+
+      We've already seen one example of this: the ``INSTALLED_APPS`` setting is
+      a list of packages in dotted-path notation.
+
+    * Setting the ``DJANGO_SETTINGS_MODULE`` environment variable, which gives
+      Django the path to your ``settings.py`` file.
+
+.. admonition:: Bypassing manage.py
+
+    If you'd rather not use ``manage.py``, no problem. Just make sure
+    ``mysite`` is at the root level on the Python path (i.e.,
+    ``import mysite`` works) and set the ``DJANGO_SETTINGS_MODULE``
+    environment variable to ``mysite.settings``.
+
+    For more information on all of this, see the `django-admin.py documentation`_.
+
+Once you're in the shell, explore the database API::
+
+    # Import the model classes we just wrote.
+    >>> from mysite.polls.models import Poll, Choice
+
+    # No polls are in the system yet.
+    >>> Poll.objects.all()
+    []
+
+    # Create a new Poll.
+    >>> from datetime import datetime
+    >>> p = Poll(question="What's up?", pub_date=datetime.now())
+
+    # Save the object into the database. You have to call save() explicitly.
+    >>> p.save()
+
+    # Now it has an ID. Note that this might say "1L" instead of "1", depending
+    # on which database you're using. That's no biggie; it just means your
+    # database backend prefers to return integers as Python long integer
+    # objects.
+    >>> p.id
+    1
+
+    # Access database columns via Python attributes.
+    >>> p.question
+    "What's up?"
+    >>> p.pub_date
+    datetime.datetime(2005, 7, 15, 12, 00, 53)
+
+    # Change values by changing the attributes, then calling save().
+    >>> p.pub_date = datetime(2005, 4, 1, 0, 0)
+    >>> p.save()
+
+    # objects.all() displays all the polls in the database.
+    >>> Poll.objects.all()
+    [<Poll: Poll object>]
+
+
+Wait a minute. ``<Poll: Poll object>`` is, utterly, an unhelpful
+representation of this object. Let's fix that by editing the polls model (in
+the ``polls/models.py`` file) and adding a ``__str__()`` method to both
+``Poll`` and ``Choice``::
+
+    class Poll(models.Model):
+        # ...
+        def __str__(self):
+            return self.question
+
+    class Choice(models.Model):
+        # ...
+        def __str__(self):
+            return self.choice
+
+It's important to add ``__str__()`` methods to your models, not only for your
+own sanity when dealing with the interactive prompt, but also because objects'
+representations are used throughout Django's automatically-generated admin.
+
+Note these are normal Python methods. Let's add a custom method, just for
+demonstration::
+
+    import datetime
+    # ...
+    class Poll(models.Model):
+        # ...
+        def was_published_today(self):
+            return self.pub_date.date() == datetime.date.today()
+
+Note the addition of ``import datetime`` to reference Python's standard
+``datetime`` module.
+
+Let's jump back into the Python interactive shell by running
+``python manage.py shell`` again::
+
+    >>> from mysite.polls.models import Poll, Choice
+
+    # Make sure our __str__() addition worked.
+    >>> Poll.objects.all()
+    [<Poll: What's up?>]
+
+    # Django provides a rich database lookup API that's entirely driven by
+    # keyword arguments.
+    >>> Poll.objects.filter(id=1)
+    [<Poll: What's up?>]
+    >>> Poll.objects.filter(question__startswith='What')
+    [<Poll: What's up?>]
+
+    # Get the poll whose year is 2005. Of course, if you're going through this
+    # tutorial in another year, change as appropriate.
+    >>> Poll.objects.get(pub_date__year=2005)
+    <Poll: What's up?>
+
+    >>> Poll.objects.get(id=2)
+    Traceback (most recent call last):
+        ...
+    DoesNotExist: Poll matching query does not exist.
+
+    # Lookup by a primary key is the most common case, so Django provides a
+    # shortcut for primary-key exact lookups.
+    # The following is identical to Poll.objects.get(id=1).
+    >>> Poll.objects.get(pk=1)
+    <Poll: What's up?>
+
+    # Make sure our custom method worked.
+    >>> p = Poll.objects.get(pk=1)
+    >>> p.was_published_today()
+    False
+
+    # Give the Poll a couple of Choices. The create call constructs a new
+    # choice object, does the INSERT statement, adds the choice to the set
+    # of available choices and returns the new Choice object.
+    >>> p = Poll.objects.get(pk=1)
+    >>> p.choice_set.create(choice='Not much', votes=0)
+    <Choice: Not much>
+    >>> p.choice_set.create(choice='The sky', votes=0)
+    <Choice: The sky>
+    >>> c = p.choice_set.create(choice='Just hacking again', votes=0)
+
+    # Choice objects have API access to their related Poll objects.
+    >>> c.poll
+    <Poll: What's up?>
+
+    # And vice versa: Poll objects get access to Choice objects.
+    >>> p.choice_set.all()
+    [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
+    >>> p.choice_set.count()
+    3
+
+    # The API automatically follows relationships as far as you need.
+    # Use double underscores to separate relationships.
+    # 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.
+    >>> Choice.objects.filter(poll__pub_date__year=2005)
+    [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]
+
+    # Let's delete one of the choices. Use delete() for that.
+    >>> c = p.choice_set.filter(choice__startswith='Just hacking')
+    >>> c.delete()
+
+For full details on the database API, see our `Database API reference`_.
+
+When you're comfortable with the API, read `part 2 of this tutorial`_ to get
+Django's automatic admin working.
+
+.. _Database API reference: ../db_api/
+.. _part 2 of this tutorial: ../tutorial2/