summaryrefslogtreecommitdiff
path: root/parts/django/docs/topics
diff options
context:
space:
mode:
Diffstat (limited to 'parts/django/docs/topics')
-rw-r--r--parts/django/docs/topics/auth.txt1612
-rw-r--r--parts/django/docs/topics/cache.txt917
-rw-r--r--parts/django/docs/topics/conditional-view-processing.txt199
-rw-r--r--parts/django/docs/topics/db/aggregation.txt378
-rw-r--r--parts/django/docs/topics/db/index.txt18
-rw-r--r--parts/django/docs/topics/db/managers.txt376
-rw-r--r--parts/django/docs/topics/db/models.txt1234
-rw-r--r--parts/django/docs/topics/db/multi-db.txt574
-rw-r--r--parts/django/docs/topics/db/optimization.txt260
-rw-r--r--parts/django/docs/topics/db/queries.txt1110
-rw-r--r--parts/django/docs/topics/db/sql.txt279
-rw-r--r--parts/django/docs/topics/db/transactions.txt328
-rw-r--r--parts/django/docs/topics/email.txt618
-rw-r--r--parts/django/docs/topics/files.txt147
-rw-r--r--parts/django/docs/topics/forms/formsets.txt440
-rw-r--r--parts/django/docs/topics/forms/index.txt402
-rw-r--r--parts/django/docs/topics/forms/media.txt309
-rw-r--r--parts/django/docs/topics/forms/modelforms.txt885
-rw-r--r--parts/django/docs/topics/generic-views.txt501
-rw-r--r--parts/django/docs/topics/http/_images/middleware.pngbin0 -> 56301 bytes
-rw-r--r--parts/django/docs/topics/http/file-uploads.txt394
-rw-r--r--parts/django/docs/topics/http/generic-views.txt5
-rw-r--r--parts/django/docs/topics/http/index.txt15
-rw-r--r--parts/django/docs/topics/http/middleware.txt179
-rw-r--r--parts/django/docs/topics/http/sessions.txt529
-rw-r--r--parts/django/docs/topics/http/shortcuts.txt229
-rw-r--r--parts/django/docs/topics/http/urls.txt890
-rw-r--r--parts/django/docs/topics/http/views.txt202
-rw-r--r--parts/django/docs/topics/i18n/deployment.txt191
-rw-r--r--parts/django/docs/topics/i18n/index.txt113
-rw-r--r--parts/django/docs/topics/i18n/internationalization.txt624
-rw-r--r--parts/django/docs/topics/i18n/localization.txt317
-rw-r--r--parts/django/docs/topics/index.txt27
-rw-r--r--parts/django/docs/topics/install.txt298
-rw-r--r--parts/django/docs/topics/pagination.txt281
-rw-r--r--parts/django/docs/topics/serialization.txt402
-rw-r--r--parts/django/docs/topics/settings.txt255
-rw-r--r--parts/django/docs/topics/signals.txt255
-rw-r--r--parts/django/docs/topics/templates.txt617
-rw-r--r--parts/django/docs/topics/testing.txt1613
40 files changed, 18023 insertions, 0 deletions
diff --git a/parts/django/docs/topics/auth.txt b/parts/django/docs/topics/auth.txt
new file mode 100644
index 0000000..a58e523
--- /dev/null
+++ b/parts/django/docs/topics/auth.txt
@@ -0,0 +1,1612 @@
+=============================
+User authentication in Django
+=============================
+
+.. module:: django.contrib.auth
+ :synopsis: Django's authentication framework.
+
+Django comes with a user authentication system. It handles user accounts,
+groups, permissions and cookie-based user sessions. This document explains how
+things work.
+
+Overview
+========
+
+The auth system consists of:
+
+ * Users
+ * Permissions: Binary (yes/no) flags designating whether a user may perform
+ a certain task.
+ * Groups: A generic way of applying labels and permissions to more than one
+ user.
+ * Messages: A simple way to queue messages for given users.
+
+.. deprecated:: 1.2
+ The Messages component of the auth system will be removed in Django 1.4.
+
+Installation
+============
+
+Authentication support is bundled as a Django application in
+``django.contrib.auth``. To install it, do the following:
+
+ 1. Put ``'django.contrib.auth'`` and ``'django.contrib.contenttypes'`` in
+ your :setting:`INSTALLED_APPS` setting.
+ (The :class:`~django.contrib.auth.models.Permission` model in
+ :mod:`django.contrib.auth` depends on :mod:`django.contrib.contenttypes`.)
+ 2. Run the command ``manage.py syncdb``.
+
+Note that the default :file:`settings.py` file created by
+:djadmin:`django-admin.py startproject <startproject>` includes
+``'django.contrib.auth'`` and ``'django.contrib.contenttypes'`` in
+:setting:`INSTALLED_APPS` for convenience. If your :setting:`INSTALLED_APPS`
+already contains these apps, feel free to run :djadmin:`manage.py syncdb
+<syncdb>` again; you can run that command as many times as you'd like, and each
+time it'll only install what's needed.
+
+The :djadmin:`syncdb` command creates the necessary database tables, creates
+permission objects for all installed apps that need 'em, and prompts you to
+create a superuser account the first time you run it.
+
+Once you've taken those steps, that's it.
+
+Users
+=====
+
+.. class:: models.User
+
+API reference
+-------------
+
+Fields
+~~~~~~
+
+.. class:: models.User
+
+ :class:`~django.contrib.auth.models.User` objects have the following
+ fields:
+
+ .. attribute:: models.User.username
+
+ Required. 30 characters or fewer. Alphanumeric characters only
+ (letters, digits and underscores).
+
+ .. versionchanged:: 1.2
+ Usernames may now contain ``@``, ``+``, ``.`` and ``-`` characters.
+
+ .. attribute:: models.User.first_name
+
+ Optional. 30 characters or fewer.
+
+ .. attribute:: models.User.last_name
+
+ Optional. 30 characters or fewer.
+
+ .. attribute:: models.User.email
+
+ Optional. E-mail address.
+
+ .. attribute:: models.User.password
+
+ Required. A hash of, and metadata about, the password. (Django doesn't
+ store the raw password.) Raw passwords can be arbitrarily long and can
+ contain any character. See the "Passwords" section below.
+
+ .. attribute:: models.User.is_staff
+
+ Boolean. Designates whether this user can access the admin site.
+
+ .. attribute:: models.User.is_active
+
+ Boolean. Designates whether this user account should be considered
+ active. We recommend that you set this flag to ``False`` instead of
+ deleting accounts; that way, if your applications have any foreign keys
+ to users, the foreign keys won't break.
+
+ This doesn't necessarily control whether or not the user can log in.
+ Authentication backends aren't required to check for the ``is_active``
+ flag, so if you want to reject a login based on ``is_active`` being
+ ``False``, it's up to you to check that in your own login view.
+ However, the :class:`~django.contrib.auth.forms.AuthenticationForm`
+ used by the :func:`~django.contrib.auth.views.login` view *does*
+ perform this check, as do the permission-checking methods such as
+ :meth:`~models.User.has_perm` and the authentication in the Django
+ admin. All of those functions/methods will return ``False`` for
+ inactive users.
+
+ .. attribute:: models.User.is_superuser
+
+ Boolean. Designates that this user has all permissions without
+ explicitly assigning them.
+
+ .. attribute:: models.User.last_login
+
+ A datetime of the user's last login. Is set to the current date/time by
+ default.
+
+ .. attribute:: models.User.date_joined
+
+ A datetime designating when the account was created. Is set to the
+ current date/time by default when the account is created.
+
+Methods
+~~~~~~~
+
+.. class:: models.User
+
+ :class:`~django.contrib.auth.models.User` objects have two many-to-many
+ fields: models.User. ``groups`` and ``user_permissions``.
+ :class:`~django.contrib.auth.models.User` objects can access their related
+ objects in the same way as any other :doc:`Django model
+ </topics/db/models>`:
+
+ .. code-block:: python
+
+ myuser.groups = [group_list]
+ myuser.groups.add(group, group, ...)
+ myuser.groups.remove(group, group, ...)
+ myuser.groups.clear()
+ myuser.user_permissions = [permission_list]
+ myuser.user_permissions.add(permission, permission, ...)
+ myuser.user_permissions.remove(permission, permission, ...)
+ myuser.user_permissions.clear()
+
+ In addition to those automatic API methods,
+ :class:`~django.contrib.auth.models.User` objects have the following custom
+ methods:
+
+ .. method:: models.User.is_anonymous()
+
+ Always returns ``False``. This is a way of differentiating
+ :class:`~django.contrib.auth.models.User` and
+ :class:`~django.contrib.auth.models.AnonymousUser` objects.
+ Generally, you should prefer using
+ :meth:`~django.contrib.auth.models.User.is_authenticated()` to this
+ method.
+
+ .. method:: models.User.is_authenticated()
+
+ Always returns ``True``. This is a way to tell if the user has been
+ authenticated. This does not imply any permissions, and doesn't check
+ if the user is active - it only indicates that the user has provided a
+ valid username and password.
+
+ .. method:: models.User.get_full_name()
+
+ Returns the :attr:`~django.contrib.auth.models.User.first_name` plus
+ the :attr:`~django.contrib.auth.models.User.last_name`, with a space in
+ between.
+
+ .. method:: models.User.set_password(raw_password)
+
+ Sets the user's password to the given raw string, taking care of the
+ password hashing. Doesn't save the
+ :class:`~django.contrib.auth.models.User` object.
+
+ .. method:: models.User.check_password(raw_password)
+
+ Returns ``True`` if the given raw string is the correct password for
+ the user. (This takes care of the password hashing in making the
+ comparison.)
+
+ .. method:: models.User.set_unusable_password()
+
+ .. versionadded:: 1.0
+
+ Marks the user as having no password set. This isn't the same as
+ having a blank string for a password.
+ :meth:`~django.contrib.auth.models.User.check_password()` for this user
+ will never return ``True``. Doesn't save the
+ :class:`~django.contrib.auth.models.User` object.
+
+ You may need this if authentication for your application takes place
+ against an existing external source such as an LDAP directory.
+
+ .. method:: models.User.has_usable_password()
+
+ .. versionadded:: 1.0
+
+ Returns ``False`` if
+ :meth:`~django.contrib.auth.models.User.set_unusable_password()` has
+ been called for this user.
+
+ .. method:: models.User.get_group_permissions(obj=None)
+
+ Returns a set of permission strings that the user has, through his/her
+ groups.
+
+ .. versionadded:: 1.2
+
+ If ``obj`` is passed in, only returns the group permissions for
+ this specific object.
+
+ .. method:: models.User.get_all_permissions(obj=None)
+
+ Returns a set of permission strings that the user has, both through
+ group and user permissions.
+
+ .. versionadded:: 1.2
+
+ If ``obj`` is passed in, only returns the permissions for this
+ specific object.
+
+ .. method:: models.User.has_perm(perm, obj=None)
+
+ Returns ``True`` if the user has the specified permission, where perm is
+ in the format ``"<app label>.<permission codename>"``. (see
+ `permissions`_ section below). If the user is inactive, this method will
+ always return ``False``.
+
+ .. versionadded:: 1.2
+
+ If ``obj`` is passed in, this method won't check for a permission for
+ the model, but for this specific object.
+
+ .. method:: models.User.has_perms(perm_list, obj=None)
+
+ Returns ``True`` if the user has each of the specified permissions,
+ where each perm is in the format
+ ``"<app label>.<permission codename>"``. If the user is inactive,
+ this method will always return ``False``.
+
+ .. versionadded:: 1.2
+
+ If ``obj`` is passed in, this method won't check for permissions for
+ the model, but for the specific object.
+
+ .. method:: models.User.has_module_perms(package_name)
+
+ Returns ``True`` if the user has any permissions in the given package
+ (the Django app label). If the user is inactive, this method will
+ always return ``False``.
+
+ .. method:: models.User.get_and_delete_messages()
+
+ Returns a list of :class:`~django.contrib.auth.models.Message` objects
+ in the user's queue and deletes the messages from the queue.
+
+ .. method:: models.User.email_user(subject, message, from_email=None)
+
+ Sends an e-mail to the user. If
+ :attr:`~django.contrib.auth.models.User.from_email` is ``None``, Django
+ uses the :setting:`DEFAULT_FROM_EMAIL`.
+
+ .. method:: models.User.get_profile()
+
+ Returns a site-specific profile for this user. Raises
+ :exc:`django.contrib.auth.models.SiteProfileNotAvailable` if the
+ current site doesn't allow profiles. For information on how to define a
+ site-specific user profile, see the section on `storing additional user
+ information`_ below.
+
+.. _storing additional user information: #storing-additional-information-about-users
+
+Manager functions
+~~~~~~~~~~~~~~~~~
+
+.. class:: models.UserManager
+
+ The :class:`~django.contrib.auth.models.User` model has a custom manager
+ that has the following helper functions:
+
+ .. method:: models.UserManager.create_user(username, email, password=None)
+
+ Creates, saves and returns a :class:`~django.contrib.auth.models.User`.
+
+ The :attr:`~django.contrib.auth.models.User.username` and
+ :attr:`~django.contrib.auth.models.User.password` are set as given. The
+ domain portion of :attr:`~django.contrib.auth.models.User.email` is
+ automatically convered to lowercase, and the returned
+ :class:`~django.contrib.auth.models.User` object will have
+ :attr:`~models.User.is_active` set to ``True``.
+
+ If no password is provided,
+ :meth:`~django.contrib.auth.models.User.set_unusable_password()` will
+ be called.
+
+ See `Creating users`_ for example usage.
+
+ .. method:: models.UserManager.make_random_password(length=10, allowed_chars='abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789')
+
+ Returns a random password with the given length and given string of
+ allowed characters. (Note that the default value of ``allowed_chars``
+ doesn't contain letters that can cause user confusion, including:
+
+ * ``i``, ``l``, ``I``, and ``1`` (lowercase letter i, lowercase
+ letter L, uppercase letter i, and the number one)
+ * ``o``, ``O``, and ``0`` (uppercase letter o, lowercase letter o,
+ and zero)
+
+Basic usage
+-----------
+
+.. _topics-auth-creating-users:
+
+Creating users
+~~~~~~~~~~~~~~
+
+The most basic way to create users is to use the
+:meth:`~django.contrib.auth.models.UserManager.create_user` helper function
+that comes with Django::
+
+ >>> from django.contrib.auth.models import User
+ >>> user = User.objects.create_user('john', 'lennon@thebeatles.com', 'johnpassword')
+
+ # At this point, user is a User object that has already been saved
+ # to the database. You can continue to change its attributes
+ # if you want to change other fields.
+ >>> user.is_staff = True
+ >>> user.save()
+
+You can also create users using the Django admin site. Assuming you've enabled
+the admin site and hooked it to the URL ``/admin/``, the "Add user" page is at
+``/admin/auth/user/add/``. You should also see a link to "Users" in the "Auth"
+section of the main admin index page. The "Add user" admin page is different
+than standard admin pages in that it requires you to choose a username and
+password before allowing you to edit the rest of the user's fields.
+
+Also note: if you want your own user account to be able to create users using
+the Django admin site, you'll need to give yourself permission to add users
+*and* change users (i.e., the "Add user" and "Change user" permissions). If
+your account has permission to add users but not to change them, you won't be
+able to add users. Why? Because if you have permission to add users, you have
+the power to create superusers, which can then, in turn, change other users. So
+Django requires add *and* change permissions as a slight security measure.
+
+Changing passwords
+~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.2
+ The ``manage.py changepassword`` command was added.
+
+:djadmin:`manage.py changepassword *username* <changepassword>` offers a method
+of changing a User's password from the command line. It prompts you to
+change the password of a given user which you must enter twice. If
+they both match, the new password will be changed immediately. If you
+do not supply a user, the command will attempt to change the password
+whose username matches the current user.
+
+You can also change a password programmatically, using
+:meth:`~django.contrib.auth.models.User.set_password()`:
+
+.. code-block:: python
+
+ >>> from django.contrib.auth.models import User
+ >>> u = User.objects.get(username__exact='john')
+ >>> u.set_password('new password')
+ >>> u.save()
+
+Don't set the :attr:`~django.contrib.auth.models.User.password` attribute
+directly unless you know what you're doing. This is explained in the next
+section.
+
+Passwords
+---------
+
+The :attr:`~django.contrib.auth.models.User.password` attribute of a
+:class:`~django.contrib.auth.models.User` object is a string in this format::
+
+ hashtype$salt$hash
+
+That's hashtype, salt and hash, separated by the dollar-sign character.
+
+Hashtype is either ``sha1`` (default), ``md5`` or ``crypt`` -- the algorithm
+used to perform a one-way hash of the password. Salt is a random string used
+to salt the raw password to create the hash. Note that the ``crypt`` method is
+only supported on platforms that have the standard Python ``crypt`` module
+available.
+
+.. versionadded:: 1.0
+ Support for the ``crypt`` module is new in Django 1.0.
+
+For example::
+
+ sha1$a1976$a36cc8cbf81742a8fb52e221aaeab48ed7f58ab4
+
+The :meth:`~django.contrib.auth.models.User.set_password` and
+:meth:`~django.contrib.auth.models.User.check_password` functions handle the
+setting and checking of these values behind the scenes.
+
+Previous Django versions, such as 0.90, used simple MD5 hashes without password
+salts. For backwards compatibility, those are still supported; they'll be
+converted automatically to the new style the first time
+:meth:`~django.contrib.auth.models.User.check_password()` works correctly for
+a given user.
+
+Anonymous users
+---------------
+
+.. class:: models.AnonymousUser
+
+ :class:`django.contrib.auth.models.AnonymousUser` is a class that
+ implements the :class:`django.contrib.auth.models.User` interface, with
+ these differences:
+
+ * :attr:`~django.contrib.auth.models.User.id` is always ``None``.
+ * :attr:`~django.contrib.auth.models.User.is_staff` and
+ :attr:`~django.contrib.auth.models.User.is_superuser` are always
+ ``False``.
+ * :attr:`~django.contrib.auth.models.User.is_active` is always ``False``.
+ * :attr:`~django.contrib.auth.models.User.groups` and
+ :attr:`~django.contrib.auth.models.User.user_permissions` are always
+ empty.
+ * :meth:`~django.contrib.auth.models.User.is_anonymous()` returns ``True``
+ instead of ``False``.
+ * :meth:`~django.contrib.auth.models.User.is_authenticated()` returns
+ ``False`` instead of ``True``.
+ * :meth:`~django.contrib.auth.models.User.set_password()`,
+ :meth:`~django.contrib.auth.models.User.check_password()`,
+ :meth:`~django.contrib.auth.models.User.save()`,
+ :meth:`~django.contrib.auth.models.User.delete()`,
+ :meth:`~django.contrib.auth.models.User.set_groups()` and
+ :meth:`~django.contrib.auth.models.User.set_permissions()` raise
+ :exc:`NotImplementedError`.
+
+In practice, you probably won't need to use
+:class:`~django.contrib.auth.models.AnonymousUser` objects on your own, but
+they're used by Web requests, as explained in the next section.
+
+.. _topics-auth-creating-superusers:
+
+Creating superusers
+-------------------
+
+.. versionadded:: 1.0
+ The ``manage.py createsuperuser`` command is new.
+
+:djadmin:`manage.py syncdb <syncdb>` prompts you to create a superuser the
+first time you run it after adding ``'django.contrib.auth'`` to your
+:setting:`INSTALLED_APPS`. If you need to create a superuser at a later date,
+you can use a command line utility::
+
+ manage.py createsuperuser --username=joe --email=joe@example.com
+
+You will be prompted for a password. After you enter one, the user will be
+created immediately. If you leave off the :djadminopt:`--username` or the
+:djadminopt:`--email` options, it will prompt you for those values.
+
+If you're using an older release of Django, the old way of creating a superuser
+on the command line still works::
+
+ python /path/to/django/contrib/auth/create_superuser.py
+
+...where :file:`/path/to` is the path to the Django codebase on your
+filesystem. The ``manage.py`` command is preferred because it figures out the
+correct path and environment for you.
+
+.. _auth-profiles:
+
+Storing additional information about users
+------------------------------------------
+
+If you'd like to store additional information related to your users, Django
+provides a method to specify a site-specific related model -- termed a "user
+profile" -- for this purpose.
+
+To make use of this feature, define a model with fields for the
+additional information you'd like to store, or additional methods
+you'd like to have available, and also add a
+:class:`~django.db.models.Field.OneToOneField` from your model to the
+:class:`~django.contrib.auth.models.User` model. This will ensure only
+one instance of your model can be created for each
+:class:`~django.contrib.auth.models.User`.
+
+To indicate that this model is the user profile model for a given site, fill in
+the setting :setting:`AUTH_PROFILE_MODULE` with a string consisting of the
+following items, separated by a dot:
+
+1. The name of the application (case sensitive) in which the user
+ profile model is defined (in other words, the
+ name which was passed to :djadmin:`manage.py startapp <startapp>` to create
+ the application).
+
+2. The name of the model (not case sensitive) class.
+
+For example, if the profile model was a class named ``UserProfile`` and was
+defined inside an application named ``accounts``, the appropriate setting would
+be::
+
+ AUTH_PROFILE_MODULE = 'accounts.UserProfile'
+
+When a user profile model has been defined and specified in this manner, each
+:class:`~django.contrib.auth.models.User` object will have a method --
+:class:`~django.contrib.auth.models.User.get_profile()` -- which returns the
+instance of the user profile model associated with that
+:class:`~django.contrib.auth.models.User`.
+
+The method :class:`~django.contrib.auth.models.User.get_profile()`
+does not create the profile, if it does not exist. You need to
+register a handler for the signal
+:attr:`django.db.models.signals.post_save` on the User model, and, in
+the handler, if created=True, create the associated user profile.
+
+For more information, see `Chapter 12 of the Django book`_.
+
+.. _Chapter 12 of the Django book: http://www.djangobook.com/en/1.0/chapter12/#cn222
+
+Authentication in Web requests
+==============================
+
+Until now, this document has dealt with the low-level APIs for manipulating
+authentication-related objects. On a higher level, Django can hook this
+authentication framework into its system of
+:class:`request objects <django.http.HttpRequest>`.
+
+First, install the
+:class:`~django.contrib.sessions.middleware.SessionMiddleware` and
+:class:`~django.contrib.auth.middleware.AuthenticationMiddleware`
+middlewares by adding them to your :setting:`MIDDLEWARE_CLASSES` setting. See
+the :doc:`session documentation </topics/http/sessions>` for more information.
+
+Once you have those middlewares installed, you'll be able to access
+:attr:`request.user <django.http.HttpRequest.user>` in views.
+:attr:`request.user <django.http.HttpRequest.user>` will give you a
+:class:`~django.contrib.auth.models.User` object representing the currently
+logged-in user. If a user isn't currently logged in,
+:attr:`request.user <django.http.HttpRequest.user>` will be set to an instance
+of :class:`~django.contrib.auth.models.AnonymousUser` (see the previous
+section). You can tell them apart with
+:meth:`~django.contrib.auth.models.User.is_authenticated()`, like so::
+
+ if request.user.is_authenticated():
+ # Do something for authenticated users.
+ else:
+ # Do something for anonymous users.
+
+.. _how-to-log-a-user-in:
+
+How to log a user in
+--------------------
+
+Django provides two functions in :mod:`django.contrib.auth`:
+:func:`~django.contrib.auth.authenticate()` and
+:func:`~django.contrib.auth.login()`.
+
+.. function:: authenticate()
+
+ To authenticate a given username and password, use
+ :func:`~django.contrib.auth.authenticate()`. It takes two keyword
+ arguments, ``username`` and ``password``, and it returns a
+ :class:`~django.contrib.auth.models.User` object if the password is valid
+ for the given username. If the password is invalid,
+ :func:`~django.contrib.auth.authenticate()` returns ``None``. Example::
+
+ from django.contrib.auth import authenticate
+ user = authenticate(username='john', password='secret')
+ if user is not None:
+ if user.is_active:
+ print "You provided a correct username and password!"
+ else:
+ print "Your account has been disabled!"
+ else:
+ print "Your username and password were incorrect."
+
+.. function:: login()
+
+ To log a user in, in a view, use :func:`~django.contrib.auth.login()`. It
+ takes an :class:`~django.http.HttpRequest` object and a
+ :class:`~django.contrib.auth.models.User` object.
+ :func:`~django.contrib.auth.login()` saves the user's ID in the session,
+ using Django's session framework, so, as mentioned above, you'll need to
+ make sure to have the session middleware installed.
+
+ This example shows how you might use both
+ :func:`~django.contrib.auth.authenticate()` and
+ :func:`~django.contrib.auth.login()`::
+
+ from django.contrib.auth import authenticate, login
+
+ def my_view(request):
+ username = request.POST['username']
+ password = request.POST['password']
+ user = authenticate(username=username, password=password)
+ if user is not None:
+ if user.is_active:
+ login(request, user)
+ # Redirect to a success page.
+ else:
+ # Return a 'disabled account' error message
+ else:
+ # Return an 'invalid login' error message.
+
+.. admonition:: Calling ``authenticate()`` first
+
+ When you're manually logging a user in, you *must* call
+ :func:`~django.contrib.auth.authenticate()` before you call
+ :func:`~django.contrib.auth.login()`.
+ :func:`~django.contrib.auth.authenticate()`
+ sets an attribute on the :class:`~django.contrib.auth.models.User` noting
+ which authentication backend successfully authenticated that user (see the
+ `backends documentation`_ for details), and this information is needed
+ later during the login process.
+
+.. _backends documentation: #other-authentication-sources
+
+Manually checking a user's password
+-----------------------------------
+
+.. function:: check_password()
+
+ If you'd like to manually authenticate a user by comparing a plain-text
+ password to the hashed password in the database, use the convenience
+ function :func:`django.contrib.auth.models.check_password`. It takes two
+ arguments: the plain-text password to check, and the full value of a user's
+ ``password`` field in the database to check against, and returns ``True``
+ if they match, ``False`` otherwise.
+
+How to log a user out
+---------------------
+
+.. function:: logout()
+
+ To log out a user who has been logged in via
+ :func:`django.contrib.auth.login()`, use
+ :func:`django.contrib.auth.logout()` within your view. It takes an
+ :class:`~django.http.HttpRequest` object and has no return value.
+ Example::
+
+ from django.contrib.auth import logout
+
+ def logout_view(request):
+ logout(request)
+ # Redirect to a success page.
+
+ Note that :func:`~django.contrib.auth.logout()` doesn't throw any errors if
+ the user wasn't logged in.
+
+ .. versionchanged:: 1.0
+ Calling ``logout()`` now cleans session data.
+
+ When you call :func:`~django.contrib.auth.logout()`, the session data for
+ the current request is completely cleaned out. All existing data is
+ removed. This is to prevent another person from using the same Web browser
+ to log in and have access to the previous user's session data. If you want
+ to put anything into the session that will be available to the user
+ immediately after logging out, do that *after* calling
+ :func:`django.contrib.auth.logout()`.
+
+Limiting access to logged-in users
+----------------------------------
+
+The raw way
+~~~~~~~~~~~
+
+The simple, raw way to limit access to pages is to check
+:meth:`request.user.is_authenticated()
+<django.contrib.auth.models.User.is_authenticated()>` and either redirect to a
+login page::
+
+ from django.http import HttpResponseRedirect
+
+ def my_view(request):
+ if not request.user.is_authenticated():
+ return HttpResponseRedirect('/login/?next=%s' % request.path)
+ # ...
+
+...or display an error message::
+
+ def my_view(request):
+ if not request.user.is_authenticated():
+ return render_to_response('myapp/login_error.html')
+ # ...
+
+The login_required decorator
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. function:: decorators.login_required([redirect_field_name=REDIRECT_FIELD_NAME])
+
+ As a shortcut, you can use the convenient
+ :func:`~django.contrib.auth.decorators.login_required` decorator::
+
+ from django.contrib.auth.decorators import login_required
+
+ @login_required
+ def my_view(request):
+ ...
+
+ :func:`~django.contrib.auth.decorators.login_required` does the following:
+
+ * If the user isn't logged in, redirect to
+ :setting:`settings.LOGIN_URL <LOGIN_URL>`, passing the current absolute
+ path in the query string. Example: ``/accounts/login/?next=/polls/3/``.
+
+ * If the user is logged in, execute the view normally. The view code is
+ free to assume the user is logged in.
+
+ By default, the path that the user should be redirected to upon
+ successful authentication is stored in a query string parameter called
+ ``"next"``. If you would prefer to use a different name for this parameter,
+ :func:`~django.contrib.auth.decorators.login_required` takes an
+ optional ``redirect_field_name`` parameter::
+
+ from django.contrib.auth.decorators import login_required
+
+ @login_required(redirect_field_name='my_redirect_field')
+ def my_view(request):
+ ...
+
+ If you provide a value to ``redirect_field_name``, you will most
+ likely need to customize your login template as well, since the template
+ context variable which stores the redirect path will use the value of
+ ``redirect_field_name`` as it's key rather than ``"next"`` (the default).
+
+ Note that you'll need to map the appropriate Django view to
+ :setting:`settings.LOGIN_URL <LOGIN_URL>`. For example, using the defaults,
+ add the following line to your URLconf::
+
+ (r'^accounts/login/$', 'django.contrib.auth.views.login'),
+
+.. function:: views.login(request, [template_name, redirect_field_name, authentication_form])
+
+ Here's what ``django.contrib.auth.views.login`` does:
+
+ * If called via ``GET``, it displays a login form that POSTs to the
+ same URL. More on this in a bit.
+
+ * If called via ``POST``, it tries to log the user in. If login is
+ successful, the view redirects to the URL specified in ``next``. If
+ ``next`` isn't provided, it redirects to
+ :setting:`settings.LOGIN_REDIRECT_URL <LOGIN_REDIRECT_URL>` (which
+ defaults to ``/accounts/profile/``). If login isn't successful, it
+ redisplays the login form.
+
+ It's your responsibility to provide the login form in a template called
+ ``registration/login.html`` by default. This template gets passed four
+ template context variables:
+
+ * ``form``: A :class:`~django.forms.Form` object representing the login
+ form. See the :doc:`forms documentation </topics/forms/index>` for
+ more on ``Form`` objects.
+
+ * ``next``: The URL to redirect to after successful login. This may
+ contain a query string, too.
+
+ * ``site``: The current :class:`~django.contrib.sites.models.Site`,
+ according to the :setting:`SITE_ID` setting. If you don't have the
+ site framework installed, this will be set to an instance of
+ :class:`~django.contrib.sites.models.RequestSite`, which derives the
+ site name and domain from the current
+ :class:`~django.http.HttpRequest`.
+
+ * ``site_name``: An alias for ``site.name``. If you don't have the site
+ framework installed, this will be set to the value of
+ :attr:`request.META['SERVER_NAME'] <django.http.HttpRequest.META>`.
+ For more on sites, see :doc:`/ref/contrib/sites`.
+
+ If you'd prefer not to call the template :file:`registration/login.html`,
+ you can pass the ``template_name`` parameter via the extra arguments to
+ the view in your URLconf. For example, this URLconf line would use
+ :file:`myapp/login.html` instead::
+
+ (r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'myapp/login.html'}),
+
+ You can also specify the name of the ``GET`` field which contains the URL
+ to redirect to after login by passing ``redirect_field_name`` to the view.
+ By default, the field is called ``next``.
+
+ Here's a sample :file:`registration/login.html` template you can use as a
+ starting point. It assumes you have a :file:`base.html` template that
+ defines a ``content`` block:
+
+ .. code-block:: html+django
+
+ {% extends "base.html" %}
+
+ {% block content %}
+
+ {% if form.errors %}
+ <p>Your username and password didn't match. Please try again.</p>
+ {% endif %}
+
+ <form method="post" action="{% url django.contrib.auth.views.login %}">
+ {% csrf_token %}
+ <table>
+ <tr>
+ <td>{{ form.username.label_tag }}</td>
+ <td>{{ form.username }}</td>
+ </tr>
+ <tr>
+ <td>{{ form.password.label_tag }}</td>
+ <td>{{ form.password }}</td>
+ </tr>
+ </table>
+
+ <input type="submit" value="login" />
+ <input type="hidden" name="next" value="{{ next }}" />
+ </form>
+
+ {% endblock %}
+
+ .. versionadded:: 1.2
+
+ If you are using alternate authentication (see
+ :ref:`authentication-backends`) you can pass a custom authentication form
+ to the login view via the ``authentication_form`` parameter. This form must
+ accept a ``request`` keyword argument in its ``__init__`` method, and
+ provide a ``get_user`` method which returns the authenticated user object
+ (this method is only ever called after successful form validation).
+
+ .. _forms documentation: ../forms/
+ .. _site framework docs: ../sites/
+
+Other built-in views
+--------------------
+
+In addition to the :func:`~views.login` view, the authentication system
+includes a few other useful built-in views located in
+:mod:`django.contrib.auth.views`:
+
+.. function:: views.logout(request, [next_page, template_name, redirect_field_name])
+
+ Logs a user out.
+
+ **Optional arguments:**
+
+ * ``next_page``: The URL to redirect to after logout.
+
+ * ``template_name``: The full name of a template to display after
+ logging the user out. This will default to
+ :file:`registration/logged_out.html` if no argument is supplied.
+
+ * ``redirect_field_name``: The name of a ``GET`` field containing the
+ URL to redirect to after log out. Overrides ``next_page`` if the given
+ ``GET`` parameter is passed.
+
+ **Template context:**
+
+ * ``title``: The string "Logged out", localized.
+
+.. function:: views.logout_then_login(request[, login_url])
+
+ Logs a user out, then redirects to the login page.
+
+ **Optional arguments:**
+
+ * ``login_url``: The URL of the login page to redirect to. This will
+ default to :setting:`settings.LOGIN_URL <LOGIN_URL>` if not supplied.
+
+.. function:: views.password_change(request[, template_name, post_change_redirect, password_change_form])
+
+ Allows a user to change their password.
+
+ **Optional arguments:**
+
+ * ``template_name``: The full name of a template to use for
+ displaying the password change form. This will default to
+ :file:`registration/password_change_form.html` if not supplied.
+
+ * ``post_change_redirect``: The URL to redirect to after a successful
+ password change.
+
+ * .. versionadded:: 1.2
+
+ ``password_change_form``: A custom "change password" form which must
+ accept a ``user`` keyword argument. The form is responsible for
+ actually changing the user's password.
+
+
+ **Template context:**
+
+ * ``form``: The password change form.
+
+.. function:: views.password_change_done(request[, template_name])
+
+ The page shown after a user has changed their password.
+
+ **Optional arguments:**
+
+ * ``template_name``: The full name of a template to use. This will
+ default to :file:`registration/password_change_done.html` if not
+ supplied.
+
+.. function:: views.password_reset(request[, is_admin_site, template_name, email_template_name, password_reset_form, token_generator, post_reset_redirect])
+
+ Allows a user to reset their password by generating a one-time use link
+ that can be used to reset the password, and sending that link to the
+ user's registered e-mail address.
+
+ **Optional arguments:**
+
+ * ``template_name``: The full name of a template to use for
+ displaying the password reset form. This will default to
+ :file:`registration/password_reset_form.html` if not supplied.
+
+ * ``email_template_name``: The full name of a template to use for
+ generating the e-mail with the new password. This will default to
+ :file:`registration/password_reset_email.html` if not supplied.
+
+ * ``password_reset_form``: Form that will be used to set the password.
+ Defaults to :class:`~django.contrib.auth.forms.PasswordResetForm`.
+
+ * ``token_generator``: Instance of the class to check the password. This
+ will default to ``default_token_generator``, it's an instance of
+ ``django.contrib.auth.tokens.PasswordResetTokenGenerator``.
+
+ * ``post_reset_redirect``: The URL to redirect to after a successful
+ password change.
+
+ **Template context:**
+
+ * ``form``: The form for resetting the user's password.
+
+.. function:: views.password_reset_done(request[, template_name])
+
+ The page shown after a user has reset their password.
+
+ **Optional arguments:**
+
+ * ``template_name``: The full name of a template to use. This will
+ default to :file:`registration/password_reset_done.html` if not
+ supplied.
+
+.. function:: views.redirect_to_login(next[, login_url, redirect_field_name])
+
+ Redirects to the login page, and then back to another URL after a
+ successful login.
+
+ **Required arguments:**
+
+ * ``next``: The URL to redirect to after a successful login.
+
+ **Optional arguments:**
+
+ * ``login_url``: The URL of the login page to redirect to. This will
+ default to :setting:`settings.LOGIN_URL <LOGIN_URL>` if not supplied.
+
+ * ``redirect_field_name``: The name of a ``GET`` field containing the
+ URL to redirect to after log out. Overrides ``next`` if the given
+ ``GET`` parameter is passed.
+
+.. function:: password_reset_confirm(request[, uidb36, token, template_name, token_generator, set_password_form, post_reset_redirect])
+
+ Presents a form for entering a new password.
+
+ **Optional arguments:**
+
+ * ``uidb36``: The user's id encoded in base 36. This will default to
+ ``None``.
+ * ``token``: Token to check that the password is valid. This will default to ``None``.
+ * ``template_name``: The full name of a template to display the confirm
+ password view. Default value is :file:`registration/password_reset_confirm.html`.
+ * ``token_generator``: Instance of the class to check the password. This
+ will default to ``default_token_generator``, it's an instance of
+ ``django.contrib.auth.tokens.PasswordResetTokenGenerator``.
+ * ``set_password_form``: Form that will be used to set the password.
+ This will default to ``SetPasswordForm``.
+ * ``post_reset_redirect``: URL to redirect after the password reset
+ done. This will default to ``None``.
+
+.. function:: password_reset_complete(request[,template_name])
+
+ Presents a view which informs the user that the password has been
+ successfully changed.
+
+ **Optional arguments:**
+
+ * ``template_name``: The full name of a template to display the view.
+ This will default to :file:`registration/password_reset_complete.html`.
+
+Built-in forms
+--------------
+
+.. module:: django.contrib.auth.forms
+
+If you don't want to use the built-in views, but want the convenience of not
+having to write forms for this functionality, the authentication system
+provides several built-in forms located in :mod:`django.contrib.auth.forms`:
+
+.. class:: AdminPasswordChangeForm
+
+ A form used in the admin interface to change a user's password.
+
+.. class:: AuthenticationForm
+
+ A form for logging a user in.
+
+.. class:: PasswordChangeForm
+
+ A form for allowing a user to change their password.
+
+.. class:: PasswordResetForm
+
+ A form for generating and e-mailing a one-time use link to reset a
+ user's password.
+
+.. class:: SetPasswordForm
+
+ A form that lets a user change his/her password without entering the old
+ password.
+
+.. class:: UserChangeForm
+
+ A form used in the admin interface to change a user's information and
+ permissions.
+
+.. class:: UserCreationForm
+
+ A form for creating a new user.
+
+Limiting access to logged-in users that pass a test
+---------------------------------------------------
+
+.. currentmodule:: django.contrib.auth
+
+To limit access based on certain permissions or some other test, you'd do
+essentially the same thing as described in the previous section.
+
+The simple way is to run your test on :attr:`request.user
+<django.http.HttpRequest.user>` in the view directly. For example, this view
+checks to make sure the user is logged in and has the permission
+``polls.can_vote``::
+
+ def my_view(request):
+ if not request.user.has_perm('polls.can_vote'):
+ return HttpResponse("You can't vote in this poll.")
+ # ...
+
+.. function:: decorators.user_passes_test()
+
+ As a shortcut, you can use the convenient ``user_passes_test`` decorator::
+
+ from django.contrib.auth.decorators import user_passes_test
+
+ @user_passes_test(lambda u: u.has_perm('polls.can_vote'))
+ def my_view(request):
+ ...
+
+ We're using this particular test as a relatively simple example. However,
+ if you just want to test whether a permission is available to a user, you
+ can use the :func:`~django.contrib.auth.decorators.permission_required()`
+ decorator, described later in this document.
+
+ :func:`~django.contrib.auth.decorators.user_passes_test` takes a required
+ argument: a callable that takes a
+ :class:`~django.contrib.auth.models.User` object and returns ``True`` if
+ the user is allowed to view the page. Note that
+ :func:`~django.contrib.auth.decorators.user_passes_test` does not
+ automatically check that the :class:`~django.contrib.auth.models.User` is
+ not anonymous.
+
+ :func:`~django.contrib.auth.decorators.user_passes_test()` takes an
+ optional ``login_url`` argument, which lets you specify the URL for your
+ login page (:setting:`settings.LOGIN_URL <LOGIN_URL>` by default).
+
+ For example::
+
+ from django.contrib.auth.decorators import user_passes_test
+
+ @user_passes_test(lambda u: u.has_perm('polls.can_vote'), login_url='/login/')
+ def my_view(request):
+ ...
+
+The permission_required decorator
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. function:: decorators.permission_required()
+
+ It's a relatively common task to check whether a user has a particular
+ permission. For that reason, Django provides a shortcut for that case: the
+ :func:`~django.contrib.auth.decorators.permission_required()` decorator.
+ Using this decorator, the earlier example can be written as::
+
+ from django.contrib.auth.decorators import permission_required
+
+ @permission_required('polls.can_vote')
+ def my_view(request):
+ ...
+
+ As for the :meth:`User.has_perm` method, permission names take the form
+ ``"<app label>.<permission codename>"`` (i.e. ``polls.can_vote`` for a
+ permission on a model in the ``polls`` application).
+
+ Note that :func:`~django.contrib.auth.decorators.permission_required()`
+ also takes an optional ``login_url`` parameter. Example::
+
+ from django.contrib.auth.decorators import permission_required
+
+ @permission_required('polls.can_vote', login_url='/loginpage/')
+ def my_view(request):
+ ...
+
+ As in the :func:`~decorators.login_required` decorator, ``login_url``
+ defaults to :setting:`settings.LOGIN_URL <LOGIN_URL>`.
+
+Limiting access to generic views
+--------------------------------
+
+To limit access to a :doc:`generic view </ref/generic-views>`, write a thin
+wrapper around the view, and point your URLconf to your wrapper instead of the
+generic view itself. For example::
+
+ from django.views.generic.date_based import object_detail
+
+ @login_required
+ def limited_object_detail(*args, **kwargs):
+ return object_detail(*args, **kwargs)
+
+.. _permissions:
+
+Permissions
+===========
+
+Django comes with a simple permissions system. It provides a way to assign
+permissions to specific users and groups of users.
+
+It's used by the Django admin site, but you're welcome to use it in your own
+code.
+
+The Django admin site uses permissions as follows:
+
+ * Access to view the "add" form and add an object is limited to users with
+ the "add" permission for that type of object.
+ * Access to view the change list, view the "change" form and change an
+ object is limited to users with the "change" permission for that type of
+ object.
+ * Access to delete an object is limited to users with the "delete"
+ permission for that type of object.
+
+Permissions are set globally per type of object, not per specific object
+instance. For example, it's possible to say "Mary may change news stories," but
+it's not currently possible to say "Mary may change news stories, but only the
+ones she created herself" or "Mary may only change news stories that have a
+certain status, publication date or ID." The latter functionality is something
+Django developers are currently discussing.
+
+Default permissions
+-------------------
+
+When ``django.contrib.auth`` is listed in your :setting:`INSTALLED_APPS`
+setting, it will ensure that three default permissions -- add, change and
+delete -- are created for each Django model defined in one of your installed
+applications.
+
+These permissions will be created when you run :djadmin:`manage.py syncdb
+<syncdb>`; the first time you run ``syncdb`` after adding
+``django.contrib.auth`` to :setting:`INSTALLED_APPS`, the default permissions
+will be created for all previously-installed models, as well as for any new
+models being installed at that time. Afterward, it will create default
+permissions for new models each time you run :djadmin:`manage.py syncdb
+<syncdb>`.
+
+Assuming you have an application with an
+:attr:`~django.db.models.Options.app_label` ``foo`` and a model named ``Bar``,
+to test for basic permissions you should use:
+
+ * add: ``user.has_perm('foo.add_bar')``
+ * change: ``user.has_perm('foo.change_bar')``
+ * delete: ``user.has_perm('foo.delete_bar')``
+
+.. _custom-permissions:
+
+Custom permissions
+------------------
+
+To create custom permissions for a given model object, use the ``permissions``
+:ref:`model Meta attribute <meta-options>`.
+
+This example Task model creates three custom permissions, i.e., actions users
+can or cannot do with Task instances, specific to your appication::
+
+ class Task(models.Model):
+ ...
+ class Meta:
+ permissions = (
+ ("can_view", "Can see available tasks"),
+ ("can_change_status", "Can change the status of tasks"),
+ ("can_close", "Can remove a task by setting its status as closed"),
+ )
+
+The only thing this does is create those extra permissions when you run
+:djadmin:`manage.py syncdb <syncdb>`. Your code is in charge of checking the
+value of these permissions when an user is trying to access the functionality
+provided by the application (viewing tasks, changing the status of tasks,
+closing tasks.)
+
+API reference
+-------------
+
+.. class:: models.Permission
+
+ Just like users, permissions are implemented in a Django model that lives
+ in `django/contrib/auth/models.py`_.
+
+.. _django/contrib/auth/models.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/models.py
+
+Fields
+~~~~~~
+
+:class:`~django.contrib.auth.models.Permission` objects have the following
+fields:
+
+.. attribute:: models.Permission.name
+
+ Required. 50 characters or fewer. Example: ``'Can vote'``.
+
+.. attribute:: models.Permission.content_type
+
+ Required. A reference to the ``django_content_type`` database table, which
+ contains a record for each installed Django model.
+
+.. attribute:: models.Permission.codename
+
+ Required. 100 characters or fewer. Example: ``'can_vote'``.
+
+Methods
+~~~~~~~
+
+:class:`~django.contrib.auth.models.Permission` objects have the standard
+data-access methods like any other :doc:`Django model </ref/models/instances>`.
+
+Authentication data in templates
+================================
+
+The currently logged-in user and his/her permissions are made available in the
+:doc:`template context </ref/templates/api>` when you use
+:class:`~django.template.context.RequestContext`.
+
+.. admonition:: Technicality
+
+ Technically, these variables are only made available in the template context
+ if you use :class:`~django.template.context.RequestContext` *and* your
+ :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting contains
+ ``"django.contrib.auth.context_processors.auth"``, which is default. For
+ more, see the :ref:`RequestContext docs <subclassing-context-requestcontext>`.
+
+Users
+-----
+
+When rendering a template :class:`~django.template.context.RequestContext`, the
+currently logged-in user, either a :class:`~django.contrib.auth.models.User`
+instance or an :class:`~django.contrib.auth.models.AnonymousUser` instance, is
+stored in the template variable ``{{ user }}``:
+
+.. code-block:: html+django
+
+ {% if user.is_authenticated %}
+ <p>Welcome, {{ user.username }}. Thanks for logging in.</p>
+ {% else %}
+ <p>Welcome, new user. Please log in.</p>
+ {% endif %}
+
+This template context variable is not available if a ``RequestContext`` is not
+being used.
+
+Permissions
+-----------
+
+The currently logged-in user's permissions are stored in the template variable
+``{{ perms }}``. This is an instance of
+:class:`django.core.context_processors.PermWrapper`, which is a
+template-friendly proxy of permissions.
+
+In the ``{{ perms }}`` object, single-attribute lookup is a proxy to
+:meth:`User.has_module_perms <django.contrib.auth.models.User.has_module_perms>`.
+This example would display ``True`` if the logged-in user had any permissions
+in the ``foo`` app::
+
+ {{ perms.foo }}
+
+Two-level-attribute lookup is a proxy to
+:meth:`User.has_perm <django.contrib.auth.models.User.has_perm>`. This example
+would display ``True`` if the logged-in user had the permission
+``foo.can_vote``::
+
+ {{ perms.foo.can_vote }}
+
+Thus, you can check permissions in template ``{% if %}`` statements:
+
+.. code-block:: html+django
+
+ {% if perms.foo %}
+ <p>You have permission to do something in the foo app.</p>
+ {% if perms.foo.can_vote %}
+ <p>You can vote!</p>
+ {% endif %}
+ {% if perms.foo.can_drive %}
+ <p>You can drive!</p>
+ {% endif %}
+ {% else %}
+ <p>You don't have permission to do anything in the foo app.</p>
+ {% endif %}
+
+Groups
+======
+
+Groups are a generic way of categorizing users so you can apply permissions, or
+some other label, to those users. A user can belong to any number of groups.
+
+A user in a group automatically has the permissions granted to that group. For
+example, if the group ``Site editors`` has the permission
+``can_edit_home_page``, any user in that group will have that permission.
+
+Beyond permissions, groups are a convenient way to categorize users to give
+them some label, or extended functionality. For example, you could create a
+group ``'Special users'``, and you could write code that could, say, give them
+access to a members-only portion of your site, or send them members-only e-mail
+messages.
+
+Messages
+========
+
+.. deprecated:: 1.2
+ This functionality will be removed in Django 1.4. You should use the
+ :doc:`messages framework </ref/contrib/messages>` for all new projects and
+ begin to update your existing code immediately.
+
+The message system is a lightweight way to queue messages for given users.
+
+A message is associated with a :class:`~django.contrib.auth.models.User`.
+There's no concept of expiration or timestamps.
+
+Messages are used by the Django admin after successful actions. For example,
+``"The poll Foo was created successfully."`` is a message.
+
+The API is simple:
+
+.. method:: models.User.message_set.create(message)
+
+ To create a new message, use
+ ``user_obj.message_set.create(message='message_text')``.
+
+ To retrieve/delete messages, use
+ :meth:`user_obj.get_and_delete_messages() <django.contrib.auth.models.User.get_and_delete_messages>`,
+ which returns a list of ``Message`` objects in the user's queue (if any)
+ and deletes the messages from the queue.
+
+In this example view, the system saves a message for the user after creating
+a playlist::
+
+ def create_playlist(request, songs):
+ # Create the playlist with the given songs.
+ # ...
+ request.user.message_set.create(message="Your playlist was added successfully.")
+ return render_to_response("playlists/create.html",
+ context_instance=RequestContext(request))
+
+When you use :class:`~django.template.context.RequestContext`, the currently
+logged-in user and his/her messages are made available in the
+:doc:`template context </ref/templates/api>` as the template variable
+``{{ messages }}``. Here's an example of template code that displays messages:
+
+.. code-block:: html+django
+
+ {% if messages %}
+ <ul>
+ {% for message in messages %}
+ <li>{{ message }}</li>
+ {% endfor %}
+ </ul>
+ {% endif %}
+
+.. versionchanged:: 1.2
+ The ``messages`` template variable uses a backwards compatible method in the
+ :doc:`messages framework </ref/contrib/messages>` to retrieve messages from
+ both the user ``Message`` model and from the new framework. Unlike in
+ previous revisions, the messages will not be erased unless they are actually
+ displayed.
+
+Finally, note that this messages framework only works with users in the user
+database. To send messages to anonymous users, use the
+:doc:`messages framework </ref/contrib/messages>`.
+
+.. _authentication-backends:
+
+Other authentication sources
+============================
+
+The authentication that comes with Django is good enough for most common cases,
+but you may have the need to hook into another authentication source -- that
+is, another source of usernames and passwords or authentication methods.
+
+For example, your company may already have an LDAP setup that stores a username
+and password for every employee. It'd be a hassle for both the network
+administrator and the users themselves if users had separate accounts in LDAP
+and the Django-based applications.
+
+So, to handle situations like this, the Django authentication system lets you
+plug in other authentication sources. You can override Django's default
+database-based scheme, or you can use the default system in tandem with other
+systems.
+
+See the :doc:`authentication backend reference </ref/authbackends>`
+for information on the authentication backends included with Django.
+
+Specifying authentication backends
+----------------------------------
+
+Behind the scenes, Django maintains a list of "authentication backends" that it
+checks for authentication. When somebody calls
+:func:`django.contrib.auth.authenticate()` -- as described in :ref:`How to log
+a user in <how-to-log-a-user-in>` above -- Django tries authenticating across
+all of its authentication backends. If the first authentication method fails,
+Django tries the second one, and so on, until all backends have been attempted.
+
+The list of authentication backends to use is specified in the
+:setting:`AUTHENTICATION_BACKENDS` setting. This should be a tuple of Python
+path names that point to Python classes that know how to authenticate. These
+classes can be anywhere on your Python path.
+
+By default, :setting:`AUTHENTICATION_BACKENDS` is set to::
+
+ ('django.contrib.auth.backends.ModelBackend',)
+
+That's the basic authentication scheme that checks the Django users database.
+
+The order of :setting:`AUTHENTICATION_BACKENDS` matters, so if the same
+username and password is valid in multiple backends, Django will stop
+processing at the first positive match.
+
+.. note::
+
+ Once a user has authenticated, Django stores which backend was used to
+ authenticate the user in the user's session, and re-uses the same backend
+ for subsequent authentication attempts for that user. This effectively means
+ that authentication sources are cached, so if you change
+ :setting:`AUTHENTICATION_BACKENDS`, you'll need to clear out session data if
+ you need to force users to re-authenticate using different methods. A simple
+ way to do that is simply to execute ``Session.objects.all().delete()``.
+
+Writing an authentication backend
+---------------------------------
+
+An authentication backend is a class that implements two methods:
+``get_user(user_id)`` and ``authenticate(**credentials)``.
+
+The ``get_user`` method takes a ``user_id`` -- which could be a username,
+database ID or whatever -- and returns a ``User`` object.
+
+The ``authenticate`` method takes credentials as keyword arguments. Most of
+the time, it'll just look like this::
+
+ class MyBackend:
+ def authenticate(self, username=None, password=None):
+ # Check the username/password and return a User.
+
+But it could also authenticate a token, like so::
+
+ class MyBackend:
+ def authenticate(self, token=None):
+ # Check the token and return a User.
+
+Either way, ``authenticate`` should check the credentials it gets, and it
+should return a ``User`` object that matches those credentials, if the
+credentials are valid. If they're not valid, it should return ``None``.
+
+The Django admin system is tightly coupled to the Django ``User`` object
+described at the beginning of this document. For now, the best way to deal with
+this is to create a Django ``User`` object for each user that exists for your
+backend (e.g., in your LDAP directory, your external SQL database, etc.) You
+can either write a script to do this in advance, or your ``authenticate``
+method can do it the first time a user logs in.
+
+Here's an example backend that authenticates against a username and password
+variable defined in your ``settings.py`` file and creates a Django ``User``
+object the first time a user authenticates::
+
+ from django.conf import settings
+ from django.contrib.auth.models import User, check_password
+
+ class SettingsBackend:
+ """
+ Authenticate against the settings ADMIN_LOGIN and ADMIN_PASSWORD.
+
+ Use the login name, and a hash of the password. For example:
+
+ ADMIN_LOGIN = 'admin'
+ ADMIN_PASSWORD = 'sha1$4e987$afbcf42e21bd417fb71db8c66b321e9fc33051de'
+ """
+ def authenticate(self, username=None, password=None):
+ login_valid = (settings.ADMIN_LOGIN == username)
+ pwd_valid = check_password(password, settings.ADMIN_PASSWORD)
+ if login_valid and pwd_valid:
+ try:
+ user = User.objects.get(username=username)
+ except User.DoesNotExist:
+ # Create a new user. Note that we can set password
+ # to anything, because it won't be checked; the password
+ # from settings.py will.
+ user = User(username=username, password='get from settings.py')
+ user.is_staff = True
+ user.is_superuser = True
+ user.save()
+ return user
+ return None
+
+ def get_user(self, user_id):
+ try:
+ return User.objects.get(pk=user_id)
+ except User.DoesNotExist:
+ return None
+
+Handling authorization in custom backends
+-----------------------------------------
+
+Custom auth backends can provide their own permissions.
+
+The user model will delegate permission lookup functions
+(:meth:`~django.contrib.auth.models.User.get_group_permissions()`,
+:meth:`~django.contrib.auth.models.User.get_all_permissions()`,
+:meth:`~django.contrib.auth.models.User.has_perm()`, and
+:meth:`~django.contrib.auth.models.User.has_module_perms()`) to any
+authentication backend that implements these functions.
+
+The permissions given to the user will be the superset of all permissions
+returned by all backends. That is, Django grants a permission to a user that
+any one backend grants.
+
+The simple backend above could implement permissions for the magic admin
+fairly simply::
+
+ class SettingsBackend:
+
+ # ...
+
+ def has_perm(self, user_obj, perm):
+ if user_obj.username == settings.ADMIN_LOGIN:
+ return True
+ else:
+ return False
+
+This gives full permissions to the user granted access in the above example.
+Notice that the backend auth functions all take the user object as an argument,
+and they also accept the same arguments given to the associated
+:class:`django.contrib.auth.models.User` functions.
+
+A full authorization implementation can be found in
+`django/contrib/auth/backends.py`_, which is the default backend and queries
+the ``auth_permission`` table most of the time.
+
+.. _django/contrib/auth/backends.py: http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/backends.py
+
+Authorization for anonymous users
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. versionchanged:: 1.2
+
+An anonymous user is one that is not authenticated i.e. they have provided no
+valid authentication details. However, that does not necessarily mean they are
+not authorized to do anything. At the most basic level, most Web sites
+authorize anonymous users to browse most of the site, and many allow anonymous
+posting of comments etc.
+
+Django's permission framework does not have a place to store permissions for
+anonymous users. However, it has a foundation that allows custom authentication
+backends to specify authorization for anonymous users. This is especially useful
+for the authors of re-usable apps, who can delegate all questions of authorization
+to the auth backend, rather than needing settings, for example, to control
+anonymous access.
+
+To enable this in your own backend, you must set the class attribute
+``supports_anonymous_user`` to ``True``. (This precaution is to maintain
+compatibility with backends that assume that all user objects are actual
+instances of the :class:`django.contrib.auth.models.User` class). With this
+in place, :class:`django.contrib.auth.models.AnonymousUser` will delegate all
+the relevant permission methods to the authentication backends.
+
+A nonexistent ``supports_anonymous_user`` attribute will raise a hidden
+``PendingDeprecationWarning`` if used in Django 1.2. In Django 1.3, this
+warning will be upgraded to a ``DeprecationWarning``, which will be displayed
+loudly. Additionally ``supports_anonymous_user`` will be set to ``False``.
+Django 1.4 will assume that every backend supports anonymous users being
+passed to the authorization methods.
+
+Handling object permissions
+---------------------------
+
+Django's permission framework has a foundation for object permissions, though
+there is no implementation for it in the core. That means that checking for
+object permissions will always return ``False`` or an empty list (depending on
+the check performed).
+
+To enable object permissions in your own
+:doc:`authentication backend </ref/authbackends>` you'll just have
+to allow passing an ``obj`` parameter to the permission methods and set the
+``supports_object_permissions`` class attribute to ``True``.
+
+A nonexistent ``supports_object_permissions`` will raise a hidden
+``PendingDeprecationWarning`` if used in Django 1.2. In Django 1.3, this
+warning will be upgraded to a ``DeprecationWarning``, which will be displayed
+loudly. Additionally ``supports_object_permissions`` will be set to ``False``.
+Django 1.4 will assume that every backend supports object permissions and
+won't check for the existence of ``supports_object_permissions``, which
+means not supporting ``obj`` as a parameter will raise a ``TypeError``.
diff --git a/parts/django/docs/topics/cache.txt b/parts/django/docs/topics/cache.txt
new file mode 100644
index 0000000..c18b811
--- /dev/null
+++ b/parts/django/docs/topics/cache.txt
@@ -0,0 +1,917 @@
+========================
+Django's cache framework
+========================
+
+A fundamental trade-off in dynamic Web sites is, well, they're dynamic. Each
+time a user requests a page, the Web server makes all sorts of calculations --
+from database queries to template rendering to business logic -- to create the
+page that your site's visitor sees. This is a lot more expensive, from a
+processing-overhead perspective, than your standard
+read-a-file-off-the-filesystem server arrangement.
+
+For most Web applications, this overhead isn't a big deal. Most Web
+applications aren't washingtonpost.com or slashdot.org; they're simply small-
+to medium-sized sites with so-so traffic. But for medium- to high-traffic
+sites, it's essential to cut as much overhead as possible.
+
+That's where caching comes in.
+
+To cache something is to save the result of an expensive calculation so that
+you don't have to perform the calculation next time. Here's some pseudocode
+explaining how this would work for a dynamically generated Web page::
+
+ given a URL, try finding that page in the cache
+ if the page is in the cache:
+ return the cached page
+ else:
+ generate the page
+ save the generated page in the cache (for next time)
+ return the generated page
+
+Django comes with a robust cache system that lets you save dynamic pages so
+they don't have to be calculated for each request. For convenience, Django
+offers different levels of cache granularity: You can cache the output of
+specific views, you can cache only the pieces that are difficult to produce, or
+you can cache your entire site.
+
+Django also works well with "upstream" caches, such as `Squid
+<http://www.squid-cache.org>`_ and browser-based caches. These are the types of
+caches that you don't directly control but to which you can provide hints (via
+HTTP headers) about which parts of your site should be cached, and how.
+
+Setting up the cache
+====================
+
+The cache system requires a small amount of setup. Namely, you have to tell it
+where your cached data should live -- whether in a database, on the filesystem
+or directly in memory. This is an important decision that affects your cache's
+performance; yes, some cache types are faster than others.
+
+Your cache preference goes in the ``CACHE_BACKEND`` setting in your settings
+file. Here's an explanation of all available values for ``CACHE_BACKEND``.
+
+Memcached
+---------
+
+By far the fastest, most efficient type of cache available to Django, Memcached
+is an entirely memory-based cache framework originally developed to handle high
+loads at LiveJournal.com and subsequently open-sourced by Danga Interactive.
+It's used by sites such as Facebook and Wikipedia to reduce database access and
+dramatically increase site performance.
+
+Memcached is available for free at http://memcached.org/. It runs as a
+daemon and is allotted a specified amount of RAM. All it does is provide a
+fast interface for adding, retrieving and deleting arbitrary data in the cache.
+All data is stored directly in memory, so there's no overhead of database or
+filesystem usage.
+
+After installing Memcached itself, you'll need to install
+``python-memcached``, which provides Python bindings to Memcached.
+This is available at ftp://ftp.tummy.com/pub/python-memcached/
+
+.. versionchanged:: 1.2
+ In Django 1.0 and 1.1, you could also use ``cmemcache`` as a binding.
+ However, support for this library was deprecated in 1.2 due to
+ a lack of maintenance on the ``cmemcache`` library itself. Support for
+ ``cmemcache`` will be removed completely in Django 1.4.
+
+To use Memcached with Django, set ``CACHE_BACKEND`` to
+``memcached://ip:port/``, where ``ip`` is the IP address of the Memcached
+daemon and ``port`` is the port on which Memcached is running.
+
+In this example, Memcached is running on localhost (127.0.0.1) port 11211::
+
+ CACHE_BACKEND = 'memcached://127.0.0.1:11211/'
+
+One excellent feature of Memcached is its ability to share cache over multiple
+servers. This means you can run Memcached daemons on multiple machines, and the
+program will treat the group of machines as a *single* cache, without the need
+to duplicate cache values on each machine. To take advantage of this feature,
+include all server addresses in ``CACHE_BACKEND``, separated by semicolons.
+
+In this example, the cache is shared over Memcached instances running on IP
+address 172.19.26.240 and 172.19.26.242, both on port 11211::
+
+ CACHE_BACKEND = 'memcached://172.19.26.240:11211;172.19.26.242:11211/'
+
+In the following example, the cache is shared over Memcached instances running
+on the IP addresses 172.19.26.240 (port 11211), 172.19.26.242 (port 11212), and
+172.19.26.244 (port 11213)::
+
+ CACHE_BACKEND = 'memcached://172.19.26.240:11211;172.19.26.242:11212;172.19.26.244:11213/'
+
+A final point about Memcached is that memory-based caching has one
+disadvantage: Because the cached data is stored in memory, the data will be
+lost if your server crashes. Clearly, memory isn't intended for permanent data
+storage, so don't rely on memory-based caching as your only data storage.
+Without a doubt, *none* of the Django caching backends should be used for
+permanent storage -- they're all intended to be solutions for caching, not
+storage -- but we point this out here because memory-based caching is
+particularly temporary.
+
+Database caching
+----------------
+
+To use a database table as your cache backend, first create a cache table in
+your database by running this command::
+
+ python manage.py createcachetable [cache_table_name]
+
+...where ``[cache_table_name]`` is the name of the database table to create.
+(This name can be whatever you want, as long as it's a valid table name that's
+not already being used in your database.) This command creates a single table
+in your database that is in the proper format that Django's database-cache
+system expects.
+
+Once you've created that database table, set your ``CACHE_BACKEND`` setting to
+``"db://tablename"``, where ``tablename`` is the name of the database table.
+In this example, the cache table's name is ``my_cache_table``::
+
+ CACHE_BACKEND = 'db://my_cache_table'
+
+The database caching backend uses the same database as specified in your
+settings file. You can't use a different database backend for your cache table.
+
+Database caching works best if you've got a fast, well-indexed database server.
+
+Database caching and multiple databases
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you use database caching with multiple databases, you'll also need
+to set up routing instructions for your database cache table. For the
+purposes of routing, the database cache table appears as a model named
+``CacheEntry``, in an application named ``django_cache``. This model
+won't appear in the models cache, but the model details can be used
+for routing purposes.
+
+For example, the following router would direct all cache read
+operations to ``cache_slave``, and all write operations to
+``cache_master``. The cache table will only be synchronized onto
+``cache_master``::
+
+ class CacheRouter(object):
+ """A router to control all database cache operations"""
+
+ def db_for_read(self, model, **hints):
+ "All cache read operations go to the slave"
+ if model._meta.app_label in ('django_cache',):
+ return 'cache_slave'
+ return None
+
+ def db_for_write(self, model, **hints):
+ "All cache write operations go to master"
+ if model._meta.app_label in ('django_cache',):
+ return 'cache_master'
+ return None
+
+ def allow_syncdb(self, db, model):
+ "Only synchronize the cache model on master"
+ if model._meta.app_label in ('django_cache',):
+ return db == 'cache_master'
+ return None
+
+If you don't specify routing directions for the database cache model,
+the cache backend will use the ``default`` database.
+
+Of course, if you don't use the database cache backend, you don't need
+to worry about providing routing instructions for the database cache
+model.
+
+Filesystem caching
+------------------
+
+To store cached items on a filesystem, use the ``"file://"`` cache type for
+``CACHE_BACKEND``. For example, to store cached data in ``/var/tmp/django_cache``,
+use this setting::
+
+ CACHE_BACKEND = 'file:///var/tmp/django_cache'
+
+Note that there are three forward slashes toward the beginning of that example.
+The first two are for ``file://``, and the third is the first character of the
+directory path, ``/var/tmp/django_cache``. If you're on Windows, put the
+drive letter after the ``file://``, like this::
+
+ file://c:/foo/bar
+
+The directory path should be absolute -- that is, it should start at the root
+of your filesystem. It doesn't matter whether you put a slash at the end of the
+setting.
+
+Make sure the directory pointed-to by this setting exists and is readable and
+writable by the system user under which your Web server runs. Continuing the
+above example, if your server runs as the user ``apache``, make sure the
+directory ``/var/tmp/django_cache`` exists and is readable and writable by the
+user ``apache``.
+
+Each cache value will be stored as a separate file whose contents are the
+cache data saved in a serialized ("pickled") format, using Python's ``pickle``
+module. Each file's name is the cache key, escaped for safe filesystem use.
+
+Local-memory caching
+--------------------
+
+If you want the speed advantages of in-memory caching but don't have the
+capability of running Memcached, consider the local-memory cache backend. This
+cache is multi-process and thread-safe. To use it, set ``CACHE_BACKEND`` to
+``"locmem://"``. For example::
+
+ CACHE_BACKEND = 'locmem://'
+
+Note that each process will have its own private cache instance, which means no
+cross-process caching is possible. This obviously also means the local memory
+cache isn't particularly memory-efficient, so it's probably not a good choice
+for production environments. It's nice for development.
+
+Dummy caching (for development)
+-------------------------------
+
+Finally, Django comes with a "dummy" cache that doesn't actually cache -- it
+just implements the cache interface without doing anything.
+
+This is useful if you have a production site that uses heavy-duty caching in
+various places but a development/test environment where you don't want to cache
+and don't want to have to change your code to special-case the latter. To
+activate dummy caching, set ``CACHE_BACKEND`` like so::
+
+ CACHE_BACKEND = 'dummy://'
+
+Using a custom cache backend
+----------------------------
+
+.. versionadded:: 1.0
+
+While Django includes support for a number of cache backends out-of-the-box,
+sometimes you might want to use a customized cache backend. To use an external
+cache backend with Django, use a Python import path as the scheme portion (the
+part before the initial colon) of the ``CACHE_BACKEND`` URI, like so::
+
+ CACHE_BACKEND = 'path.to.backend://'
+
+If you're building your own backend, you can use the standard cache backends
+as reference implementations. You'll find the code in the
+``django/core/cache/backends/`` directory of the Django source.
+
+Note: Without a really compelling reason, such as a host that doesn't support
+them, you should stick to the cache backends included with Django. They've
+been well-tested and are easy to use.
+
+CACHE_BACKEND arguments
+-----------------------
+
+Each cache backend may take arguments. They're given in query-string style on
+the ``CACHE_BACKEND`` setting. Valid arguments are as follows:
+
+ * ``timeout``: The default timeout, in seconds, to use for the cache.
+ This argument defaults to 300 seconds (5 minutes).
+
+ * ``max_entries``: For the ``locmem``, ``filesystem`` and ``database``
+ backends, the maximum number of entries allowed in the cache before old
+ values are deleted. This argument defaults to 300.
+
+ * ``cull_frequency``: The fraction of entries that are culled when
+ ``max_entries`` is reached. The actual ratio is ``1/cull_frequency``, so
+ set ``cull_frequency=2`` to cull half of the entries when ``max_entries``
+ is reached.
+
+ A value of ``0`` for ``cull_frequency`` means that the entire cache will
+ be dumped when ``max_entries`` is reached. This makes culling *much*
+ faster at the expense of more cache misses.
+
+In this example, ``timeout`` is set to ``60``::
+
+ CACHE_BACKEND = "memcached://127.0.0.1:11211/?timeout=60"
+
+In this example, ``timeout`` is ``30`` and ``max_entries`` is ``400``::
+
+ CACHE_BACKEND = "locmem://?timeout=30&max_entries=400"
+
+Invalid arguments are silently ignored, as are invalid values of known
+arguments.
+
+The per-site cache
+==================
+
+.. versionchanged:: 1.0
+ (previous versions of Django only provided a single ``CacheMiddleware`` instead
+ of the two pieces described below).
+
+Once the cache is set up, the simplest way to use caching is to cache your
+entire site. You'll need to add
+``'django.middleware.cache.UpdateCacheMiddleware'`` and
+``'django.middleware.cache.FetchFromCacheMiddleware'`` to your
+``MIDDLEWARE_CLASSES`` setting, as in this example::
+
+ MIDDLEWARE_CLASSES = (
+ 'django.middleware.cache.UpdateCacheMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ 'django.middleware.cache.FetchFromCacheMiddleware',
+ )
+
+.. note::
+
+ No, that's not a typo: the "update" middleware must be first in the list,
+ and the "fetch" middleware must be last. The details are a bit obscure, but
+ see `Order of MIDDLEWARE_CLASSES`_ below if you'd like the full story.
+
+Then, add the following required settings to your Django settings file:
+
+* ``CACHE_MIDDLEWARE_SECONDS`` -- The number of seconds each page should be
+ cached.
+* ``CACHE_MIDDLEWARE_KEY_PREFIX`` -- If the cache is shared across multiple
+ sites using the same Django installation, set this to the name of the site,
+ or some other string that is unique to this Django instance, to prevent key
+ collisions. Use an empty string if you don't care.
+
+The cache middleware caches every page that doesn't have GET or POST
+parameters. Optionally, if the ``CACHE_MIDDLEWARE_ANONYMOUS_ONLY`` setting is
+``True``, only anonymous requests (i.e., not those made by a logged-in user)
+will be cached. This is a simple and effective way of disabling caching for any
+user-specific pages (include Django's admin interface). Note that if you use
+``CACHE_MIDDLEWARE_ANONYMOUS_ONLY``, you should make sure you've activated
+``AuthenticationMiddleware``.
+
+Additionally, the cache middleware automatically sets a few headers in each
+:class:`~django.http.HttpResponse`:
+
+ * Sets the ``Last-Modified`` header to the current date/time when a fresh
+ (uncached) version of the page is requested.
+
+ * Sets the ``Expires`` header to the current date/time plus the defined
+ ``CACHE_MIDDLEWARE_SECONDS``.
+
+ * Sets the ``Cache-Control`` header to give a max age for the page --
+ again, from the ``CACHE_MIDDLEWARE_SECONDS`` setting.
+
+See :doc:`/topics/http/middleware` for more on middleware.
+
+.. versionadded:: 1.0
+
+If a view sets its own cache expiry time (i.e. it has a ``max-age`` section in
+its ``Cache-Control`` header) then the page will be cached until the expiry
+time, rather than ``CACHE_MIDDLEWARE_SECONDS``. Using the decorators in
+``django.views.decorators.cache`` you can easily set a view's expiry time
+(using the ``cache_control`` decorator) or disable caching for a view (using
+the ``never_cache`` decorator). See the `using other headers`__ section for
+more on these decorators.
+
+.. _i18n-cache-key:
+
+.. versionadded:: 1.2
+
+If :setting:`USE_I18N` is set to ``True`` then the generated cache key will
+include the name of the active :term:`language<language code>`.
+This allows you to easily cache multilingual sites without having to create
+the cache key yourself.
+
+See :doc:`/topics/i18n/deployment` for more on how Django discovers the active
+language.
+
+__ `Controlling cache: Using other headers`_
+
+The per-view cache
+==================
+
+A more granular way to use the caching framework is by caching the output of
+individual views. ``django.views.decorators.cache`` defines a ``cache_page``
+decorator that will automatically cache the view's response for you. It's easy
+to use::
+
+ from django.views.decorators.cache import cache_page
+
+ @cache_page(60 * 15)
+ def my_view(request):
+ ...
+
+``cache_page`` takes a single argument: the cache timeout, in seconds. In the
+above example, the result of the ``my_view()`` view will be cached for 15
+minutes. (Note that we've written it as ``60 * 15`` for the purpose of
+readability. ``60 * 15`` will be evaluated to ``900`` -- that is, 15 minutes
+multiplied by 60 seconds per minute.)
+
+The per-view cache, like the per-site cache, is keyed off of the URL. If
+multiple URLs point at the same view, each URL will be cached separately.
+Continuing the ``my_view`` example, if your URLconf looks like this::
+
+ urlpatterns = ('',
+ (r'^foo/(\d{1,2})/$', my_view),
+ )
+
+then requests to ``/foo/1/`` and ``/foo/23/`` will be cached separately, as
+you may expect. But once a particular URL (e.g., ``/foo/23/``) has been
+requested, subsequent requests to that URL will use the cache.
+
+``cache_page`` can also take an optional keyword argument, ``key_prefix``, which
+works in the same way as the ``CACHE_MIDDLEWARE_KEY_PREFIX`` setting for the
+middleware. It can be used like this::
+
+ @cache_page(60 * 15, key_prefix="site1")
+ def my_view(request):
+ ...
+
+Specifying per-view cache in the URLconf
+----------------------------------------
+
+The examples in the previous section have hard-coded the fact that the view is
+cached, because ``cache_page`` alters the ``my_view`` function in place. This
+approach couples your view to the cache system, which is not ideal for several
+reasons. For instance, you might want to reuse the view functions on another,
+cache-less site, or you might want to distribute the views to people who might
+want to use them without being cached. The solution to these problems is to
+specify the per-view cache in the URLconf rather than next to the view functions
+themselves.
+
+Doing so is easy: simply wrap the view function with ``cache_page`` when you
+refer to it in the URLconf. Here's the old URLconf from earlier::
+
+ urlpatterns = ('',
+ (r'^foo/(\d{1,2})/$', my_view),
+ )
+
+Here's the same thing, with ``my_view`` wrapped in ``cache_page``::
+
+ from django.views.decorators.cache import cache_page
+
+ urlpatterns = ('',
+ (r'^foo/(\d{1,2})/$', cache_page(my_view, 60 * 15)),
+ )
+
+If you take this approach, don't forget to import ``cache_page`` within your
+URLconf.
+
+Template fragment caching
+=========================
+
+.. versionadded:: 1.0
+
+If you're after even more control, you can also cache template fragments using
+the ``cache`` template tag. To give your template access to this tag, put
+``{% load cache %}`` near the top of your template.
+
+The ``{% cache %}`` template tag caches the contents of the block for a given
+amount of time. It takes at least two arguments: the cache timeout, in seconds,
+and the name to give the cache fragment. For example:
+
+.. code-block:: html+django
+
+ {% load cache %}
+ {% cache 500 sidebar %}
+ .. sidebar ..
+ {% endcache %}
+
+Sometimes you might want to cache multiple copies of a fragment depending on
+some dynamic data that appears inside the fragment. For example, you might want a
+separate cached copy of the sidebar used in the previous example for every user
+of your site. Do this by passing additional arguments to the ``{% cache %}``
+template tag to uniquely identify the cache fragment:
+
+.. code-block:: html+django
+
+ {% load cache %}
+ {% cache 500 sidebar request.user.username %}
+ .. sidebar for logged in user ..
+ {% endcache %}
+
+It's perfectly fine to specify more than one argument to identify the fragment.
+Simply pass as many arguments to ``{% cache %}`` as you need.
+
+If :setting:`USE_I18N` is set to ``True`` the per-site middleware cache will
+:ref:`respect the active language<i18n-cache-key>`. For the ``cache`` template
+tag you could use one of the
+:ref:`translation-specific variables<template-translation-vars>` available in
+templates to archieve the same result:
+
+.. code-block:: html+django
+
+ {% load i18n %}
+ {% load cache %}
+
+ {% get_current_language as LANGUAGE_CODE %}
+
+ {% cache 600 welcome LANGUAGE_CODE %}
+ {% trans "Welcome to example.com" %}
+ {% endcache %}
+
+The cache timeout can be a template variable, as long as the template variable
+resolves to an integer value. For example, if the template variable
+``my_timeout`` is set to the value ``600``, then the following two examples are
+equivalent:
+
+.. code-block:: html+django
+
+ {% cache 600 sidebar %} ... {% endcache %}
+ {% cache my_timeout sidebar %} ... {% endcache %}
+
+This feature is useful in avoiding repetition in templates. You can set the
+timeout in a variable, in one place, and just reuse that value.
+
+The low-level cache API
+=======================
+
+.. highlight:: python
+
+Sometimes, caching an entire rendered page doesn't gain you very much and is,
+in fact, inconvenient overkill.
+
+Perhaps, for instance, your site includes a view whose results depend on
+several expensive queries, the results of which change at different intervals.
+In this case, it would not be ideal to use the full-page caching that the
+per-site or per-view cache strategies offer, because you wouldn't want to
+cache the entire result (since some of the data changes often), but you'd still
+want to cache the results that rarely change.
+
+For cases like this, Django exposes a simple, low-level cache API. You can use
+this API to store objects in the cache with any level of granularity you like.
+You can cache any Python object that can be pickled safely: strings,
+dictionaries, lists of model objects, and so forth. (Most common Python objects
+can be pickled; refer to the Python documentation for more information about
+pickling.)
+
+The cache module, ``django.core.cache``, has a ``cache`` object that's
+automatically created from the ``CACHE_BACKEND`` setting::
+
+ >>> from django.core.cache import cache
+
+The basic interface is ``set(key, value, timeout)`` and ``get(key)``::
+
+ >>> cache.set('my_key', 'hello, world!', 30)
+ >>> cache.get('my_key')
+ 'hello, world!'
+
+The ``timeout`` argument is optional and defaults to the ``timeout``
+argument in the ``CACHE_BACKEND`` setting (explained above). It's the number of
+seconds the value should be stored in the cache.
+
+If the object doesn't exist in the cache, ``cache.get()`` returns ``None``::
+
+ # Wait 30 seconds for 'my_key' to expire...
+
+ >>> cache.get('my_key')
+ None
+
+We advise against storing the literal value ``None`` in the cache, because you
+won't be able to distinguish between your stored ``None`` value and a cache
+miss signified by a return value of ``None``.
+
+``cache.get()`` can take a ``default`` argument. This specifies which value to
+return if the object doesn't exist in the cache::
+
+ >>> cache.get('my_key', 'has expired')
+ 'has expired'
+
+.. versionadded:: 1.0
+
+To add a key only if it doesn't already exist, use the ``add()`` method.
+It takes the same parameters as ``set()``, but it will not attempt to
+update the cache if the key specified is already present::
+
+ >>> cache.set('add_key', 'Initial value')
+ >>> cache.add('add_key', 'New value')
+ >>> cache.get('add_key')
+ 'Initial value'
+
+If you need to know whether ``add()`` stored a value in the cache, you can
+check the return value. It will return ``True`` if the value was stored,
+``False`` otherwise.
+
+There's also a ``get_many()`` interface that only hits the cache once.
+``get_many()`` returns a dictionary with all the keys you asked for that
+actually exist in the cache (and haven't expired)::
+
+ >>> cache.set('a', 1)
+ >>> cache.set('b', 2)
+ >>> cache.set('c', 3)
+ >>> cache.get_many(['a', 'b', 'c'])
+ {'a': 1, 'b': 2, 'c': 3}
+
+.. versionadded:: 1.2
+
+To set multiple values more efficiently, use ``set_many()`` to pass a dictionary
+of key-value pairs::
+
+ >>> cache.set_many({'a': 1, 'b': 2, 'c': 3})
+ >>> cache.get_many(['a', 'b', 'c'])
+ {'a': 1, 'b': 2, 'c': 3}
+
+Like ``cache.set()``, ``set_many()`` takes an optional ``timeout`` parameter.
+
+You can delete keys explicitly with ``delete()``. This is an easy way of
+clearing the cache for a particular object::
+
+ >>> cache.delete('a')
+
+.. versionadded:: 1.2
+
+If you want to clear a bunch of keys at once, ``delete_many()`` can take a list
+of keys to be cleared::
+
+ >>> cache.delete_many(['a', 'b', 'c'])
+
+.. versionadded:: 1.2
+
+Finally, if you want to delete all the keys in the cache, use
+``cache.clear()``. Be careful with this; ``clear()`` will remove *everything*
+from the cache, not just the keys set by your application. ::
+
+ >>> cache.clear()
+
+.. versionadded:: 1.1
+
+You can also increment or decrement a key that already exists using the
+``incr()`` or ``decr()`` methods, respectively. By default, the existing cache
+value will incremented or decremented by 1. Other increment/decrement values
+can be specified by providing an argument to the increment/decrement call. A
+ValueError will be raised if you attempt to increment or decrement a
+nonexistent cache key.::
+
+ >>> cache.set('num', 1)
+ >>> cache.incr('num')
+ 2
+ >>> cache.incr('num', 10)
+ 12
+ >>> cache.decr('num')
+ 11
+ >>> cache.decr('num', 5)
+ 6
+
+.. note::
+
+ ``incr()``/``decr()`` methods are not guaranteed to be atomic. On those
+ backends that support atomic increment/decrement (most notably, the
+ memcached backend), increment and decrement operations will be atomic.
+ However, if the backend doesn't natively provide an increment/decrement
+ operation, it will be implemented using a two-step retrieve/update.
+
+Cache key warnings
+------------------
+
+.. versionadded:: 1.3
+
+Memcached, the most commonly-used production cache backend, does not allow
+cache keys longer than 250 characters or containing whitespace or control
+characters, and using such keys will cause an exception. To encourage
+cache-portable code and minimize unpleasant surprises, the other built-in cache
+backends issue a warning (``django.core.cache.backends.base.CacheKeyWarning``)
+if a key is used that would cause an error on memcached.
+
+If you are using a production backend that can accept a wider range of keys (a
+custom backend, or one of the non-memcached built-in backends), and want to use
+this wider range without warnings, you can silence ``CacheKeyWarning`` with
+this code in the ``management`` module of one of your
+:setting:`INSTALLED_APPS`::
+
+ import warnings
+
+ from django.core.cache import CacheKeyWarning
+
+ warnings.simplefilter("ignore", CacheKeyWarning)
+
+If you want to instead provide custom key validation logic for one of the
+built-in backends, you can subclass it, override just the ``validate_key``
+method, and follow the instructions for `using a custom cache backend`_. For
+instance, to do this for the ``locmem`` backend, put this code in a module::
+
+ from django.core.cache.backends.locmem import CacheClass as LocMemCacheClass
+
+ class CacheClass(LocMemCacheClass):
+ def validate_key(self, key):
+ """Custom validation, raising exceptions or warnings as needed."""
+ # ...
+
+...and use the dotted Python path to this module as the scheme portion of your
+:setting:`CACHE_BACKEND`.
+
+Upstream caches
+===============
+
+So far, this document has focused on caching your *own* data. But another type
+of caching is relevant to Web development, too: caching performed by "upstream"
+caches. These are systems that cache pages for users even before the request
+reaches your Web site.
+
+Here are a few examples of upstream caches:
+
+ * Your ISP may cache certain pages, so if you requested a page from
+ http://example.com/, your ISP would send you the page without having to
+ access example.com directly. The maintainers of example.com have no
+ knowledge of this caching; the ISP sits between example.com and your Web
+ browser, handling all of the caching transparently.
+
+ * Your Django Web site may sit behind a *proxy cache*, such as Squid Web
+ Proxy Cache (http://www.squid-cache.org/), that caches pages for
+ performance. In this case, each request first would be handled by the
+ proxy, and it would be passed to your application only if needed.
+
+ * Your Web browser caches pages, too. If a Web page sends out the
+ appropriate headers, your browser will use the local cached copy for
+ subsequent requests to that page, without even contacting the Web page
+ again to see whether it has changed.
+
+Upstream caching is a nice efficiency boost, but there's a danger to it:
+Many Web pages' contents differ based on authentication and a host of other
+variables, and cache systems that blindly save pages based purely on URLs could
+expose incorrect or sensitive data to subsequent visitors to those pages.
+
+For example, say you operate a Web e-mail system, and the contents of the
+"inbox" page obviously depend on which user is logged in. If an ISP blindly
+cached your site, then the first user who logged in through that ISP would have
+his user-specific inbox page cached for subsequent visitors to the site. That's
+not cool.
+
+Fortunately, HTTP provides a solution to this problem. A number of HTTP headers
+exist to instruct upstream caches to differ their cache contents depending on
+designated variables, and to tell caching mechanisms not to cache particular
+pages. We'll look at some of these headers in the sections that follow.
+
+Using Vary headers
+==================
+
+The ``Vary`` header defines which request headers a cache
+mechanism should take into account when building its cache key. For example, if
+the contents of a Web page depend on a user's language preference, the page is
+said to "vary on language."
+
+By default, Django's cache system creates its cache keys using the requested
+path (e.g., ``"/stories/2005/jun/23/bank_robbed/"``). This means every request
+to that URL will use the same cached version, regardless of user-agent
+differences such as cookies or language preferences. However, if this page
+produces different content based on some difference in request headers -- such
+as a cookie, or a language, or a user-agent -- you'll need to use the ``Vary``
+header to tell caching mechanisms that the page output depends on those things.
+
+To do this in Django, use the convenient ``vary_on_headers`` view decorator,
+like so::
+
+ from django.views.decorators.vary import vary_on_headers
+
+ @vary_on_headers('User-Agent')
+ def my_view(request):
+ # ...
+
+In this case, a caching mechanism (such as Django's own cache middleware) will
+cache a separate version of the page for each unique user-agent.
+
+The advantage to using the ``vary_on_headers`` decorator rather than manually
+setting the ``Vary`` header (using something like
+``response['Vary'] = 'user-agent'``) is that the decorator *adds* to the
+``Vary`` header (which may already exist), rather than setting it from scratch
+and potentially overriding anything that was already in there.
+
+You can pass multiple headers to ``vary_on_headers()``::
+
+ @vary_on_headers('User-Agent', 'Cookie')
+ def my_view(request):
+ # ...
+
+This tells upstream caches to vary on *both*, which means each combination of
+user-agent and cookie will get its own cache value. For example, a request with
+the user-agent ``Mozilla`` and the cookie value ``foo=bar`` will be considered
+different from a request with the user-agent ``Mozilla`` and the cookie value
+``foo=ham``.
+
+Because varying on cookie is so common, there's a ``vary_on_cookie``
+decorator. These two views are equivalent::
+
+ @vary_on_cookie
+ def my_view(request):
+ # ...
+
+ @vary_on_headers('Cookie')
+ def my_view(request):
+ # ...
+
+The headers you pass to ``vary_on_headers`` are not case sensitive;
+``"User-Agent"`` is the same thing as ``"user-agent"``.
+
+You can also use a helper function, ``django.utils.cache.patch_vary_headers``,
+directly. This function sets, or adds to, the ``Vary header``. For example::
+
+ from django.utils.cache import patch_vary_headers
+
+ def my_view(request):
+ # ...
+ response = render_to_response('template_name', context)
+ patch_vary_headers(response, ['Cookie'])
+ return response
+
+``patch_vary_headers`` takes an :class:`~django.http.HttpResponse` instance as
+its first argument and a list/tuple of case-insensitive header names as its
+second argument.
+
+For more on Vary headers, see the `official Vary spec`_.
+
+.. _`official Vary spec`: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.44
+
+Controlling cache: Using other headers
+======================================
+
+Other problems with caching are the privacy of data and the question of where
+data should be stored in a cascade of caches.
+
+A user usually faces two kinds of caches: his or her own browser cache (a
+private cache) and his or her provider's cache (a public cache). A public cache
+is used by multiple users and controlled by someone else. This poses problems
+with sensitive data--you don't want, say, your bank account number stored in a
+public cache. So Web applications need a way to tell caches which data is
+private and which is public.
+
+The solution is to indicate a page's cache should be "private." To do this in
+Django, use the ``cache_control`` view decorator. Example::
+
+ from django.views.decorators.cache import cache_control
+
+ @cache_control(private=True)
+ def my_view(request):
+ # ...
+
+This decorator takes care of sending out the appropriate HTTP header behind the
+scenes.
+
+There are a few other ways to control cache parameters. For example, HTTP
+allows applications to do the following:
+
+ * Define the maximum time a page should be cached.
+
+ * Specify whether a cache should always check for newer versions, only
+ delivering the cached content when there are no changes. (Some caches
+ might deliver cached content even if the server page changed, simply
+ because the cache copy isn't yet expired.)
+
+In Django, use the ``cache_control`` view decorator to specify these cache
+parameters. In this example, ``cache_control`` tells caches to revalidate the
+cache on every access and to store cached versions for, at most, 3,600 seconds::
+
+ from django.views.decorators.cache import cache_control
+
+ @cache_control(must_revalidate=True, max_age=3600)
+ def my_view(request):
+ # ...
+
+Any valid ``Cache-Control`` HTTP directive is valid in ``cache_control()``.
+Here's a full list:
+
+ * ``public=True``
+ * ``private=True``
+ * ``no_cache=True``
+ * ``no_transform=True``
+ * ``must_revalidate=True``
+ * ``proxy_revalidate=True``
+ * ``max_age=num_seconds``
+ * ``s_maxage=num_seconds``
+
+For explanation of Cache-Control HTTP directives, see the `Cache-Control spec`_.
+
+(Note that the caching middleware already sets the cache header's max-age with
+the value of the :setting:`CACHE_MIDDLEWARE_SECONDS` setting. If you use a custom
+``max_age`` in a ``cache_control`` decorator, the decorator will take
+precedence, and the header values will be merged correctly.)
+
+If you want to use headers to disable caching altogether,
+``django.views.decorators.cache.never_cache`` is a view decorator that adds
+headers to ensure the response won't be cached by browsers or other caches.
+Example::
+
+ from django.views.decorators.cache import never_cache
+
+ @never_cache
+ def myview(request):
+ # ...
+
+.. _`Cache-Control spec`: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
+
+Other optimizations
+===================
+
+Django comes with a few other pieces of middleware that can help optimize your
+site's performance:
+
+ * ``django.middleware.http.ConditionalGetMiddleware`` adds support for
+ modern browsers to conditionally GET responses based on the ``ETag``
+ and ``Last-Modified`` headers.
+
+ * ``django.middleware.gzip.GZipMiddleware`` compresses responses for all
+ moderns browsers, saving bandwidth and transfer time.
+
+Order of MIDDLEWARE_CLASSES
+===========================
+
+If you use caching middleware, it's important to put each half in the right
+place within the ``MIDDLEWARE_CLASSES`` setting. That's because the cache
+middleware needs to know which headers by which to vary the cache storage.
+Middleware always adds something to the ``Vary`` response header when it can.
+
+``UpdateCacheMiddleware`` runs during the response phase, where middleware is
+run in reverse order, so an item at the top of the list runs *last* during the
+response phase. Thus, you need to make sure that ``UpdateCacheMiddleware``
+appears *before* any other middleware that might add something to the ``Vary``
+header. The following middleware modules do so:
+
+ * ``SessionMiddleware`` adds ``Cookie``
+ * ``GZipMiddleware`` adds ``Accept-Encoding``
+ * ``LocaleMiddleware`` adds ``Accept-Language``
+
+``FetchFromCacheMiddleware``, on the other hand, runs during the request phase,
+where middleware is applied first-to-last, so an item at the top of the list
+runs *first* during the request phase. The ``FetchFromCacheMiddleware`` also
+needs to run after other middleware updates the ``Vary`` header, so
+``FetchFromCacheMiddleware`` must be *after* any item that does so.
+
diff --git a/parts/django/docs/topics/conditional-view-processing.txt b/parts/django/docs/topics/conditional-view-processing.txt
new file mode 100644
index 0000000..c631a13
--- /dev/null
+++ b/parts/django/docs/topics/conditional-view-processing.txt
@@ -0,0 +1,199 @@
+===========================
+Conditional View Processing
+===========================
+
+.. versionadded:: 1.1
+
+HTTP clients can send a number of headers to tell the server about copies of a
+resource that they have already seen. This is commonly used when retrieving a
+Web page (using an HTTP ``GET`` request) to avoid sending all the data for
+something the client has already retrieved. However, the same headers can be
+used for all HTTP methods (``POST``, ``PUT``, ``DELETE``, etc).
+
+For each page (response) that Django sends back from a view, it might provide
+two HTTP headers: the ``ETag`` header and the ``Last-Modified`` header. These
+headers are optional on HTTP responses. They can be set by your view function,
+or you can rely on the :class:`~django.middleware.common.CommonMiddleware`
+middleware to set the ``ETag`` header.
+
+When the client next requests the same resource, it might send along a header
+such as `If-modified-since`_, containing the date of the last modification
+time it was sent, or `If-none-match`_, containing the ``ETag`` it was sent.
+If the current version of the page matches the ``ETag`` sent by the client, or
+if the resource has not been modified, a 304 status code can be sent back,
+instead of a full response, telling the client that nothing has changed.
+
+.. _If-none-match: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.26
+.. _If-modified-since: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.25
+
+When you need more fine-grained control you may use per-view conditional
+processing functions.
+
+.. conditional-decorators:
+
+The ``condition`` decorator
+===========================
+
+Sometimes (in fact, quite often) you can create functions to rapidly compute the ETag_
+value or the last-modified time for a resource, **without** needing to do all
+the computations needed to construct the full view. Django can then use these
+functions to provide an "early bailout" option for the view processing.
+Telling the client that the content has not been modified since the last
+request, perhaps.
+
+.. _ETag: http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.11
+
+These two functions are passed as parameters the
+``django.views.decorators.http.condition`` decorator. This decorator uses
+the two functions (you only need to supply one, if you can't compute both
+quantities easily and quickly) to work out if the headers in the HTTP request
+match those on the resource. If they don't match, a new copy of the resource
+must be computed and your normal view is called.
+
+The ``condition`` decorator's signature looks like this::
+
+ condition(etag_func=None, last_modified_func=None)
+
+The two functions, to compute the ETag and the last modified time, will be
+passed the incoming ``request`` object and the same parameters, in the same
+order, as the view function they are helping to wrap. The function passed
+``last_modified_func`` should return a standard datetime value specifying the
+last time the resource was modified, or ``None`` if the resource doesn't
+exist. The function passed to the ``etag`` decorator should return a string
+representing the `Etag`_ for the resource, or ``None`` if it doesn't exist.
+
+Using this feature usefully is probably best explained with an example.
+Suppose you have this pair of models, representing a simple blog system::
+
+ import datetime
+ from django.db import models
+
+ class Blog(models.Model):
+ ...
+
+ class Entry(models.Model):
+ blog = models.ForeignKey(Blog)
+ published = models.DateTimeField(default=datetime.datetime.now)
+ ...
+
+If the front page, displaying the latest blog entries, only changes when you
+add a new blog entry, you can compute the last modified time very quickly. You
+need the latest ``published`` date for every entry associated with that blog.
+One way to do this would be::
+
+ def latest_entry(request, blog_id):
+ return Entry.objects.filter(blog=blog_id).latest("published").published
+
+You can then use this function to provide early detection of an unchanged page
+for your front page view::
+
+ from django.views.decorators.http import condition
+
+ @condition(last_modified_func=latest_entry)
+ def front_page(request, blog_id):
+ ...
+
+Shortcuts for only computing one value
+======================================
+
+As a general rule, if you can provide functions to compute *both* the ETag and
+the last modified time, you should do so. You don't know which headers any
+given HTTP client will send you, so be prepared to handle both. However,
+sometimes only one value is easy to compute and Django provides decorators
+that handle only ETag or only last-modified computations.
+
+The ``django.views.decorators.http.etag`` and
+``django.views.decorators.http.last_modified`` decorators are passed the same
+type of functions as the ``condition`` decorator. Their signatures are::
+
+ etag(etag_func)
+ last_modified(last_modified_func)
+
+We could write the earlier example, which only uses a last-modified function,
+using one of these decorators::
+
+ @last_modified(latest_entry)
+ def front_page(request, blog_id):
+ ...
+
+...or::
+
+ def front_page(request, blog_id):
+ ...
+ front_page = last_modified(latest_entry)(front_page)
+
+Use ``condition`` when testing both conditions
+------------------------------------------------
+
+It might look nicer to some people to try and chain the ``etag`` and
+``last_modified`` decorators if you want to test both preconditions. However,
+this would lead to incorrect behavior.
+
+::
+
+ # Bad code. Don't do this!
+ @etag(etag_func)
+ @last_modified(last_modified_func)
+ def my_view(request):
+ # ...
+
+ # End of bad code.
+
+The first decorator doesn't know anything about the second and might
+answer that the response is not modified even if the second decorators would
+determine otherwise. The ``condition`` decorator uses both callback functions
+simultaneously to work out the right action to take.
+
+Using the decorators with other HTTP methods
+============================================
+
+The ``condition`` decorator is useful for more than only ``GET`` and
+``HEAD`` requests (``HEAD`` requests are the same as ``GET`` in this
+situation). It can be used also to be used to provide checking for ``POST``,
+``PUT`` and ``DELETE`` requests. In these situations, the idea isn't to return
+a "not modified" response, but to tell the client that the resource they are
+trying to change has been altered in the meantime.
+
+For example, consider the following exchange between the client and server:
+
+ 1. Client requests ``/foo/``.
+ 2. Server responds with some content with an ETag of ``"abcd1234"``.
+ 3. Client sends an HTTP ``PUT`` request to ``/foo/`` to update the
+ resource. It also sends an ``If-Match: "abcd1234"`` header to specify
+ the version it is trying to update.
+ 4. Server checks to see if the resource has changed, by computing the ETag
+ the same way it does for a ``GET`` request (using the same function).
+ If the resource *has* changed, it will return a 412 status code code,
+ meaning "precondition failed".
+ 5. Client sends a ``GET`` request to ``/foo/``, after receiving a 412
+ response, to retrieve an updated version of the content before updating
+ it.
+
+The important thing this example shows is that the same functions can be used
+to compute the ETag and last modification values in all situations. In fact,
+you **should** use the same functions, so that the same values are returned
+every time.
+
+Comparison with middleware conditional processing
+=================================================
+
+You may notice that Django already provides simple and straightforward
+conditional ``GET`` handling via the
+:class:`django.middleware.http.ConditionalGetMiddleware` and
+:class:`~django.middleware.common.CommonMiddleware`. Whilst certainly being
+easy to use and suitable for many situations, those pieces of middleware
+functionality have limitations for advanced usage:
+
+ * They are applied globally to all views in your project
+ * They don't save you from generating the response itself, which may be
+ expensive
+ * They are only appropriate for HTTP ``GET`` requests.
+
+You should choose the most appropriate tool for your particular problem here.
+If you have a way to compute ETags and modification times quickly and if some
+view takes a while to generate the content, you should consider using the
+``condition`` decorator described in this document. If everything already runs
+fairly quickly, stick to using the middleware and the amount of network
+traffic sent back to the clients will still be reduced if the view hasn't
+changed.
+
diff --git a/parts/django/docs/topics/db/aggregation.txt b/parts/django/docs/topics/db/aggregation.txt
new file mode 100644
index 0000000..eb21021
--- /dev/null
+++ b/parts/django/docs/topics/db/aggregation.txt
@@ -0,0 +1,378 @@
+===========
+Aggregation
+===========
+
+.. versionadded:: 1.1
+
+.. currentmodule:: django.db.models
+
+The topic guide on :doc:`Django's database-abstraction API </topics/db/queries>`
+described the way that you can use Django queries that create,
+retrieve, update and delete individual objects. However, sometimes you will
+need to retrieve values that are derived by summarizing or *aggregating* a
+collection of objects. This topic guide describes the ways that aggregate values
+can be generated and returned using Django queries.
+
+Throughout this guide, we'll refer to the following models. These models are
+used to track the inventory for a series of online bookstores:
+
+.. _queryset-model-example:
+
+.. code-block:: python
+
+ class Author(models.Model):
+ name = models.CharField(max_length=100)
+ age = models.IntegerField()
+ friends = models.ManyToManyField('self', blank=True)
+
+ class Publisher(models.Model):
+ name = models.CharField(max_length=300)
+ num_awards = models.IntegerField()
+
+ class Book(models.Model):
+ isbn = models.CharField(max_length=9)
+ name = models.CharField(max_length=300)
+ pages = models.IntegerField()
+ price = models.DecimalField(max_digits=10, decimal_places=2)
+ rating = models.FloatField()
+ authors = models.ManyToManyField(Author)
+ publisher = models.ForeignKey(Publisher)
+ pubdate = models.DateField()
+
+ class Store(models.Model):
+ name = models.CharField(max_length=300)
+ books = models.ManyToManyField(Book)
+
+
+Generating aggregates over a QuerySet
+=====================================
+
+Django provides two ways to generate aggregates. The first way is to generate
+summary values over an entire ``QuerySet``. For example, say you wanted to
+calculate the average price of all books available for sale. Django's query
+syntax provides a means for describing the set of all books::
+
+ >>> Book.objects.all()
+
+What we need is a way to calculate summary values over the objects that
+belong to this ``QuerySet``. This is done by appending an ``aggregate()``
+clause onto the ``QuerySet``::
+
+ >>> from django.db.models import Avg
+ >>> Book.objects.all().aggregate(Avg('price'))
+ {'price__avg': 34.35}
+
+The ``all()`` is redundant in this example, so this could be simplified to::
+
+ >>> Book.objects.aggregate(Avg('price'))
+ {'price__avg': 34.35}
+
+The argument to the ``aggregate()`` clause describes the aggregate value that
+we want to compute - in this case, the average of the ``price`` field on the
+``Book`` model. A list of the aggregate functions that are available can be
+found in the :ref:`QuerySet reference <aggregation-functions>`.
+
+``aggregate()`` is a terminal clause for a ``QuerySet`` that, when invoked,
+returns a dictionary of name-value pairs. The name is an identifier for the
+aggregate value; the value is the computed aggregate. The name is
+automatically generated from the name of the field and the aggregate function.
+If you want to manually specify a name for the aggregate value, you can do so
+by providing that name when you specify the aggregate clause::
+
+ >>> Book.objects.aggregate(average_price=Avg('price'))
+ {'average_price': 34.35}
+
+If you want to generate more than one aggregate, you just add another
+argument to the ``aggregate()`` clause. So, if we also wanted to know
+the maximum and minimum price of all books, we would issue the query::
+
+ >>> from django.db.models import Avg, Max, Min, Count
+ >>> Book.objects.aggregate(Avg('price'), Max('price'), Min('price'))
+ {'price__avg': 34.35, 'price__max': Decimal('81.20'), 'price__min': Decimal('12.99')}
+
+Generating aggregates for each item in a QuerySet
+=================================================
+
+The second way to generate summary values is to generate an independent
+summary for each object in a ``QuerySet``. For example, if you are retrieving
+a list of books, you may want to know how many authors contributed to
+each book. Each Book has a many-to-many relationship with the Author; we
+want to summarize this relationship for each book in the ``QuerySet``.
+
+Per-object summaries can be generated using the ``annotate()`` clause.
+When an ``annotate()`` clause is specified, each object in the ``QuerySet``
+will be annotated with the specified values.
+
+The syntax for these annotations is identical to that used for the
+``aggregate()`` clause. Each argument to ``annotate()`` describes an
+aggregate that is to be calculated. For example, to annotate Books with
+the number of authors::
+
+ # Build an annotated queryset
+ >>> q = Book.objects.annotate(Count('authors'))
+ # Interrogate the first object in the queryset
+ >>> q[0]
+ <Book: The Definitive Guide to Django>
+ >>> q[0].authors__count
+ 2
+ # Interrogate the second object in the queryset
+ >>> q[1]
+ <Book: Practical Django Projects>
+ >>> q[1].authors__count
+ 1
+
+As with ``aggregate()``, the name for the annotation is automatically derived
+from the name of the aggregate function and the name of the field being
+aggregated. You can override this default name by providing an alias when you
+specify the annotation::
+
+ >>> q = Book.objects.annotate(num_authors=Count('authors'))
+ >>> q[0].num_authors
+ 2
+ >>> q[1].num_authors
+ 1
+
+Unlike ``aggregate()``, ``annotate()`` is *not* a terminal clause. The output
+of the ``annotate()`` clause is a ``QuerySet``; this ``QuerySet`` can be
+modified using any other ``QuerySet`` operation, including ``filter()``,
+``order_by``, or even additional calls to ``annotate()``.
+
+Joins and aggregates
+====================
+
+So far, we have dealt with aggregates over fields that belong to the
+model being queried. However, sometimes the value you want to aggregate
+will belong to a model that is related to the model you are querying.
+
+When specifying the field to be aggregated in an aggregate function, Django
+will allow you to use the same :ref:`double underscore notation
+<field-lookups-intro>` that is used when referring to related fields in
+filters. Django will then handle any table joins that are required to retrieve
+and aggregate the related value.
+
+For example, to find the price range of books offered in each store,
+you could use the annotation::
+
+ >>> Store.objects.annotate(min_price=Min('books__price'), max_price=Max('books__price'))
+
+This tells Django to retrieve the Store model, join (through the
+many-to-many relationship) with the Book model, and aggregate on the
+price field of the book model to produce a minimum and maximum value.
+
+The same rules apply to the ``aggregate()`` clause. If you wanted to
+know the lowest and highest price of any book that is available for sale
+in a store, you could use the aggregate::
+
+ >>> Store.objects.aggregate(min_price=Min('books__price'), max_price=Max('books__price'))
+
+Join chains can be as deep as you require. For example, to extract the
+age of the youngest author of any book available for sale, you could
+issue the query::
+
+ >>> Store.objects.aggregate(youngest_age=Min('books__authors__age'))
+
+Aggregations and other QuerySet clauses
+=======================================
+
+``filter()`` and ``exclude()``
+------------------------------
+
+Aggregates can also participate in filters. Any ``filter()`` (or
+``exclude()``) applied to normal model fields will have the effect of
+constraining the objects that are considered for aggregation.
+
+When used with an ``annotate()`` clause, a filter has the effect of
+constraining the objects for which an annotation is calculated. For example,
+you can generate an annotated list of all books that have a title starting
+with "Django" using the query::
+
+ >>> Book.objects.filter(name__startswith="Django").annotate(num_authors=Count('authors'))
+
+When used with an ``aggregate()`` clause, a filter has the effect of
+constraining the objects over which the aggregate is calculated.
+For example, you can generate the average price of all books with a
+title that starts with "Django" using the query::
+
+ >>> Book.objects.filter(name__startswith="Django").aggregate(Avg('price'))
+
+Filtering on annotations
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Annotated values can also be filtered. The alias for the annotation can be
+used in ``filter()`` and ``exclude()`` clauses in the same way as any other
+model field.
+
+For example, to generate a list of books that have more than one author,
+you can issue the query::
+
+ >>> Book.objects.annotate(num_authors=Count('authors')).filter(num_authors__gt=1)
+
+This query generates an annotated result set, and then generates a filter
+based upon that annotation.
+
+Order of ``annotate()`` and ``filter()`` clauses
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+When developing a complex query that involves both ``annotate()`` and
+``filter()`` clauses, particular attention should be paid to the order
+in which the clauses are applied to the ``QuerySet``.
+
+When an ``annotate()`` clause is applied to a query, the annotation is
+computed over the state of the query up to the point where the annotation
+is requested. The practical implication of this is that ``filter()`` and
+``annotate()`` are not commutative operations -- that is, there is a
+difference between the query::
+
+ >>> Publisher.objects.annotate(num_books=Count('book')).filter(book__rating__gt=3.0)
+
+and the query::
+
+ >>> Publisher.objects.filter(book__rating__gt=3.0).annotate(num_books=Count('book'))
+
+Both queries will return a list of Publishers that have at least one good
+book (i.e., a book with a rating exceeding 3.0). However, the annotation in
+the first query will provide the total number of all books published by the
+publisher; the second query will only include good books in the annotated
+count. In the first query, the annotation precedes the filter, so the
+filter has no effect on the annotation. In the second query, the filter
+preceeds the annotation, and as a result, the filter constrains the objects
+considered when calculating the annotation.
+
+``order_by()``
+--------------
+
+Annotations can be used as a basis for ordering. When you
+define an ``order_by()`` clause, the aggregates you provide can reference
+any alias defined as part of an ``annotate()`` clause in the query.
+
+For example, to order a ``QuerySet`` of books by the number of authors
+that have contributed to the book, you could use the following query::
+
+ >>> Book.objects.annotate(num_authors=Count('authors')).order_by('num_authors')
+
+``values()``
+------------
+
+Ordinarily, annotations are generated on a per-object basis - an annotated
+``QuerySet`` will return one result for each object in the original
+``QuerySet``. However, when a ``values()`` clause is used to constrain the
+columns that are returned in the result set, the method for evaluating
+annotations is slightly different. Instead of returning an annotated result
+for each result in the original ``QuerySet``, the original results are
+grouped according to the unique combinations of the fields specified in the
+``values()`` clause. An annotation is then provided for each unique group;
+the annotation is computed over all members of the group.
+
+For example, consider an author query that attempts to find out the average
+rating of books written by each author:
+
+ >>> Author.objects.annotate(average_rating=Avg('book__rating'))
+
+This will return one result for each author in the database, annotated with
+their average book rating.
+
+However, the result will be slightly different if you use a ``values()`` clause::
+
+ >>> Author.objects.values('name').annotate(average_rating=Avg('book__rating'))
+
+In this example, the authors will be grouped by name, so you will only get
+an annotated result for each *unique* author name. This means if you have
+two authors with the same name, their results will be merged into a single
+result in the output of the query; the average will be computed as the
+average over the books written by both authors.
+
+Order of ``annotate()`` and ``values()`` clauses
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As with the ``filter()`` clause, the order in which ``annotate()`` and
+``values()`` clauses are applied to a query is significant. If the
+``values()`` clause precedes the ``annotate()``, the annotation will be
+computed using the grouping described by the ``values()`` clause.
+
+However, if the ``annotate()`` clause precedes the ``values()`` clause,
+the annotations will be generated over the entire query set. In this case,
+the ``values()`` clause only constrains the fields that are generated on
+output.
+
+For example, if we reverse the order of the ``values()`` and ``annotate()``
+clause from our previous example::
+
+ >>> Author.objects.annotate(average_rating=Avg('book__rating')).values('name', 'average_rating')
+
+This will now yield one unique result for each author; however, only
+the author's name and the ``average_rating`` annotation will be returned
+in the output data.
+
+You should also note that ``average_rating`` has been explicitly included
+in the list of values to be returned. This is required because of the
+ordering of the ``values()`` and ``annotate()`` clause.
+
+If the ``values()`` clause precedes the ``annotate()`` clause, any annotations
+will be automatically added to the result set. However, if the ``values()``
+clause is applied after the ``annotate()`` clause, you need to explicitly
+include the aggregate column.
+
+Interaction with default ordering or ``order_by()``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Fields that are mentioned in the ``order_by()`` part of a queryset (or which
+are used in the default ordering on a model) are used when selecting the
+output data, even if they are not otherwise specified in the ``values()``
+call. These extra fields are used to group "like" results together and they
+can make otherwise identical result rows appear to be separate. This shows up,
+particularly, when counting things.
+
+By way of example, suppose you have a model like this::
+
+ class Item(models.Model):
+ name = models.CharField(max_length=10)
+ data = models.IntegerField()
+
+ class Meta:
+ ordering = ["name"]
+
+The important part here is the default ordering on the ``name`` field. If you
+want to count how many times each distinct ``data`` value appears, you might
+try this::
+
+ # Warning: not quite correct!
+ Item.objects.values("data").annotate(Count("id"))
+
+...which will group the ``Item`` objects by their common ``data`` values and
+then count the number of ``id`` values in each group. Except that it won't
+quite work. The default ordering by ``name`` will also play a part in the
+grouping, so this query will group by distinct ``(data, name)`` pairs, which
+isn't what you want. Instead, you should construct this queryset::
+
+ Item.objects.values("data").annotate(Count("id")).order_by()
+
+...clearing any ordering in the query. You could also order by, say, ``data``
+without any harmful effects, since that is already playing a role in the
+query.
+
+This behavior is the same as that noted in the queryset documentation for
+:meth:`~django.db.models.QuerySet.distinct` and the general rule is the same:
+normally you won't want extra columns playing a part in the result, so clear
+out the ordering, or at least make sure it's restricted only to those fields
+you also select in a ``values()`` call.
+
+.. note::
+ You might reasonably ask why Django doesn't remove the extraneous columns
+ for you. The main reason is consistency with ``distinct()`` and other
+ places: Django **never** removes ordering constraints that you have
+ specified (and we can't change those other methods' behavior, as that
+ would violate our :doc:`/misc/api-stability` policy).
+
+Aggregating annotations
+-----------------------
+
+You can also generate an aggregate on the result of an annotation. When you
+define an ``aggregate()`` clause, the aggregates you provide can reference
+any alias defined as part of an ``annotate()`` clause in the query.
+
+For example, if you wanted to calculate the average number of authors per
+book you first annotate the set of books with the author count, then
+aggregate that author count, referencing the annotation field::
+
+ >>> Book.objects.annotate(num_authors=Count('authors')).aggregate(Avg('num_authors'))
+ {'num_authors__avg': 1.66}
diff --git a/parts/django/docs/topics/db/index.txt b/parts/django/docs/topics/db/index.txt
new file mode 100644
index 0000000..c49f158
--- /dev/null
+++ b/parts/django/docs/topics/db/index.txt
@@ -0,0 +1,18 @@
+Models and databases
+====================
+
+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. Generally, each
+model maps to a single database table.
+
+.. toctree::
+ :maxdepth: 1
+
+ models
+ queries
+ aggregation
+ managers
+ sql
+ transactions
+ multi-db
+ optimization
diff --git a/parts/django/docs/topics/db/managers.txt b/parts/django/docs/topics/db/managers.txt
new file mode 100644
index 0000000..5ebe0b1
--- /dev/null
+++ b/parts/django/docs/topics/db/managers.txt
@@ -0,0 +1,376 @@
+========
+Managers
+========
+
+.. currentmodule:: django.db.models
+
+.. class:: Manager()
+
+A ``Manager`` is the interface through which database query operations are
+provided to Django models. At least one ``Manager`` exists for every model in
+a Django application.
+
+The way ``Manager`` classes work is documented in :doc:`/topics/db/queries`;
+this document specifically touches on model options that customize ``Manager``
+behavior.
+
+.. _manager-names:
+
+Manager names
+=============
+
+By default, Django adds a ``Manager`` with the name ``objects`` to every Django
+model class. However, if you want to use ``objects`` as a field name, or if you
+want to use a name other than ``objects`` for the ``Manager``, you can rename
+it on a per-model basis. To rename the ``Manager`` for a given class, define a
+class attribute of type ``models.Manager()`` on that model. For example::
+
+ from django.db import models
+
+ class Person(models.Model):
+ #...
+ people = models.Manager()
+
+Using this example model, ``Person.objects`` will generate an
+``AttributeError`` exception, but ``Person.people.all()`` will provide a list
+of all ``Person`` objects.
+
+.. _custom-managers:
+
+Custom Managers
+===============
+
+You can use a custom ``Manager`` in a particular model by extending the base
+``Manager`` class and instantiating your custom ``Manager`` in your model.
+
+There are two reasons you might want to customize a ``Manager``: to add extra
+``Manager`` methods, and/or to modify the initial ``QuerySet`` the ``Manager``
+returns.
+
+Adding extra Manager methods
+----------------------------
+
+Adding extra ``Manager`` methods is the preferred way to add "table-level"
+functionality to your models. (For "row-level" functionality -- i.e., functions
+that act on a single instance of a model object -- use :ref:`Model methods
+<model-methods>`, not custom ``Manager`` methods.)
+
+A custom ``Manager`` method can return anything you want. It doesn't have to
+return a ``QuerySet``.
+
+For example, this custom ``Manager`` offers a method ``with_counts()``, which
+returns a list of all ``OpinionPoll`` objects, each with an extra
+``num_responses`` attribute that is the result of an aggregate query::
+
+ class PollManager(models.Manager):
+ def with_counts(self):
+ from django.db import connection
+ cursor = connection.cursor()
+ cursor.execute("""
+ SELECT p.id, p.question, p.poll_date, COUNT(*)
+ FROM polls_opinionpoll p, polls_response r
+ WHERE p.id = r.poll_id
+ GROUP BY 1, 2, 3
+ ORDER BY 3 DESC""")
+ result_list = []
+ for row in cursor.fetchall():
+ p = self.model(id=row[0], question=row[1], poll_date=row[2])
+ p.num_responses = row[3]
+ result_list.append(p)
+ return result_list
+
+ class OpinionPoll(models.Model):
+ question = models.CharField(max_length=200)
+ poll_date = models.DateField()
+ objects = PollManager()
+
+ class Response(models.Model):
+ poll = models.ForeignKey(Poll)
+ person_name = models.CharField(max_length=50)
+ response = models.TextField()
+
+With this example, you'd use ``OpinionPoll.objects.with_counts()`` to return
+that list of ``OpinionPoll`` objects with ``num_responses`` attributes.
+
+Another thing to note about this example is that ``Manager`` methods can
+access ``self.model`` to get the model class to which they're attached.
+
+Modifying initial Manager QuerySets
+-----------------------------------
+
+A ``Manager``'s base ``QuerySet`` returns all objects in the system. For
+example, using this model::
+
+ class Book(models.Model):
+ title = models.CharField(max_length=100)
+ author = models.CharField(max_length=50)
+
+...the statement ``Book.objects.all()`` will return all books in the database.
+
+You can override a ``Manager``\'s base ``QuerySet`` by overriding the
+``Manager.get_query_set()`` method. ``get_query_set()`` should return a
+``QuerySet`` with the properties you require.
+
+For example, the following model has *two* ``Manager``\s -- one that returns
+all objects, and one that returns only the books by Roald Dahl::
+
+ # First, define the Manager subclass.
+ class DahlBookManager(models.Manager):
+ def get_query_set(self):
+ return super(DahlBookManager, self).get_query_set().filter(author='Roald Dahl')
+
+ # Then hook it into the Book model explicitly.
+ class Book(models.Model):
+ title = models.CharField(max_length=100)
+ author = models.CharField(max_length=50)
+
+ objects = models.Manager() # The default manager.
+ dahl_objects = DahlBookManager() # The Dahl-specific manager.
+
+With this sample model, ``Book.objects.all()`` will return all books in the
+database, but ``Book.dahl_objects.all()`` will only return the ones written by
+Roald Dahl.
+
+Of course, because ``get_query_set()`` returns a ``QuerySet`` object, you can
+use ``filter()``, ``exclude()`` and all the other ``QuerySet`` methods on it.
+So these statements are all legal::
+
+ Book.dahl_objects.all()
+ Book.dahl_objects.filter(title='Matilda')
+ Book.dahl_objects.count()
+
+This example also pointed out another interesting technique: using multiple
+managers on the same model. You can attach as many ``Manager()`` instances to
+a model as you'd like. This is an easy way to define common "filters" for your
+models.
+
+For example::
+
+ class MaleManager(models.Manager):
+ def get_query_set(self):
+ return super(MaleManager, self).get_query_set().filter(sex='M')
+
+ class FemaleManager(models.Manager):
+ def get_query_set(self):
+ return super(FemaleManager, self).get_query_set().filter(sex='F')
+
+ class Person(models.Model):
+ first_name = models.CharField(max_length=50)
+ last_name = models.CharField(max_length=50)
+ sex = models.CharField(max_length=1, choices=(('M', 'Male'), ('F', 'Female')))
+ people = models.Manager()
+ men = MaleManager()
+ women = FemaleManager()
+
+This example allows you to request ``Person.men.all()``, ``Person.women.all()``,
+and ``Person.people.all()``, yielding predictable results.
+
+If you use custom ``Manager`` objects, take note that the first ``Manager``
+Django encounters (in the order in which they're defined in the model) has a
+special status. Django interprets the first ``Manager`` defined in a class as
+the "default" ``Manager``, and several parts of Django
+(including :djadmin:`dumpdata`) will use that ``Manager``
+exclusively for that model. As a result, it's a good idea to be careful in
+your choice of default manager in order to avoid a situation where overriding
+``get_query_set()`` results in an inability to retrieve objects you'd like to
+work with.
+
+.. _managers-for-related-objects:
+
+Using managers for related object access
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+By default, Django uses an instance of a "plain" manager class when accessing
+related objects (i.e. ``choice.poll``), not the default manager on the related
+object. This is because Django needs to be able to retrieve the related
+object, even if it would otherwise be filtered out (and hence be inaccessible)
+by the default manager.
+
+If the normal plain manager class (:class:`django.db.models.Manager`) is not
+appropriate for your circumstances, you can force Django to use the same class
+as the default manager for your model by setting the `use_for_related_fields`
+attribute on the manager class. This is documented fully below_.
+
+.. _below: manager-types_
+
+.. _custom-managers-and-inheritance:
+
+Custom managers and model inheritance
+-------------------------------------
+
+Class inheritance and model managers aren't quite a perfect match for each
+other. Managers are often specific to the classes they are defined on and
+inheriting them in subclasses isn't necessarily a good idea. Also, because the
+first manager declared is the *default manager*, it is important to allow that
+to be controlled. So here's how Django handles custom managers and
+:ref:`model inheritance <model-inheritance>`:
+
+ 1. Managers defined on non-abstract base classes are *not* inherited by
+ child classes. If you want to reuse a manager from a non-abstract base,
+ redeclare it explicitly on the child class. These sorts of managers are
+ likely to be fairly specific to the class they are defined on, so
+ inheriting them can often lead to unexpected results (particularly as
+ far as the default manager goes). Therefore, they aren't passed onto
+ child classes.
+
+ 2. Managers from abstract base classes are always inherited by the child
+ class, using Python's normal name resolution order (names on the child
+ class override all others; then come names on the first parent class,
+ and so on). Abstract base classes are designed to capture information
+ and behavior that is common to their child classes. Defining common
+ managers is an appropriate part of this common information.
+
+ 3. The default manager on a class is either the first manager declared on
+ the class, if that exists, or the default manager of the first abstract
+ base class in the parent hierarchy, if that exists. If no default
+ manager is explicitly declared, Django's normal default manager is
+ used.
+
+These rules provide the necessary flexibility if you want to install a
+collection of custom managers on a group of models, via an abstract base
+class, but still customize the default manager. For example, suppose you have
+this base class::
+
+ class AbstractBase(models.Model):
+ ...
+ objects = CustomManager()
+
+ class Meta:
+ abstract = True
+
+If you use this directly in a subclass, ``objects`` will be the default
+manager if you declare no managers in the base class::
+
+ class ChildA(AbstractBase):
+ ...
+ # This class has CustomManager as the default manager.
+
+If you want to inherit from ``AbstractBase``, but provide a different default
+manager, you can provide the default manager on the child class::
+
+ class ChildB(AbstractBase):
+ ...
+ # An explicit default manager.
+ default_manager = OtherManager()
+
+Here, ``default_manager`` is the default. The ``objects`` manager is
+still available, since it's inherited. It just isn't used as the default.
+
+Finally for this example, suppose you want to add extra managers to the child
+class, but still use the default from ``AbstractBase``. You can't add the new
+manager directly in the child class, as that would override the default and you would
+have to also explicitly include all the managers from the abstract base class.
+The solution is to put the extra managers in another base class and introduce
+it into the inheritance hierarchy *after* the defaults::
+
+ class ExtraManager(models.Model):
+ extra_manager = OtherManager()
+
+ class Meta:
+ abstract = True
+
+ class ChildC(AbstractBase, ExtraManager):
+ ...
+ # Default manager is CustomManager, but OtherManager is
+ # also available via the "extra_manager" attribute.
+
+.. _manager-types:
+
+Controlling Automatic Manager Types
+===================================
+
+This document has already mentioned a couple of places where Django creates a
+manager class for you: `default managers`_ and the "plain" manager used to
+`access related objects`_. There are other places in the implementation of
+Django where temporary plain managers are needed. Those automatically created
+managers will normally be instances of the :class:`django.db.models.Manager`
+class.
+
+.. _default managers: manager-names_
+.. _access related objects: managers-for-related-objects_
+
+Throughout this section, we will use the term "automatic manager" to mean a
+manager that Django creates for you -- either as a default manager on a model
+with no managers, or to use temporarily when accessing related objects.
+
+Sometimes this default class won't be the right choice. One example is in the
+:mod:`django.contrib.gis` application that ships with Django itself. All ``gis``
+models must use a special manager class (:class:`~django.contrib.gis.db.models.GeoManager`)
+because they need a special queryset (:class:`~django.contrib.gis.db.models.GeoQuerySet`)
+to be used for interacting with the database. It turns out that models which require
+a special manager like this need to use the same manager class wherever an automatic
+manager is created.
+
+Django provides a way for custom manager developers to say that their manager
+class should be used for automatic managers whenever it is the default manager
+on a model. This is done by setting the ``use_for_related_fields`` attribute on
+the manager class::
+
+ class MyManager(models.Manager):
+ use_for_related_fields = True
+
+ ...
+
+If this attribute is set on the *default* manager for a model (only the
+default manager is considered in these situations), Django will use that class
+whenever it needs to automatically create a manager for the class. Otherwise,
+it will use :class:`django.db.models.Manager`.
+
+.. admonition:: Historical Note
+
+ Given the purpose for which it's used, the name of this attribute
+ (``use_for_related_fields``) might seem a little odd. Originally, the
+ attribute only controlled the type of manager used for related field
+ access, which is where the name came from. As it became clear the concept
+ was more broadly useful, the name hasn't been changed. This is primarily
+ so that existing code will :doc:`continue to work </misc/api-stability>` in
+ future Django versions.
+
+Writing Correct Managers For Use In Automatic Manager Instances
+---------------------------------------------------------------
+
+As already suggested by the `django.contrib.gis` example, above, the
+``use_for_related_fields`` feature is primarily for managers that need to
+return a custom ``QuerySet`` subclass. In providing this functionality in your
+manager, there are a couple of things to remember.
+
+Do not filter away any results in this type of manager subclass
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+One reason an automatic manager is used is to access objects that are related
+to from some other model. In those situations, Django has to be able to see
+all the objects for the model it is fetching, so that *anything* which is
+referred to can be retrieved.
+
+If you override the ``get_query_set()`` method and filter out any rows, Django
+will return incorrect results. Don't do that. A manager that filters results
+in ``get_query_set()`` is not appropriate for use as an automatic manager.
+
+Set ``use_for_related_fields`` when you define the class
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ``use_for_related_fields`` attribute must be set on the manager *class*,
+object not on an *instance* of the class. The earlier example shows the
+correct way to set it, whereas the following will not work::
+
+ # BAD: Incorrect code
+ class MyManager(models.Manager):
+ ...
+
+ # Sets the attribute on an instance of MyManager. Django will
+ # ignore this setting.
+ mgr = MyManager()
+ mgr.use_for_related_fields = True
+
+ class MyModel(models.Model):
+ ...
+ objects = mgr
+
+ # End of incorrect code.
+
+You also shouldn't change the attribute on the class object after it has been
+used in a model, since the attribute's value is processed when the model class
+is created and not subsequently reread. Set the attribute on the manager class
+when it is first defined, as in the initial example of this section and
+everything will work smoothly.
+
diff --git a/parts/django/docs/topics/db/models.txt b/parts/django/docs/topics/db/models.txt
new file mode 100644
index 0000000..2a19cbd
--- /dev/null
+++ b/parts/django/docs/topics/db/models.txt
@@ -0,0 +1,1234 @@
+======
+Models
+======
+
+.. module:: django.db.models
+
+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. Generally, each
+model maps to a single database table.
+
+The basics:
+
+ * Each model is a Python class that subclasses
+ :class:`django.db.models.Model`.
+
+ * Each attribute of the model represents a database field.
+
+ * With all of this, Django gives you an automatically-generated
+ database-access API; see :doc:`/topics/db/queries`.
+
+.. seealso::
+
+ A companion to this document is the `official repository of model
+ examples`_. (In the Django source distribution, these examples are in the
+ ``tests/modeltests`` directory.)
+
+ .. _official repository of model examples: http://www.djangoproject.com/documentation/models/
+
+Quick example
+=============
+
+This example model defines a ``Person``, which has a ``first_name`` and
+``last_name``::
+
+ from django.db import models
+
+ class Person(models.Model):
+ first_name = models.CharField(max_length=30)
+ last_name = models.CharField(max_length=30)
+
+``first_name`` and ``last_name`` are fields_ of the model. Each field is
+specified as a class attribute, and each attribute maps to a database column.
+
+The above ``Person`` model would create a database table like this:
+
+.. code-block:: sql
+
+ CREATE TABLE myapp_person (
+ "id" serial NOT NULL PRIMARY KEY,
+ "first_name" varchar(30) NOT NULL,
+ "last_name" varchar(30) NOT NULL
+ );
+
+Some technical notes:
+
+ * The name of the table, ``myapp_person``, is automatically derived from
+ some model metadata but can be overridden. See :ref:`table-names` for more
+ details..
+
+ * An ``id`` field is added automatically, but this behavior can be
+ overridden. See :ref:`automatic-primary-key-fields`.
+
+ * The ``CREATE TABLE`` SQL in this example is formatted using PostgreSQL
+ syntax, but it's worth noting Django uses SQL tailored to the database
+ backend specified in your :doc:`settings file </topics/settings>`.
+
+Using models
+============
+
+Once you have defined your models, you need to tell Django you're going to *use*
+those models. Do this by editing your settings file and changing the
+:setting:`INSTALLED_APPS` setting to add the name of the module that contains
+your ``models.py``.
+
+For example, if the models for your application live in the module
+``mysite.myapp.models`` (the package structure that is created for an
+application by the :djadmin:`manage.py startapp <startapp>` script),
+:setting:`INSTALLED_APPS` should read, in part::
+
+ INSTALLED_APPS = (
+ #...
+ 'mysite.myapp',
+ #...
+ )
+
+When you add new apps to :setting:`INSTALLED_APPS`, be sure to run
+:djadmin:`manage.py syncdb <syncdb>`.
+
+Fields
+======
+
+The most important part of a model -- and the only required part of a model --
+is the list of database fields it defines. Fields are specified by class
+attributes.
+
+Example::
+
+ class Musician(models.Model):
+ first_name = models.CharField(max_length=50)
+ last_name = models.CharField(max_length=50)
+ instrument = models.CharField(max_length=100)
+
+ class Album(models.Model):
+ artist = models.ForeignKey(Musician)
+ name = models.CharField(max_length=100)
+ release_date = models.DateField()
+ num_stars = models.IntegerField()
+
+Field types
+-----------
+
+Each field in your model should be an instance of the appropriate
+:class:`~django.db.models.Field` class. Django uses the field class types to
+determine a few things:
+
+ * The database column type (e.g. ``INTEGER``, ``VARCHAR``).
+
+ * The :doc:`widget </ref/forms/widgets>` to use in Django's admin interface,
+ if you care to use it (e.g. ``<input type="text">``, ``<select>``).
+
+ * The minimal validation requirements, used in Django's admin and in
+ automatically-generated forms.
+
+Django ships with dozens of built-in field types; you can find the complete list
+in the :ref:`model field reference <model-field-types>`. You can easily write
+your own fields if Django's built-in ones don't do the trick; see
+:doc:`/howto/custom-model-fields`.
+
+Field options
+-------------
+
+Each field takes a certain set of field-specific arguments (documented in the
+:ref:`model field reference <model-field-types>`). For example,
+:class:`~django.db.models.CharField` (and its subclasses) require a
+:attr:`~django.db.models.CharField.max_length` argument which specifies the size
+of the ``VARCHAR`` database field used to store the data.
+
+There's also a set of common arguments available to all field types. All are
+optional. They're fully explained in the :ref:`reference
+<common-model-field-options>`, but here's a quick summary of the most often-used
+ones:
+
+ :attr:`~Field.null`
+ If ``True``, Django will store empty values as ``NULL`` in the database.
+ Default is ``False``.
+
+ :attr:`~Field.blank`
+ If ``True``, the field is allowed to be blank. Default is ``False``.
+
+ Note that this is different than :attr:`~Field.null`.
+ :attr:`~Field.null` is purely database-related, whereas
+ :attr:`~Field.blank` is validation-related. If a field has
+ :attr:`blank=True <Field.blank>`, validation on Django's admin site will
+ allow entry of an empty value. If a field has :attr:`blank=False
+ <Field.blank>`, the field will be required.
+
+ :attr:`~Field.choices`
+ An iterable (e.g., a list or tuple) of 2-tuples to use as choices for
+ this field. If this is given, Django's admin will use a select box
+ instead of the standard text field and will limit choices to the choices
+ given.
+
+ A choices list looks like this::
+
+ YEAR_IN_SCHOOL_CHOICES = (
+ (u'FR', u'Freshman'),
+ (u'SO', u'Sophomore'),
+ (u'JR', u'Junior'),
+ (u'SR', u'Senior'),
+ (u'GR', u'Graduate'),
+ )
+
+ The first element in each tuple is the value that will be stored in the
+ database, the second element will be displayed by the admin interface,
+ or in a ModelChoiceField. Given an instance of a model object, the
+ display value for a choices field can be accessed using the
+ ``get_FOO_display`` method. For example::
+
+ from django.db import models
+
+ class Person(models.Model):
+ GENDER_CHOICES = (
+ (u'M', u'Male'),
+ (u'F', u'Female'),
+ )
+ name = models.CharField(max_length=60)
+ gender = models.CharField(max_length=2, choices=GENDER_CHOICES)
+
+ ::
+
+ >>> p = Person(name="Fred Flinstone", gender="M")
+ >>> p.save()
+ >>> p.gender
+ u'M'
+ >>> p.get_gender_display()
+ u'Male'
+
+ :attr:`~Field.default`
+ The default value for the field. This can be a value or a callable
+ object. If callable it will be called every time a new object is
+ created.
+
+ :attr:`~Field.help_text`
+ Extra "help" text to be displayed under the field on the object's admin
+ form. It's useful for documentation even if your object doesn't have an
+ admin form.
+
+ :attr:`~Field.primary_key`
+ If ``True``, this field is the primary key for the model.
+
+ If you don't specify :attr:`primary_key=True <Field.primary_key>` for
+ any fields in your model, Django will automatically add an
+ :class:`IntegerField` to hold the primary key, so you don't need to set
+ :attr:`primary_key=True <Field.primary_key>` on any of your fields
+ unless you want to override the default primary-key behavior. For more,
+ see :ref:`automatic-primary-key-fields`.
+
+ :attr:`~Field.unique`
+ If ``True``, this field must be unique throughout the table.
+
+Again, these are just short descriptions of the most common field options. Full
+details can be found in the :ref:`common model field option reference
+<common-model-field-options>`.
+
+.. _automatic-primary-key-fields:
+
+Automatic primary key fields
+----------------------------
+
+By default, Django gives each model the following field::
+
+ id = models.AutoField(primary_key=True)
+
+This is an auto-incrementing primary key.
+
+If you'd like to specify a custom primary key, just specify
+:attr:`primary_key=True <Field.primary_key>` on one of your fields. If Django
+sees you've explicitly set :attr:`Field.primary_key`, it won't add the automatic
+``id`` column.
+
+Each model requires exactly one field to have :attr:`primary_key=True
+<Field.primary_key>`.
+
+.. _verbose-field-names:
+
+Verbose field names
+-------------------
+
+Each field type, except for :class:`~django.db.models.ForeignKey`,
+:class:`~django.db.models.ManyToManyField` and
+:class:`~django.db.models.OneToOneField`, takes an optional first positional
+argument -- a verbose name. If the verbose name isn't given, Django will
+automatically create it using the field's attribute name, converting underscores
+to spaces.
+
+In this example, the verbose name is ``"person's first name"``::
+
+ first_name = models.CharField("person's first name", max_length=30)
+
+In this example, the verbose name is ``"first name"``::
+
+ first_name = models.CharField(max_length=30)
+
+:class:`~django.db.models.ForeignKey`,
+:class:`~django.db.models.ManyToManyField` and
+:class:`~django.db.models.OneToOneField` require the first argument to be a
+model class, so use the :attr:`~Field.verbose_name` keyword argument::
+
+ poll = models.ForeignKey(Poll, verbose_name="the related poll")
+ sites = models.ManyToManyField(Site, verbose_name="list of sites")
+ place = models.OneToOneField(Place, verbose_name="related place")
+
+The convention is not to capitalize the first letter of the
+:attr:`~Field.verbose_name`. Django will automatically capitalize the first
+letter where it needs to.
+
+Relationships
+-------------
+
+Clearly, the power of relational databases lies in relating tables to each
+other. Django offers ways to define the three most common types of database
+relationships: many-to-one, many-to-many and one-to-one.
+
+Many-to-one relationships
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To define a many-to-one relationship, use :class:`~django.db.models.ForeignKey`.
+You use it just like any other :class:`~django.db.models.Field` type: by
+including it as a class attribute of your model.
+
+:class:`~django.db.models.ForeignKey` requires a positional argument: the class
+to which the model is related.
+
+For example, if a ``Car`` model has a ``Manufacturer`` -- that is, a
+``Manufacturer`` makes multiple cars but each ``Car`` only has one
+``Manufacturer`` -- use the following definitions::
+
+ class Manufacturer(models.Model):
+ # ...
+
+ class Car(models.Model):
+ manufacturer = models.ForeignKey(Manufacturer)
+ # ...
+
+You can also create :ref:`recursive relationships <recursive-relationships>` (an
+object with a many-to-one relationship to itself) and :ref:`relationships to
+models not yet defined <lazy-relationships>`; see :ref:`the model field
+reference <ref-foreignkey>` for details.
+
+It's suggested, but not required, that the name of a
+:class:`~django.db.models.ForeignKey` field (``manufacturer`` in the example
+above) be the name of the model, lowercase. You can, of course, call the field
+whatever you want. For example::
+
+ class Car(models.Model):
+ company_that_makes_it = models.ForeignKey(Manufacturer)
+ # ...
+
+.. seealso::
+
+ See the `Many-to-one relationship model example`_ for a full example.
+
+.. _Many-to-one relationship model example: http://www.djangoproject.com/documentation/models/many_to_one/
+
+:class:`~django.db.models.ForeignKey` fields also accept a number of extra
+arguments which are explained in :ref:`the model field reference
+<foreign-key-arguments>`. These options help define how the relationship should
+work; all are optional.
+
+Many-to-many relationships
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To define a many-to-many relationship, use
+:class:`~django.db.models.ManyToManyField`. You use it just like any other
+:class:`~django.db.models.Field` type: by including it as a class attribute of
+your model.
+
+:class:`~django.db.models.ManyToManyField` requires a positional argument: the
+class to which the model is related.
+
+For example, if a ``Pizza`` has multiple ``Topping`` objects -- that is, a
+``Topping`` can be on multiple pizzas and each ``Pizza`` has multiple toppings
+-- here's how you'd represent that::
+
+ class Topping(models.Model):
+ # ...
+
+ class Pizza(models.Model):
+ # ...
+ toppings = models.ManyToManyField(Topping)
+
+As with :class:`~django.db.models.ForeignKey`, you can also create
+:ref:`recursive relationships <recursive-relationships>` (an object with a
+many-to-many relationship to itself) and :ref:`relationships to models not yet
+defined <lazy-relationships>`; see :ref:`the model field reference
+<ref-manytomany>` for details.
+
+It's suggested, but not required, that the name of a
+:class:`~django.db.models.ManyToManyField` (``toppings`` in the example above)
+be a plural describing the set of related model objects.
+
+It doesn't matter which model gets the
+:class:`~django.db.models.ManyToManyField`, but you only need it in one of the
+models -- not in both.
+
+Generally, :class:`~django.db.models.ManyToManyField` instances should go in the
+object that's going to be edited in the admin interface, if you're using
+Django's admin. In the above example, ``toppings`` is in ``Pizza`` (rather than
+``Topping`` having a ``pizzas`` :class:`~django.db.models.ManyToManyField` )
+because it's more natural to think about a pizza having toppings than a
+topping being on multiple pizzas. The way it's set up above, the ``Pizza`` admin
+form would let users select the toppings.
+
+.. seealso::
+
+ See the `Many-to-many relationship model example`_ for a full example.
+
+.. _Many-to-many relationship model example: http://www.djangoproject.com/documentation/models/many_to_many/
+
+:class:`~django.db.models.ManyToManyField` fields also accept a number of extra
+arguments which are explained in :ref:`the model field reference
+<manytomany-arguments>`. These options help define how the relationship should
+work; all are optional.
+
+.. _intermediary-manytomany:
+
+Extra fields on many-to-many relationships
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.0
+
+When you're only dealing with simple many-to-many relationships such as
+mixing and matching pizzas and toppings, a standard :class:`~django.db.models.ManyToManyField` is all you need. However, sometimes
+you may need to associate data with the relationship between two models.
+
+For example, consider the case of an application tracking the musical groups
+which musicians belong to. There is a many-to-many relationship between a person
+and the groups of which they are a member, so you could use a
+:class:`~django.db.models.ManyToManyField` to represent this relationship.
+However, there is a lot of detail about the membership that you might want to
+collect, such as the date at which the person joined the group.
+
+For these situations, Django allows you to specify the model that will be used
+to govern the many-to-many relationship. You can then put extra fields on the
+intermediate model. The intermediate model is associated with the
+:class:`~django.db.models.ManyToManyField` using the
+:attr:`through <ManyToManyField.through>` argument to point to the model
+that will act as an intermediary. For our musician example, the code would look
+something like this::
+
+ class Person(models.Model):
+ name = models.CharField(max_length=128)
+
+ def __unicode__(self):
+ return self.name
+
+ class Group(models.Model):
+ name = models.CharField(max_length=128)
+ members = models.ManyToManyField(Person, through='Membership')
+
+ def __unicode__(self):
+ return self.name
+
+ class Membership(models.Model):
+ person = models.ForeignKey(Person)
+ group = models.ForeignKey(Group)
+ date_joined = models.DateField()
+ invite_reason = models.CharField(max_length=64)
+
+When you set up the intermediary model, you explicitly specify foreign
+keys to the models that are involved in the ManyToMany relation. This
+explicit declaration defines how the two models are related.
+
+There are a few restrictions on the intermediate model:
+
+ * Your intermediate model must contain one - and *only* one - foreign key
+ to the target model (this would be ``Person`` in our example). If you
+ have more than one foreign key, a validation error will be raised.
+
+ * Your intermediate model must contain one - and *only* one - foreign key
+ to the source model (this would be ``Group`` in our example). If you
+ have more than one foreign key, a validation error will be raised.
+
+ * The only exception to this is a model which has a many-to-many
+ relationship to itself, through an intermediary model. In this
+ case, two foreign keys to the same model are permitted, but they
+ will be treated as the two (different) sides of the many-to-many
+ relation.
+
+ * When defining a many-to-many relationship from a model to
+ itself, using an intermediary model, you *must* use
+ :attr:`symmetrical=False <ManyToManyField.symmetrical>` (see
+ :ref:`the model field reference <manytomany-arguments>`).
+
+Now that you have set up your :class:`~django.db.models.ManyToManyField` to use
+your intermediary model (``Membership``, in this case), you're ready to start
+creating some many-to-many relationships. You do this by creating instances of
+the intermediate model::
+
+ >>> ringo = Person.objects.create(name="Ringo Starr")
+ >>> paul = Person.objects.create(name="Paul McCartney")
+ >>> beatles = Group.objects.create(name="The Beatles")
+ >>> m1 = Membership(person=ringo, group=beatles,
+ ... date_joined=date(1962, 8, 16),
+ ... invite_reason= "Needed a new drummer.")
+ >>> m1.save()
+ >>> beatles.members.all()
+ [<Person: Ringo Starr>]
+ >>> ringo.group_set.all()
+ [<Group: The Beatles>]
+ >>> m2 = Membership.objects.create(person=paul, group=beatles,
+ ... date_joined=date(1960, 8, 1),
+ ... invite_reason= "Wanted to form a band.")
+ >>> beatles.members.all()
+ [<Person: Ringo Starr>, <Person: Paul McCartney>]
+
+Unlike normal many-to-many fields, you *can't* use ``add``, ``create``,
+or assignment (i.e., ``beatles.members = [...]``) to create relationships::
+
+ # THIS WILL NOT WORK
+ >>> beatles.members.add(john)
+ # NEITHER WILL THIS
+ >>> beatles.members.create(name="George Harrison")
+ # AND NEITHER WILL THIS
+ >>> beatles.members = [john, paul, ringo, george]
+
+Why? You can't just create a relationship between a ``Person`` and a ``Group``
+- you need to specify all the detail for the relationship required by the
+``Membership`` model. The simple ``add``, ``create`` and assignment calls
+don't provide a way to specify this extra detail. As a result, they are
+disabled for many-to-many relationships that use an intermediate model.
+The only way to create this type of relationship is to create instances of the
+intermediate model.
+
+The :meth:`~django.db.models.fields.related.RelatedManager.remove` method is
+disabled for similar reasons. However, the
+:meth:`~django.db.models.fields.related.RelatedManager.clear` method can be
+used to remove all many-to-many relationships for an instance::
+
+ # Beatles have broken up
+ >>> beatles.members.clear()
+
+Once you have established the many-to-many relationships by creating instances
+of your intermediate model, you can issue queries. Just as with normal
+many-to-many relationships, you can query using the attributes of the
+many-to-many-related model::
+
+ # Find all the groups with a member whose name starts with 'Paul'
+ >>> Group.objects.filter(members__name__startswith='Paul')
+ [<Group: The Beatles>]
+
+As you are using an intermediate model, you can also query on its attributes::
+
+ # Find all the members of the Beatles that joined after 1 Jan 1961
+ >>> Person.objects.filter(
+ ... group__name='The Beatles',
+ ... membership__date_joined__gt=date(1961,1,1))
+ [<Person: Ringo Starr]
+
+
+One-to-one relationships
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+To define a one-to-one relationship, use
+:class:`~django.db.models.OneToOneField`. You use it just like any other
+``Field`` type: by including it as a class attribute of your model.
+
+This is most useful on the primary key of an object when that object "extends"
+another object in some way.
+
+:class:`~django.db.models.OneToOneField` requires a positional argument: the
+class to which the model is related.
+
+For example, if you were building a database of "places", you would
+build pretty standard stuff such as address, phone number, etc. in the
+database. Then, if you wanted to build a database of restaurants on
+top of the places, instead of repeating yourself and replicating those
+fields in the ``Restaurant`` model, you could make ``Restaurant`` have
+a :class:`~django.db.models.OneToOneField` to ``Place`` (because a
+restaurant "is a" place; in fact, to handle this you'd typically use
+:ref:`inheritance <model-inheritance>`, which involves an implicit
+one-to-one relation).
+
+As with :class:`~django.db.models.ForeignKey`, a
+:ref:`recursive relationship <recursive-relationships>`
+can be defined and
+:ref:`references to as-yet undefined models <lazy-relationships>`
+can be made; see :ref:`the model field reference <ref-onetoone>` for details.
+
+.. seealso::
+
+ See the `One-to-one relationship model example`_ for a full example.
+
+.. _One-to-one relationship model example: http://www.djangoproject.com/documentation/models/one_to_one/
+
+.. versionadded:: 1.0
+
+:class:`~django.db.models.OneToOneField` fields also accept one optional argument
+described in the :ref:`model field reference <ref-onetoone>`.
+
+:class:`~django.db.models.OneToOneField` classes used to automatically become
+the primary key on a model. This is no longer true (although you can manually
+pass in the :attr:`~django.db.models.Field.primary_key` argument if you like).
+Thus, it's now possible to have multiple fields of type
+:class:`~django.db.models.OneToOneField` on a single model.
+
+Models across files
+-------------------
+
+It's perfectly OK to relate a model to one from another app. To do this,
+import the related model at the top of the model that holds your model. Then,
+just refer to the other model class wherever needed. For example::
+
+ from geography.models import ZipCode
+
+ class Restaurant(models.Model):
+ # ...
+ zip_code = models.ForeignKey(ZipCode)
+
+Field name restrictions
+-----------------------
+
+Django places only two restrictions on model field names:
+
+ 1. A field name cannot be a Python reserved word, because that would result
+ in a Python syntax error. For example::
+
+ class Example(models.Model):
+ pass = models.IntegerField() # 'pass' is a reserved word!
+
+ 2. A field name cannot contain more than one underscore in a row, due to
+ the way Django's query lookup syntax works. For example::
+
+ class Example(models.Model):
+ foo__bar = models.IntegerField() # 'foo__bar' has two underscores!
+
+These limitations can be worked around, though, because your field name doesn't
+necessarily have to match your database column name. See the
+:attr:`~Field.db_column` option.
+
+SQL reserved words, such as ``join``, ``where`` or ``select``, *are* allowed as
+model field names, because Django escapes all database table names and column
+names in every underlying SQL query. It uses the quoting syntax of your
+particular database engine.
+
+Custom field types
+------------------
+
+.. versionadded:: 1.0
+
+If one of the existing model fields cannot be used to fit your purposes, or if
+you wish to take advantage of some less common database column types, you can
+create your own field class. Full coverage of creating your own fields is
+provided in :doc:`/howto/custom-model-fields`.
+
+.. _meta-options:
+
+Meta options
+============
+
+Give your model metadata by using an inner ``class Meta``, like so::
+
+ class Ox(models.Model):
+ horn_length = models.IntegerField()
+
+ class Meta:
+ ordering = ["horn_length"]
+ verbose_name_plural = "oxen"
+
+Model metadata is "anything that's not a field", such as ordering options
+(:attr:`~Options.ordering`), database table name (:attr:`~Options.db_table`), or
+human-readable singular and plural names (:attr:`~Options.verbose_name` and
+:attr:`~Options.verbose_name_plural`). None are required, and adding ``class
+Meta`` to a model is completely optional.
+
+A complete list of all possible ``Meta`` options can be found in the :doc:`model
+option reference </ref/models/options>`.
+
+.. _model-methods:
+
+Model methods
+=============
+
+Define custom methods on a model to add custom "row-level" functionality to your
+objects. Whereas :class:`~django.db.models.Manager` methods are intended to do
+"table-wide" things, model methods should act on a particular model instance.
+
+This is a valuable technique for keeping business logic in one place -- the
+model.
+
+For example, this model has a few custom methods::
+
+ from django.contrib.localflavor.us.models import USStateField
+
+ class Person(models.Model):
+ first_name = models.CharField(max_length=50)
+ last_name = models.CharField(max_length=50)
+ birth_date = models.DateField()
+ address = models.CharField(max_length=100)
+ city = models.CharField(max_length=50)
+ state = USStateField() # Yes, this is America-centric...
+
+ def baby_boomer_status(self):
+ "Returns the person's baby-boomer status."
+ import datetime
+ if datetime.date(1945, 8, 1) <= self.birth_date <= datetime.date(1964, 12, 31):
+ return "Baby boomer"
+ if self.birth_date < datetime.date(1945, 8, 1):
+ return "Pre-boomer"
+ return "Post-boomer"
+
+ def is_midwestern(self):
+ "Returns True if this person is from the Midwest."
+ return self.state in ('IL', 'WI', 'MI', 'IN', 'OH', 'IA', 'MO')
+
+ def _get_full_name(self):
+ "Returns the person's full name."
+ return '%s %s' % (self.first_name, self.last_name)
+ full_name = property(_get_full_name)
+
+The last method in this example is a :term:`property`. `Read more about
+properties`_.
+
+.. _Read more about properties: http://www.python.org/download/releases/2.2/descrintro/#property
+
+The :doc:`model instance reference </ref/models/instances>` has a complete list
+of :ref:`methods automatically given to each model <model-instance-methods>`.
+You can override most of these -- see `overriding predefined model methods`_,
+below -- but there are a couple that you'll almost always want to define:
+
+ :meth:`~Model.__unicode__`
+ A Python "magic method" that returns a unicode "representation" of any
+ object. This is what Python and Django will use whenever a model
+ instance needs to be coerced and displayed as a plain string. Most
+ notably, this happens when you display an object in an interactive
+ console or in the admin.
+
+ You'll always want to define this method; the default isn't very helpful
+ at all.
+
+ :meth:`~Model.get_absolute_url`
+ This tells Django how to calculate the URL for an object. Django uses
+ this in its admin interface, and any time it needs to figure out a URL
+ for an object.
+
+ Any object that has a URL that uniquely identifies it should define this
+ method.
+
+.. _overriding-model-methods:
+
+Overriding predefined model methods
+-----------------------------------
+
+There's another set of :ref:`model methods <model-instance-methods>` that
+encapsulate a bunch of database behavior that you'll want to customize. In
+particular you'll often want to change the way :meth:`~Model.save` and
+:meth:`~Model.delete` work.
+
+You're free to override these methods (and any other model method) to alter
+behavior.
+
+A classic use-case for overriding the built-in methods is if you want something
+to happen whenever you save an object. For example (see
+:meth:`~Model.save` for documentation of the parameters it accepts)::
+
+ class Blog(models.Model):
+ name = models.CharField(max_length=100)
+ tagline = models.TextField()
+
+ def save(self, *args, **kwargs):
+ do_something()
+ super(Blog, self).save(*args, **kwargs) # Call the "real" save() method.
+ do_something_else()
+
+You can also prevent saving::
+
+ class Blog(models.Model):
+ name = models.CharField(max_length=100)
+ tagline = models.TextField()
+
+ def save(self, *args, **kwargs):
+ if self.name == "Yoko Ono's blog":
+ return # Yoko shall never have her own blog!
+ else:
+ super(Blog, self).save(*args, **kwargs) # Call the "real" save() method.
+
+It's important to remember to call the superclass method -- that's
+that ``super(Blog, self).save(*args, **kwargs)`` business -- to ensure
+that the object still gets saved into the database. If you forget to
+call the superclass method, the default behavior won't happen and the
+database won't get touched.
+
+It's also important that you pass through the arguments that can be
+passed to the model method -- that's what the ``*args, **kwargs`` bit
+does. Django will, from time to time, extend the capabilities of
+built-in model methods, adding new arguments. If you use ``*args,
+**kwargs`` in your method definitions, you are guaranteed that your
+code will automatically support those arguments when they are added.
+
+Executing custom SQL
+--------------------
+
+Another common pattern is writing custom SQL statements in model methods and
+module-level methods. For more details on using raw SQL, see the documentation
+on :doc:`using raw SQL</topics/db/sql>`.
+
+.. _model-inheritance:
+
+Model inheritance
+=================
+
+.. versionadded:: 1.0
+
+Model inheritance in Django works almost identically to the way normal
+class inheritance works in Python. The only decision you have to make
+is whether you want the parent models to be models in their own right
+(with their own database tables), or if the parents are just holders
+of common information that will only be visible through the child
+models.
+
+There are three styles of inheritance that are possible in Django.
+
+ 1. Often, you will just want to use the parent class to hold information that
+ you don't want to have to type out for each child model. This class isn't
+ going to ever be used in isolation, so :ref:`abstract-base-classes` are
+ what you're after.
+ 2. If you're subclassing an existing model (perhaps something from another
+ application entirely) and want each model to have its own database table,
+ :ref:`multi-table-inheritance` is the way to go.
+ 3. Finally, if you only want to modify the Python-level behaviour of a model,
+ without changing the models fields in any way, you can use
+ :ref:`proxy-models`.
+
+.. _abstract-base-classes:
+
+Abstract base classes
+---------------------
+
+Abstract base classes are useful when you want to put some common
+information into a number of other models. You write your base class
+and put ``abstract=True`` in the :ref:`Meta <meta-options>`
+class. This model will then not be used to create any database
+table. Instead, when it is used as a base class for other models, its
+fields will be added to those of the child class. It is an error to
+have fields in the abstract base class with the same name as those in
+the child (and Django will raise an exception).
+
+An example::
+
+ class CommonInfo(models.Model):
+ name = models.CharField(max_length=100)
+ age = models.PositiveIntegerField()
+
+ class Meta:
+ abstract = True
+
+ class Student(CommonInfo):
+ home_group = models.CharField(max_length=5)
+
+The ``Student`` model will have three fields: ``name``, ``age`` and
+``home_group``. The ``CommonInfo`` model cannot be used as a normal Django
+model, since it is an abstract base class. It does not generate a database
+table or have a manager, and cannot be instantiated or saved directly.
+
+For many uses, this type of model inheritance will be exactly what you want.
+It provides a way to factor out common information at the Python level, whilst
+still only creating one database table per child model at the database level.
+
+``Meta`` inheritance
+~~~~~~~~~~~~~~~~~~~~
+
+When an abstract base class is created, Django makes any :ref:`Meta <meta-options>`
+inner class you declared in the base class available as an
+attribute. If a child class does not declare its own :ref:`Meta <meta-options>`
+class, it will inherit the parent's :ref:`Meta <meta-options>`. If the child wants to
+extend the parent's :ref:`Meta <meta-options>` class, it can subclass it. For example::
+
+ class CommonInfo(models.Model):
+ ...
+ class Meta:
+ abstract = True
+ ordering = ['name']
+
+ class Student(CommonInfo):
+ ...
+ class Meta(CommonInfo.Meta):
+ db_table = 'student_info'
+
+Django does make one adjustment to the :ref:`Meta <meta-options>` class of an abstract base
+class: before installing the :ref:`Meta <meta-options>` attribute, it sets ``abstract=False``.
+This means that children of abstract base classes don't automatically become
+abstract classes themselves. Of course, you can make an abstract base class
+that inherits from another abstract base class. You just need to remember to
+explicitly set ``abstract=True`` each time.
+
+Some attributes won't make sense to include in the :ref:`Meta <meta-options>` class of an
+abstract base class. For example, including ``db_table`` would mean that all
+the child classes (the ones that don't specify their own :ref:`Meta <meta-options>`) would use
+the same database table, which is almost certainly not what you want.
+
+.. _abstract-related-name:
+
+Be careful with ``related_name``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you are using the :attr:`~django.db.models.ForeignKey.related_name` attribute on a ``ForeignKey`` or
+``ManyToManyField``, you must always specify a *unique* reverse name for the
+field. This would normally cause a problem in abstract base classes, since the
+fields on this class are included into each of the child classes, with exactly
+the same values for the attributes (including :attr:`~django.db.models.ForeignKey.related_name`) each time.
+
+.. versionchanged:: 1.2
+
+To work around this problem, when you are using :attr:`~django.db.models.ForeignKey.related_name` in an
+abstract base class (only), part of the name should contain
+``'%(app_label)s'`` and ``'%(class)s'``.
+
+- ``'%(class)s'`` is replaced by the lower-cased name of the child class
+ that the field is used in.
+- ``'%(app_label)s'`` is replaced by the lower-cased name of the app the child
+ class is contained within. Each installed application name must be unique
+ and the model class names within each app must also be unique, therefore the
+ resulting name will end up being different.
+
+For example, given an app ``common/models.py``::
+
+ class Base(models.Model):
+ m2m = models.ManyToManyField(OtherModel, related_name="%(app_label)s_%(class)s_related")
+
+ class Meta:
+ abstract = True
+
+ class ChildA(Base):
+ pass
+
+ class ChildB(Base):
+ pass
+
+Along with another app ``rare/models.py``::
+
+ from common.models import Base
+
+ class ChildB(Base):
+ pass
+
+The reverse name of the ``commmon.ChildA.m2m`` field will be
+``common_childa_related``, whilst the reverse name of the
+``common.ChildB.m2m`` field will be ``common_childb_related``, and finally the
+reverse name of the ``rare.ChildB.m2m`` field will be ``rare_childb_related``.
+It is up to you how you use the ``'%(class)s'`` and ``'%(app_label)s`` portion
+to construct your related name, but if you forget to use it, Django will raise
+errors when you validate your models (or run :djadmin:`syncdb`).
+
+If you don't specify a :attr:`~django.db.models.ForeignKey.related_name`
+attribute for a field in an abstract base class, the default reverse name will
+be the name of the child class followed by ``'_set'``, just as it normally
+would be if you'd declared the field directly on the child class. For example,
+in the above code, if the :attr:`~django.db.models.ForeignKey.related_name`
+attribute was omitted, the reverse name for the ``m2m`` field would be
+``childa_set`` in the ``ChildA`` case and ``childb_set`` for the ``ChildB``
+field.
+
+.. _multi-table-inheritance:
+
+Multi-table inheritance
+-----------------------
+
+The second type of model inheritance supported by Django is when each model in
+the hierarchy is a model all by itself. Each model corresponds to its own
+database table and can be queried and created individually. The inheritance
+relationship introduces links between the child model and each of its parents
+(via an automatically-created :class:`~django.db.models.fields.OneToOneField`).
+For example::
+
+ class Place(models.Model):
+ name = models.CharField(max_length=50)
+ address = models.CharField(max_length=80)
+
+ class Restaurant(Place):
+ serves_hot_dogs = models.BooleanField()
+ serves_pizza = models.BooleanField()
+
+All of the fields of ``Place`` will also be available in ``Restaurant``,
+although the data will reside in a different database table. So these are both
+possible::
+
+ >>> Place.objects.filter(name="Bob's Cafe")
+ >>> Restaurant.objects.filter(name="Bob's Cafe")
+
+If you have a ``Place`` that is also a ``Restaurant``, you can get from the
+``Place`` object to the ``Restaurant`` object by using the lower-case version
+of the model name::
+
+ >>> p = Place.objects.get(id=12)
+ # If p is a Restaurant object, this will give the child class:
+ >>> p.restaurant
+ <Restaurant: ...>
+
+However, if ``p`` in the above example was *not* a ``Restaurant`` (it had been
+created directly as a ``Place`` object or was the parent of some other class),
+referring to ``p.restaurant`` would raise a Restaurant.DoesNotExist exception.
+
+``Meta`` and multi-table inheritance
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In the multi-table inheritance situation, it doesn't make sense for a child
+class to inherit from its parent's :ref:`Meta <meta-options>` class. All the :ref:`Meta <meta-options>` options
+have already been applied to the parent class and applying them again would
+normally only lead to contradictory behavior (this is in contrast with the
+abstract base class case, where the base class doesn't exist in its own
+right).
+
+So a child model does not have access to its parent's :ref:`Meta
+<meta-options>` class. However, there are a few limited cases where the child
+inherits behavior from the parent: if the child does not specify an
+:attr:`~django.db.models.Options.ordering` attribute or a
+:attr:`~django.db.models.Options.get_latest_by` attribute, it will inherit
+these from its parent.
+
+If the parent has an ordering and you don't want the child to have any natural
+ordering, you can explicitly disable it::
+
+ class ChildModel(ParentModel):
+ ...
+ class Meta:
+ # Remove parent's ordering effect
+ ordering = []
+
+Inheritance and reverse relations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Because multi-table inheritance uses an implicit
+:class:`~django.db.models.OneToOneField` to link the child and
+the parent, it's possible to move from the parent down to the child,
+as in the above example. However, this uses up the name that is the
+default :attr:`~django.db.models.ForeignKey.related_name` value for
+:class:`~django.db.models.ForeignKey` and
+:class:`~django.db.models.ManyToManyField` relations. If you
+are putting those types of relations on a subclass of another model,
+you **must** specify the
+:attr:`~django.db.models.ForeignKey.related_name` attribute on each
+such field. If you forget, Django will raise an error when you run
+:djadmin:`validate` or :djadmin:`syncdb`.
+
+For example, using the above ``Place`` class again, let's create another
+subclass with a :class:`~django.db.models.ManyToManyField`::
+
+ class Supplier(Place):
+ # Must specify related_name on all relations.
+ customers = models.ManyToManyField(Restaurant, related_name='provider')
+
+
+Specifying the parent link field
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As mentioned, Django will automatically create a
+:class:`~django.db.models.OneToOneField` linking your child
+class back any non-abstract parent models. If you want to control the
+name of the attribute linking back to the parent, you can create your
+own :class:`~django.db.models.OneToOneField` and set
+:attr:`parent_link=True <django.db.models.OneToOneField.parent_link>`
+to indicate that your field is the link back to the parent class.
+
+.. _proxy-models:
+
+Proxy models
+------------
+
+.. versionadded:: 1.1
+
+When using :ref:`multi-table inheritance <multi-table-inheritance>`, a new
+database table is created for each subclass of a model. This is usually the
+desired behavior, since the subclass needs a place to store any additional
+data fields that are not present on the base class. Sometimes, however, you
+only want to change the Python behavior of a model -- perhaps to change the
+default manager, or add a new method.
+
+This is what proxy model inheritance is for: creating a *proxy* for the
+original model. You can create, delete and update instances of the proxy model
+and all the data will be saved as if you were using the original (non-proxied)
+model. The difference is that you can change things like the default model
+ordering or the default manager in the proxy, without having to alter the
+original.
+
+Proxy models are declared like normal models. You tell Django that it's a
+proxy model by setting the :attr:`~django.db.models.Options.proxy` attribute of
+the ``Meta`` class to ``True``.
+
+For example, suppose you want to add a method to the standard
+:class:`~django.contrib.auth.models.User` model that will be used in your
+templates. You can do it like this::
+
+ from django.contrib.auth.models import User
+
+ class MyUser(User):
+ class Meta:
+ proxy = True
+
+ def do_something(self):
+ ...
+
+The ``MyUser`` class operates on the same database table as its parent
+:class:`~django.contrib.auth.models.User` class. In particular, any new
+instances of :class:`~django.contrib.auth.models.User` will also be accessible
+through ``MyUser``, and vice-versa::
+
+ >>> u = User.objects.create(username="foobar")
+ >>> MyUser.objects.get(username="foobar")
+ <MyUser: foobar>
+
+You could also use a proxy model to define a different default ordering on a
+model. The standard :class:`~django.contrib.auth.models.User` model has no
+ordering defined on it (intentionally; sorting is expensive and we don't want
+to do it all the time when we fetch users). You might want to regularly order
+by the ``username`` attribute when you use the proxy. This is easy::
+
+ class OrderedUser(User):
+ class Meta:
+ ordering = ["username"]
+ proxy = True
+
+Now normal :class:`~django.contrib.auth.models.User` queries will be unordered
+and ``OrderedUser`` queries will be ordered by ``username``.
+
+QuerySets still return the model that was requested
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+There is no way to have Django return, say, a ``MyUser`` object whenever you
+query for :class:`~django.contrib.auth.models.User` objects. A queryset for
+``User`` objects will return those types of objects. The whole point of proxy
+objects is that code relying on the original ``User`` will use those and your
+own code can use the extensions you included (that no other code is relying on
+anyway). It is not a way to replace the ``User`` (or any other) model
+everywhere with something of your own creation.
+
+Base class restrictions
+~~~~~~~~~~~~~~~~~~~~~~~
+
+A proxy model must inherit from exactly one non-abstract model class. You
+can't inherit from multiple non-abstract models as the proxy model doesn't
+provide any connection between the rows in the different database tables. A
+proxy model can inherit from any number of abstract model classes, providing
+they do *not* define any model fields.
+
+Proxy models inherit any ``Meta`` options that they don't define from their
+non-abstract model parent (the model they are proxying for).
+
+Proxy model managers
+~~~~~~~~~~~~~~~~~~~~
+
+If you don't specify any model managers on a proxy model, it inherits the
+managers from its model parents. If you define a manager on the proxy model,
+it will become the default, although any managers defined on the parent
+classes will still be available.
+
+Continuing our example from above, you could change the default manager used
+when you query the ``User`` model like this::
+
+ class NewManager(models.Manager):
+ ...
+
+ class MyUser(User):
+ objects = NewManager()
+
+ class Meta:
+ proxy = True
+
+If you wanted to add a new manager to the Proxy, without replacing the
+existing default, you can use the techniques described in the :ref:`custom
+manager <custom-managers-and-inheritance>` documentation: create a base class
+containing the new managers and inherit that after the primary base class::
+
+ # Create an abstract class for the new manager.
+ class ExtraManagers(models.Model):
+ secondary = NewManager()
+
+ class Meta:
+ abstract = True
+
+ class MyUser(User, ExtraManagers):
+ class Meta:
+ proxy = True
+
+You probably won't need to do this very often, but, when you do, it's
+possible.
+
+.. _proxy-vs-unmanaged-models:
+
+Differences between proxy inheritance and unmanaged models
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Proxy model inheritance might look fairly similar to creating an unmanaged
+model, using the :attr:`~django.db.models.Options.managed` attribute on a
+model's ``Meta`` class. The two alternatives are not quite the same and it's
+worth considering which one you should use.
+
+One difference is that you can (and, in fact, must unless you want an empty
+model) specify model fields on models with ``Meta.managed=False``. You could,
+with careful setting of :attr:`Meta.db_table
+<django.db.models.Options.db_table>` create an unmanaged model that shadowed
+an existing model and add Python methods to it. However, that would be very
+repetitive and fragile as you need to keep both copies synchronized if you
+make any changes.
+
+The other difference that is more important for proxy models, is how model
+managers are handled. Proxy models are intended to behave exactly like the
+model they are proxying for. So they inherit the parent model's managers,
+including the default manager. In the normal multi-table model inheritance
+case, children do not inherit managers from their parents as the custom
+managers aren't always appropriate when extra fields are involved. The
+:ref:`manager documentation <custom-managers-and-inheritance>` has more
+details about this latter case.
+
+When these two features were implemented, attempts were made to squash them
+into a single option. It turned out that interactions with inheritance, in
+general, and managers, in particular, made the API very complicated and
+potentially difficult to understand and use. It turned out that two options
+were needed in any case, so the current separation arose.
+
+So, the general rules are:
+
+ 1. If you are mirroring an existing model or database table and don't want
+ all the original database table columns, use ``Meta.managed=False``.
+ That option is normally useful for modeling database views and tables
+ not under the control of Django.
+ 2. If you are wanting to change the Python-only behavior of a model, but
+ keep all the same fields as in the original, use ``Meta.proxy=True``.
+ This sets things up so that the proxy model is an exact copy of the
+ storage structure of the original model when data is saved.
+
+Multiple inheritance
+--------------------
+
+Just as with Python's subclassing, it's possible for a Django model to inherit
+from multiple parent models. Keep in mind that normal Python name resolution
+rules apply. The first base class that a particular name (e.g. :ref:`Meta
+<meta-options>`) appears in will be the one that is used; for example, this
+means that if multiple parents contain a :ref:`Meta <meta-options>` class,
+only the first one is going to be used, and all others will be ignored.
+
+Generally, you won't need to inherit from multiple parents. The main use-case
+where this is useful is for "mix-in" classes: adding a particular extra
+field or method to every class that inherits the mix-in. Try to keep your
+inheritance hierarchies as simple and straightforward as possible so that you
+won't have to struggle to work out where a particular piece of information is
+coming from.
+
+Field name "hiding" is not permitted
+-------------------------------------
+
+In normal Python class inheritance, it is permissible for a child class to
+override any attribute from the parent class. In Django, this is not permitted
+for attributes that are :class:`~django.db.models.fields.Field` instances (at
+least, not at the moment). If a base class has a field called ``author``, you
+cannot create another model field called ``author`` in any class that inherits
+from that base class.
+
+Overriding fields in a parent model leads to difficulties in areas such as
+initialising new instances (specifying which field is being initialized in
+``Model.__init__``) and serialization. These are features which normal Python
+class inheritance doesn't have to deal with in quite the same way, so the
+difference between Django model inheritance and Python class inheritance isn't
+arbitrary.
+
+This restriction only applies to attributes which are
+:class:`~django.db.models.fields.Field` instances. Normal Python attributes
+can be overridden if you wish. It also only applies to the name of the
+attribute as Python sees it: if you are manually specifying the database
+column name, you can have the same column name appearing in both a child and
+an ancestor model for multi-table inheritance (they are columns in two
+different database tables).
+
+Django will raise a :exc:`~django.core.exceptions.FieldError` if you override
+any model field in any ancestor model.
diff --git a/parts/django/docs/topics/db/multi-db.txt b/parts/django/docs/topics/db/multi-db.txt
new file mode 100644
index 0000000..1a939b0
--- /dev/null
+++ b/parts/django/docs/topics/db/multi-db.txt
@@ -0,0 +1,574 @@
+==================
+Multiple databases
+==================
+
+.. versionadded:: 1.2
+
+This topic guide describes Django's support for interacting with
+multiple databases. Most of the rest of Django's documentation assumes
+you are interacting with a single database. If you want to interact
+with multiple databases, you'll need to take some additional steps.
+
+Defining your databases
+=======================
+
+The first step to using more than one database with Django is to tell
+Django about the database servers you'll be using. This is done using
+the :setting:`DATABASES` setting. This setting maps database aliases,
+which are a way to refer to a specific database throughout Django, to
+a dictionary of settings for that specific connection. The settings in
+the inner dictionaries are described fully in the :setting:`DATABASES`
+documentation.
+
+Databases can have any alias you choose. However, the alias
+``default`` has special significance. Django uses the database with
+the alias of ``default`` when no other database has been selected. If
+you don't have a ``default`` database, you need to be careful to
+always specify the database that you want to use.
+
+The following is an example ``settings.py`` snippet defining two
+databases -- a default PostgreSQL database and a MySQL database called
+``users``:
+
+.. code-block:: python
+
+ DATABASES = {
+ 'default': {
+ 'NAME': 'app_data',
+ 'ENGINE': 'django.db.backends.postgresql_psycopg2',
+ 'USER': 'postgres_user',
+ 'PASSWORD': 's3krit'
+ },
+ 'users': {
+ 'NAME': 'user_data',
+ 'ENGINE': 'django.db.backends.mysql',
+ 'USER': 'mysql_user',
+ 'PASSWORD': 'priv4te'
+ }
+ }
+
+If you attempt to access a database that you haven't defined in your
+:setting:`DATABASES` setting, Django will raise a
+``django.db.utils.ConnectionDoesNotExist`` exception.
+
+Synchronizing your databases
+============================
+
+The :djadmin:`syncdb` management command operates on one database at a
+time. By default, it operates on the ``default`` database, but by
+providing a :djadminopt:`--database` argument, you can tell syncdb to
+synchronize a different database. So, to synchronize all models onto
+all databases in our example, you would need to call::
+
+ $ ./manage.py syncdb
+ $ ./manage.py syncdb --database=users
+
+If you don't want every application to be synchronized onto a
+particular database, you can define a :ref:`database
+router<topics-db-multi-db-routing>` that implements a policy
+constraining the availability of particular models.
+
+Alternatively, if you want fine-grained control of synchronization,
+you can pipe all or part of the output of :djadmin:`sqlall` for a
+particular application directly into your database prompt, like this::
+
+ $ ./manage.py sqlall sales | ./manage.py dbshell
+
+Using other management commands
+-------------------------------
+
+The other ``django-admin.py`` commands that interact with the database
+operate in the same way as :djadmin:`syncdb` -- they only ever operate
+on one database at a time, using :djadminopt:`--database` to control
+the database used.
+
+.. _topics-db-multi-db-routing:
+
+Automatic database routing
+==========================
+
+The easiest way to use multiple databases is to set up a database
+routing scheme. The default routing scheme ensures that objects remain
+'sticky' to their original database (i.e., an object retrieved from
+the ``foo`` database will be saved on the same database). The default
+routing scheme ensures that if a database isn't specified, all queries
+fall back to the ``default`` database.
+
+You don't have to do anything to activate the default routing scheme
+-- it is provided 'out of the box' on every Django project. However,
+if you want to implement more interesting database allocation
+behaviors, you can define and install your own database routers.
+
+Database routers
+----------------
+
+A database Router is a class that provides up to four methods:
+
+.. method:: db_for_read(model, **hints)
+
+ Suggest the database that should be used for read operations for
+ objects of type ``model``.
+
+ If a database operation is able to provide any additional
+ information that might assist in selecting a database, it will be
+ provided in the ``hints`` dictionary. Details on valid hints are
+ provided :ref:`below <topics-db-multi-db-hints>`.
+
+ Returns None if there is no suggestion.
+
+.. method:: db_for_write(model, **hints)
+
+ Suggest the database that should be used for writes of objects of
+ type Model.
+
+ If a database operation is able to provide any additional
+ information that might assist in selecting a database, it will be
+ provided in the ``hints`` dictionary. Details on valid hints are
+ provided :ref:`below <topics-db-multi-db-hints>`.
+
+ Returns None if there is no suggestion.
+
+.. method:: allow_relation(obj1, obj2, **hints)
+
+ Return True if a relation between obj1 and obj2 should be
+ allowed, False if the relation should be prevented, or None if
+ the router has no opinion. This is purely a validation operation,
+ used by foreign key and many to many operations to determine if a
+ relation should be allowed between two objects.
+
+.. method:: allow_syncdb(db, model)
+
+ Determine if the ``model`` should be synchronized onto the
+ database with alias ``db``. Return True if the model should be
+ synchronized, False if it should not be synchronized, or None if
+ the router has no opinion. This method can be used to determine
+ the availability of a model on a given database.
+
+A router doesn't have to provide *all* these methods - it omit one or
+more of them. If one of the methods is omitted, Django will skip that
+router when performing the relevant check.
+
+.. _topics-db-multi-db-hints:
+
+Hints
+~~~~~
+
+The hints received by the database router can be used to decide which
+database should receive a given request.
+
+At present, the only hint that will be provided is ``instance``, an
+object instance that is related to the read or write operation that is
+underway. This might be the instance that is being saved, or it might
+be an instance that is being added in a many-to-many relation. In some
+cases, no instance hint will be provided at all. The router checks for
+the existence of an instance hint, and determine if that hint should be
+used to alter routing behavior.
+
+Using routers
+-------------
+
+Database routers are installed using the :setting:`DATABASE_ROUTERS`
+setting. This setting defines a list of class names, each specifying a
+router that should be used by the master router
+(``django.db.router``).
+
+The master router is used by Django's database operations to allocate
+database usage. Whenever a query needs to know which database to use,
+it calls the master router, providing a model and a hint (if
+available). Django then tries each router in turn until a database
+suggestion can be found. If no suggestion can be found, it tries the
+current ``_state.db`` of the hint instance. If a hint instance wasn't
+provided, or the instance doesn't currently have database state, the
+master router will allocate the ``default`` database.
+
+An example
+----------
+
+.. admonition:: Example purposes only!
+
+ This example is intended as a demonstration of how the router
+ infrastructure can be used to alter database usage. It
+ intentionally ignores some complex issues in order to
+ demonstrate how routers are used.
+
+ This example won't work if any of the models in ``myapp`` contain
+ relationships to models outside of the ``other`` database.
+ :ref:`Cross-database relationships <no_cross_database_relations>`
+ introduce referential integrity problems that Django can't
+ currently handle.
+
+ The master/slave configuration described is also flawed -- it
+ doesn't provide any solution for handling replication lag (i.e.,
+ query inconsistencies introduced because of the time taken for a
+ write to propagate to the slaves). It also doesn't consider the
+ interaction of transactions with the database utilization strategy.
+
+So - what does this mean in practice? Say you want ``myapp`` to
+exist on the ``other`` database, and you want all other models in a
+master/slave relationship between the databases ``master``, ``slave1`` and
+``slave2``. To implement this, you would need 2 routers::
+
+ class MyAppRouter(object):
+ """A router to control all database operations on models in
+ the myapp application"""
+
+ def db_for_read(self, model, **hints):
+ "Point all operations on myapp models to 'other'"
+ if model._meta.app_label == 'myapp':
+ return 'other'
+ return None
+
+ def db_for_write(self, model, **hints):
+ "Point all operations on myapp models to 'other'"
+ if model._meta.app_label == 'myapp':
+ return 'other'
+ return None
+
+ def allow_relation(self, obj1, obj2, **hints):
+ "Allow any relation if a model in myapp is involved"
+ if obj1._meta.app_label == 'myapp' or obj2._meta.app_label == 'myapp':
+ return True
+ return None
+
+ def allow_syncdb(self, db, model):
+ "Make sure the myapp app only appears on the 'other' db"
+ if db == 'other':
+ return model._meta.app_label == 'myapp'
+ elif model._meta.app_label == 'myapp':
+ return False
+ return None
+
+ class MasterSlaveRouter(object):
+ """A router that sets up a simple master/slave configuration"""
+
+ def db_for_read(self, model, **hints):
+ "Point all read operations to a random slave"
+ return random.choice(['slave1','slave2'])
+
+ def db_for_write(self, model, **hints):
+ "Point all write operations to the master"
+ return 'master'
+
+ def allow_relation(self, obj1, obj2, **hints):
+ "Allow any relation between two objects in the db pool"
+ db_list = ('master','slave1','slave2')
+ if obj1._state.db in db_list and obj2._state.db in db_list:
+ return True
+ return None
+
+ def allow_syncdb(self, db, model):
+ "Explicitly put all models on all databases."
+ return True
+
+Then, in your settings file, add the following (substituting ``path.to.`` with
+the actual python path to the module where you define the routers)::
+
+ DATABASE_ROUTERS = ['path.to.MyAppRouter', 'path.to.MasterSlaveRouter']
+
+The order in which routers are processed is significant. Routers will
+be queried in the order the are listed in the
+:setting:`DATABASE_ROUTERS` setting . In this example, the
+``MyAppRouter`` is processed before the ``MasterSlaveRouter``, and as a
+result, decisions concerning the models in ``myapp`` are processed
+before any other decision is made. If the :setting:`DATABASE_ROUTERS`
+setting listed the two routers in the other order,
+``MasterSlaveRouter.allow_syncdb()`` would be processed first. The
+catch-all nature of the MasterSlaveRouter implementation would mean
+that all models would be available on all databases.
+
+With this setup installed, lets run some Django code::
+
+ >>> # This retrieval will be performed on the 'credentials' database
+ >>> fred = User.objects.get(username='fred')
+ >>> fred.first_name = 'Frederick'
+
+ >>> # This save will also be directed to 'credentials'
+ >>> fred.save()
+
+ >>> # These retrieval will be randomly allocated to a slave database
+ >>> dna = Person.objects.get(name='Douglas Adams')
+
+ >>> # A new object has no database allocation when created
+ >>> mh = Book(title='Mostly Harmless')
+
+ >>> # This assignment will consult the router, and set mh onto
+ >>> # the same database as the author object
+ >>> mh.author = dna
+
+ >>> # This save will force the 'mh' instance onto the master database...
+ >>> mh.save()
+
+ >>> # ... but if we re-retrieve the object, it will come back on a slave
+ >>> mh = Book.objects.get(title='Mostly Harmless')
+
+
+Manually selecting a database
+=============================
+
+Django also provides an API that allows you to maintain complete control
+over database usage in your code. A manually specified database allocation
+will take priority over a database allocated by a router.
+
+Manually selecting a database for a ``QuerySet``
+------------------------------------------------
+
+You can select the database for a ``QuerySet`` at any point in the
+``QuerySet`` "chain." Just call ``using()`` on the ``QuerySet`` to get
+another ``QuerySet`` that uses the specified database.
+
+``using()`` takes a single argument: the alias of the database on
+which you want to run the query. For example::
+
+ >>> # This will run on the 'default' database.
+ >>> Author.objects.all()
+
+ >>> # So will this.
+ >>> Author.objects.using('default').all()
+
+ >>> # This will run on the 'other' database.
+ >>> Author.objects.using('other').all()
+
+Selecting a database for ``save()``
+-----------------------------------
+
+Use the ``using`` keyword to ``Model.save()`` to specify to which
+database the data should be saved.
+
+For example, to save an object to the ``legacy_users`` database, you'd
+use this::
+
+ >>> my_object.save(using='legacy_users')
+
+If you don't specify ``using``, the ``save()`` method will save into
+the default database allocated by the routers.
+
+Moving an object from one database to another
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you've saved an instance to one database, it might be tempting to
+use ``save(using=...)`` as a way to migrate the instance to a new
+database. However, if you don't take appropriate steps, this could
+have some unexpected consequences.
+
+Consider the following example::
+
+ >>> p = Person(name='Fred')
+ >>> p.save(using='first') # (statement 1)
+ >>> p.save(using='second') # (statement 2)
+
+In statement 1, a new ``Person`` object is saved to the ``first``
+database. At this time, ``p`` doesn't have a primary key, so Django
+issues a SQL ``INSERT`` statement. This creates a primary key, and
+Django assigns that primary key to ``p``.
+
+When the save occurs in statement 2, ``p`` already has a primary key
+value, and Django will attempt to use that primary key on the new
+database. If the primary key value isn't in use in the ``second``
+database, then you won't have any problems -- the object will be
+copied to the new database.
+
+However, if the primary key of ``p`` is already in use on the
+``second`` database, the existing object in the ``second`` database
+will be overridden when ``p`` is saved.
+
+You can avoid this in two ways. First, you can clear the primary key
+of the instance. If an object has no primary key, Django will treat it
+as a new object, avoiding any loss of data on the ``second``
+database::
+
+ >>> p = Person(name='Fred')
+ >>> p.save(using='first')
+ >>> p.pk = None # Clear the primary key.
+ >>> p.save(using='second') # Write a completely new object.
+
+The second option is to use the ``force_insert`` option to ``save()``
+to ensure that Django does a SQL ``INSERT``::
+
+ >>> p = Person(name='Fred')
+ >>> p.save(using='first')
+ >>> p.save(using='second', force_insert=True)
+
+This will ensure that the person named ``Fred`` will have the same
+primary key on both databases. If that primary key is already in use
+when you try to save onto the ``second`` database, an error will be
+raised.
+
+Selecting a database to delete from
+-----------------------------------
+
+By default, a call to delete an existing object will be executed on
+the same database that was used to retrieve the object in the first
+place::
+
+ >>> u = User.objects.using('legacy_users').get(username='fred')
+ >>> u.delete() # will delete from the `legacy_users` database
+
+To specify the database from which a model will be deleted, pass a
+``using`` keyword argument to the ``Model.delete()`` method. This
+argument works just like the ``using`` keyword argument to ``save()``.
+
+For example, if you're migrating a user from the ``legacy_users``
+database to the ``new_users`` database, you might use these commands::
+
+ >>> user_obj.save(using='new_users')
+ >>> user_obj.delete(using='legacy_users')
+
+Using managers with multiple databases
+--------------------------------------
+
+Use the ``db_manager()`` method on managers to give managers access to
+a non-default database.
+
+For example, say you have a custom manager method that touches the
+database -- ``User.objects.create_user()``. Because ``create_user()``
+is a manager method, not a ``QuerySet`` method, you can't do
+``User.objects.using('new_users').create_user()``. (The
+``create_user()`` method is only available on ``User.objects``, the
+manager, not on ``QuerySet`` objects derived from the manager.) The
+solution is to use ``db_manager()``, like this::
+
+ User.objects.db_manager('new_users').create_user(...)
+
+``db_manager()`` returns a copy of the manager bound to the database you specify.
+
+Using ``get_query_set()`` with multiple databases
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you're overriding ``get_query_set()`` on your manager, be sure to
+either call the method on the parent (using ``super()``) or do the
+appropriate handling of the ``_db`` attribute on the manager (a string
+containing the name of the database to use).
+
+For example, if you want to return a custom ``QuerySet`` class from
+the ``get_query_set`` method, you could do this::
+
+ class MyManager(models.Manager):
+ def get_query_set(self):
+ qs = CustomQuerySet(self.model)
+ if self._db is not None:
+ qs = qs.using(self._db)
+ return qs
+
+Exposing multiple databases in Django's admin interface
+=======================================================
+
+Django's admin doesn't have any explicit support for multiple
+databases. If you want to provide an admin interface for a model on a
+database other than that that specified by your router chain, you'll
+need to write custom :class:`~django.contrib.admin.ModelAdmin` classes
+that will direct the admin to use a specific database for content.
+
+``ModelAdmin`` objects have four methods that require customization for
+multiple-database support::
+
+ class MultiDBModelAdmin(admin.ModelAdmin):
+ # A handy constant for the name of the alternate database.
+ using = 'other'
+
+ def save_model(self, request, obj, form, change):
+ # Tell Django to save objects to the 'other' database.
+ obj.save(using=self.using)
+
+ def queryset(self, request):
+ # Tell Django to look for objects on the 'other' database.
+ return super(MultiDBModelAdmin, self).queryset(request).using(self.using)
+
+ def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
+ # Tell Django to populate ForeignKey widgets using a query
+ # on the 'other' database.
+ return super(MultiDBModelAdmin, self).formfield_for_foreignkey(db_field, request=request, using=self.using, **kwargs)
+
+ def formfield_for_manytomany(self, db_field, request=None, **kwargs):
+ # Tell Django to populate ManyToMany widgets using a query
+ # on the 'other' database.
+ return super(MultiDBModelAdmin, self).formfield_for_manytomany(db_field, request=request, using=self.using, **kwargs)
+
+The implementation provided here implements a multi-database strategy
+where all objects of a given type are stored on a specific database
+(e.g., all ``User`` objects are in the ``other`` database). If your
+usage of multiple databases is more complex, your ``ModelAdmin`` will
+need to reflect that strategy.
+
+Inlines can be handled in a similar fashion. They require three customized methods::
+
+ class MultiDBTabularInline(admin.TabularInline):
+ using = 'other'
+
+ def queryset(self, request):
+ # Tell Django to look for inline objects on the 'other' database.
+ return super(MultiDBTabularInline, self).queryset(request).using(self.using)
+
+ def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
+ # Tell Django to populate ForeignKey widgets using a query
+ # on the 'other' database.
+ return super(MultiDBTabularInline, self).formfield_for_foreignkey(db_field, request=request, using=self.using, **kwargs)
+
+ def formfield_for_manytomany(self, db_field, request=None, **kwargs):
+ # Tell Django to populate ManyToMany widgets using a query
+ # on the 'other' database.
+ return super(MultiDBTabularInline, self).formfield_for_manytomany(db_field, request=request, using=self.using, **kwargs)
+
+Once you've written your model admin definitions, they can be
+registered with any ``Admin`` instance::
+
+ from django.contrib import admin
+
+ # Specialize the multi-db admin objects for use with specific models.
+ class BookInline(MultiDBTabularInline):
+ model = Book
+
+ class PublisherAdmin(MultiDBModelAdmin):
+ inlines = [BookInline]
+
+ admin.site.register(Author, MultiDBModelAdmin)
+ admin.site.register(Publisher, PublisherAdmin)
+
+ othersite = admin.Site('othersite')
+ othersite.register(Publisher, MultiDBModelAdmin)
+
+This example sets up two admin sites. On the first site, the
+``Author`` and ``Publisher`` objects are exposed; ``Publisher``
+objects have an tabular inline showing books published by that
+publisher. The second site exposes just publishers, without the
+inlines.
+
+Using raw cursors with multiple databases
+=========================================
+
+If you are using more than one database you can use
+``django.db.connections`` to obtain the connection (and cursor) for a
+specific database. ``django.db.connections`` is a dictionary-like
+object that allows you to retrieve a specific connection using it's
+alias::
+
+ from django.db import connections
+ cursor = connections['my_db_alias'].cursor()
+
+Limitations of multiple databases
+=================================
+
+.. _no_cross_database_relations:
+
+Cross-database relations
+------------------------
+
+Django doesn't currently provide any support for foreign key or
+many-to-many relationships spanning multiple databases. If you
+have used a router to partition models to different databases,
+any foreign key and many-to-many relationships defined by those
+models must be internal to a single database.
+
+This is because of referential integrity. In order to maintain a
+relationship between two objects, Django needs to know that the
+primary key of the related object is valid. If the primary key is
+stored on a separate database, it's not possible to easily evaluate
+the validity of a primary key.
+
+If you're using Postgres, Oracle, or MySQL with InnoDB, this is
+enforced at the database integrity level -- database level key
+constraints prevent the creation of relations that can't be validated.
+
+However, if you're using SQLite or MySQL with MyISAM tables, there is
+no enforced referential integrity; as a result, you may be able to
+'fake' cross database foreign keys. However, this configuration is not
+officially supported by Django.
diff --git a/parts/django/docs/topics/db/optimization.txt b/parts/django/docs/topics/db/optimization.txt
new file mode 100644
index 0000000..7d51052
--- /dev/null
+++ b/parts/django/docs/topics/db/optimization.txt
@@ -0,0 +1,260 @@
+============================
+Database access optimization
+============================
+
+Django's database layer provides various ways to help developers get the most
+out of their databases. This document gathers together links to the relevant
+documentation, and adds various tips, organized under a number of headings that
+outline the steps to take when attempting to optimize your database usage.
+
+Profile first
+=============
+
+As general programming practice, this goes without saying. Find out :ref:`what
+queries you are doing and what they are costing you
+<faq-see-raw-sql-queries>`. You may also want to use an external project like
+django-debug-toolbar_, or a tool that monitors your database directly.
+
+Remember that you may be optimizing for speed or memory or both, depending on
+your requirements. Sometimes optimizing for one will be detrimental to the
+other, but sometimes they will help each other. Also, work that is done by the
+database process might not have the same cost (to you) as the same amount of
+work done in your Python process. It is up to you to decide what your
+priorities are, where the balance must lie, and profile all of these as required
+since this will depend on your application and server.
+
+With everything that follows, remember to profile after every change to ensure
+that the change is a benefit, and a big enough benefit given the decrease in
+readability of your code. **All** of the suggestions below come with the caveat
+that in your circumstances the general principle might not apply, or might even
+be reversed.
+
+.. _django-debug-toolbar: http://robhudson.github.com/django-debug-toolbar/
+
+Use standard DB optimization techniques
+=======================================
+
+...including:
+
+* Indexes. This is a number one priority, *after* you have determined from
+ profiling what indexes should be added. Use
+ :attr:`django.db.models.Field.db_index` to add these from Django.
+
+* Appropriate use of field types.
+
+We will assume you have done the obvious things above. The rest of this document
+focuses on how to use Django in such a way that you are not doing unnecessary
+work. This document also does not address other optimization techniques that
+apply to all expensive operations, such as :doc:`general purpose caching
+</topics/cache>`.
+
+Understand QuerySets
+====================
+
+Understanding :doc:`QuerySets </ref/models/querysets>` is vital to getting good
+performance with simple code. In particular:
+
+Understand QuerySet evaluation
+------------------------------
+
+To avoid performance problems, it is important to understand:
+
+* that :ref:`QuerySets are lazy <querysets-are-lazy>`.
+
+* when :ref:`they are evaluated <when-querysets-are-evaluated>`.
+
+* how :ref:`the data is held in memory <caching-and-querysets>`.
+
+Understand cached attributes
+----------------------------
+
+As well as caching of the whole ``QuerySet``, there is caching of the result of
+attributes on ORM objects. In general, attributes that are not callable will be
+cached. For example, assuming the :ref:`example Weblog models
+<queryset-model-example>`::
+
+ >>> entry = Entry.objects.get(id=1)
+ >>> entry.blog # Blog object is retrieved at this point
+ >>> entry.blog # cached version, no DB access
+
+But in general, callable attributes cause DB lookups every time::
+
+ >>> entry = Entry.objects.get(id=1)
+ >>> entry.authors.all() # query performed
+ >>> entry.authors.all() # query performed again
+
+Be careful when reading template code - the template system does not allow use
+of parentheses, but will call callables automatically, hiding the above
+distinction.
+
+Be careful with your own custom properties - it is up to you to implement
+caching.
+
+Use the ``with`` template tag
+-----------------------------
+
+To make use of the caching behaviour of ``QuerySet``, you may need to use the
+:ttag:`with` template tag.
+
+Use ``iterator()``
+------------------
+
+When you have a lot of objects, the caching behaviour of the ``QuerySet`` can
+cause a large amount of memory to be used. In this case,
+:meth:`~django.db.models.QuerySet.iterator()` may help.
+
+Do database work in the database rather than in Python
+======================================================
+
+For instance:
+
+* At the most basic level, use :ref:`filter and exclude <queryset-api>` to do
+ filtering in the database.
+
+* Use :ref:`F() object query expressions <query-expressions>` to do filtering
+ against other fields within the same model.
+
+* Use :doc:`annotate to do aggregation in the database </topics/db/aggregation>`.
+
+If these aren't enough to generate the SQL you need:
+
+Use ``QuerySet.extra()``
+------------------------
+
+A less portable but more powerful method is
+:meth:`~django.db.models.QuerySet.extra()`, which allows some SQL to be
+explicitly added to the query. If that still isn't powerful enough:
+
+Use raw SQL
+-----------
+
+Write your own :doc:`custom SQL to retrieve data or populate models
+</topics/db/sql>`. Use ``django.db.connection.queries`` to find out what Django
+is writing for you and start from there.
+
+Retrieve everything at once if you know you will need it
+========================================================
+
+Hitting the database multiple times for different parts of a single 'set' of
+data that you will need all parts of is, in general, less efficient than
+retrieving it all in one query. This is particularly important if you have a
+query that is executed in a loop, and could therefore end up doing many database
+queries, when only one was needed. So:
+
+Use ``QuerySet.select_related()``
+---------------------------------
+
+Understand :ref:`QuerySet.select_related() <select-related>` thoroughly, and use it:
+
+* in view code,
+
+* and in :doc:`managers and default managers </topics/db/managers>` where
+ appropriate. Be aware when your manager is and is not used; sometimes this is
+ tricky so don't make assumptions.
+
+Don't retrieve things you don't need
+====================================
+
+Use ``QuerySet.values()`` and ``values_list()``
+-----------------------------------------------
+
+When you just want a ``dict`` or ``list`` of values, and don't need ORM model
+objects, make appropriate usage of :meth:`~django.db.models.QuerySet.values()`.
+These can be useful for replacing model objects in template code - as long as
+the dicts you supply have the same attributes as those used in the template,
+you are fine.
+
+Use ``QuerySet.defer()`` and ``only()``
+---------------------------------------
+
+Use :meth:`~django.db.models.QuerySet.defer()` and
+:meth:`~django.db.models.QuerySet.only()` if there are database columns you
+know that you won't need (or won't need in most cases) to avoid loading
+them. Note that if you *do* use them, the ORM will have to go and get them in a
+separate query, making this a pessimization if you use it inappropriately.
+
+Use QuerySet.count()
+--------------------
+
+...if you only want the count, rather than doing ``len(queryset)``.
+
+Use QuerySet.exists()
+---------------------
+
+...if you only want to find out if at least one result exists, rather than ``if
+queryset``.
+
+But:
+
+Don't overuse ``count()`` and ``exists()``
+------------------------------------------
+
+If you are going to need other data from the QuerySet, just evaluate it.
+
+For example, assuming an Email class that has a ``body`` attribute and a
+many-to-many relation to User, the following template code is optimal:
+
+.. code-block:: html+django
+
+ {% if display_inbox %}
+ {% with user.emails.all as emails %}
+ {% if emails %}
+ <p>You have {{ emails|length }} email(s)</p>
+ {% for email in emails %}
+ <p>{{ email.body }}</p>
+ {% endfor %}
+ {% else %}
+ <p>No messages today.</p>
+ {% endif %}
+ {% endwith %}
+ {% endif %}
+
+
+It is optimal because:
+
+ 1. Since QuerySets are lazy, this does no database if 'display_inbox' is False.
+
+ #. Use of ``with`` means that we store ``user.emails.all`` in a variable for
+ later use, allowing its cache to be re-used.
+
+ #. The line ``{% if emails %}`` causes ``QuerySet.__nonzero__()`` to be called,
+ which causes the ``user.emails.all()`` query to be run on the database, and
+ at the least the first line to be turned into an ORM object. If there aren't
+ any results, it will return False, otherwise True.
+
+ #. The use of ``{{ emails|length }}`` calls ``QuerySet.__len__()``, filling
+ out the rest of the cache without doing another query.
+
+ #. The ``for`` loop iterates over the already filled cache.
+
+In total, this code does either one or zero database queries. The only
+deliberate optimization performed is the use of the ``with`` tag. Using
+``QuerySet.exists()`` or ``QuerySet.count()`` at any point would cause
+additional queries.
+
+Use ``QuerySet.update()`` and ``delete()``
+------------------------------------------
+
+Rather than retrieve a load of objects, set some values, and save them
+individual, use a bulk SQL UPDATE statement, via :ref:`QuerySet.update()
+<topics-db-queries-update>`. Similarly, do :ref:`bulk deletes
+<topics-db-queries-delete>` where possible.
+
+Note, however, that these bulk update methods cannot call the ``save()`` or
+``delete()`` methods of individual instances, which means that any custom
+behaviour you have added for these methods will not be executed, including
+anything driven from the normal database object :doc:`signals </ref/signals>`.
+
+Use foreign key values directly
+-------------------------------
+
+If you only need a foreign key value, use the foreign key value that is already on
+the object you've got, rather than getting the whole related object and taking
+its primary key. i.e. do::
+
+ entry.blog_id
+
+instead of::
+
+ entry.blog.id
+
diff --git a/parts/django/docs/topics/db/queries.txt b/parts/django/docs/topics/db/queries.txt
new file mode 100644
index 0000000..923b1e4
--- /dev/null
+++ b/parts/django/docs/topics/db/queries.txt
@@ -0,0 +1,1110 @@
+==============
+Making queries
+==============
+
+.. currentmodule:: django.db.models
+
+Once you've created your :doc:`data models </topics/db/models>`, Django
+automatically gives you a database-abstraction API that lets you create,
+retrieve, update and delete objects. This document explains how to use this
+API. Refer to the :doc:`data model reference </ref/models/index>` for full
+details of all the various model lookup options.
+
+Throughout this guide (and in the reference), we'll refer to the following
+models, which comprise a Weblog application:
+
+.. _queryset-model-example:
+
+.. code-block:: python
+
+ class Blog(models.Model):
+ name = models.CharField(max_length=100)
+ tagline = models.TextField()
+
+ def __unicode__(self):
+ return self.name
+
+ class Author(models.Model):
+ name = models.CharField(max_length=50)
+ email = models.EmailField()
+
+ def __unicode__(self):
+ return self.name
+
+ class Entry(models.Model):
+ blog = models.ForeignKey(Blog)
+ headline = models.CharField(max_length=255)
+ body_text = models.TextField()
+ pub_date = models.DateTimeField()
+ authors = models.ManyToManyField(Author)
+ n_comments = models.IntegerField()
+ n_pingbacks = models.IntegerField()
+ rating = models.IntegerField()
+
+ def __unicode__(self):
+ return self.headline
+
+Creating objects
+================
+
+To represent database-table data in Python objects, Django uses an intuitive
+system: A model class represents a database table, and an instance of that
+class represents a particular record in the database table.
+
+To create an object, instantiate it using keyword arguments to the model class,
+then call ``save()`` to save it to the database.
+
+You import the model class from wherever it lives on the Python path, as you
+may expect. (We point this out here because previous Django versions required
+funky model importing.)
+
+Assuming models live in a file ``mysite/blog/models.py``, here's an example::
+
+ >>> from blog.models import Blog
+ >>> b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')
+ >>> b.save()
+
+This performs an ``INSERT`` SQL statement behind the scenes. Django doesn't hit
+the database until you explicitly call ``save()``.
+
+The ``save()`` method has no return value.
+
+.. seealso::
+
+ ``save()`` takes a number of advanced options not described here.
+ See the documentation for ``save()`` for complete details.
+
+ To create an object and save it all in one step see the ```create()```
+ method.
+
+Saving changes to objects
+=========================
+
+To save changes to an object that's already in the database, use ``save()``.
+
+Given a ``Blog`` instance ``b5`` that has already been saved to the database,
+this example changes its name and updates its record in the database::
+
+ >> b5.name = 'New name'
+ >> b5.save()
+
+This performs an ``UPDATE`` SQL statement behind the scenes. Django doesn't hit
+the database until you explicitly call ``save()``.
+
+Saving ``ForeignKey`` and ``ManyToManyField`` fields
+----------------------------------------------------
+
+Updating a ``ForeignKey`` field works exactly the same way as saving a normal
+field; simply assign an object of the right type to the field in question.
+This example updates the ``blog`` attribute of an ``Entry`` instance ``entry``::
+
+ >>> from blog.models import Entry
+ >>> entry = Entry.objects.get(pk=1)
+ >>> cheese_blog = Blog.objects.get(name="Cheddar Talk")
+ >>> entry.blog = cheese_blog
+ >>> entry.save()
+
+Updating a ``ManyToManyField`` works a little differently; use the ``add()``
+method on the field to add a record to the relation. This example adds the
+``Author`` instance ``joe`` to the ``entry`` object::
+
+ >>> from blog.models import Author
+ >>> joe = Author.objects.create(name="Joe")
+ >>> entry.authors.add(joe)
+
+Django will complain if you try to assign or add an object of the wrong type.
+
+Retrieving objects
+==================
+
+To retrieve objects from your database, you construct a ``QuerySet`` via a
+``Manager`` on your model class.
+
+A ``QuerySet`` represents a collection of objects from your database. It can
+have zero, one or many *filters* -- criteria that narrow down the collection
+based on given parameters. In SQL terms, a ``QuerySet`` equates to a ``SELECT``
+statement, and a filter is a limiting clause such as ``WHERE`` or ``LIMIT``.
+
+You get a ``QuerySet`` by using your model's ``Manager``. Each model has at
+least one ``Manager``, and it's called ``objects`` by default. Access it
+directly via the model class, like so::
+
+ >>> Blog.objects
+ <django.db.models.manager.Manager object at ...>
+ >>> b = Blog(name='Foo', tagline='Bar')
+ >>> b.objects
+ Traceback:
+ ...
+ AttributeError: "Manager isn't accessible via Blog instances."
+
+.. note::
+
+ ``Managers`` are accessible only via model classes, rather than from model
+ instances, to enforce a separation between "table-level" operations and
+ "record-level" operations.
+
+The ``Manager`` is the main source of ``QuerySets`` for a model. It acts as a
+"root" ``QuerySet`` that describes all objects in the model's database table.
+For example, ``Blog.objects`` is the initial ``QuerySet`` that contains all
+``Blog`` objects in the database.
+
+Retrieving all objects
+----------------------
+
+The simplest way to retrieve objects from a table is to get all of them.
+To do this, use the ``all()`` method on a ``Manager``::
+
+ >>> all_entries = Entry.objects.all()
+
+The ``all()`` method returns a ``QuerySet`` of all the objects in the database.
+
+(If ``Entry.objects`` is a ``QuerySet``, why can't we just do ``Entry.objects``?
+That's because ``Entry.objects``, the root ``QuerySet``, is a special case
+that cannot be evaluated. The ``all()`` method returns a ``QuerySet`` that
+*can* be evaluated.)
+
+
+Retrieving specific objects with filters
+----------------------------------------
+
+The root ``QuerySet`` provided by the ``Manager`` describes all objects in the
+database table. Usually, though, you'll need to select only a subset of the
+complete set of objects.
+
+To create such a subset, you refine the initial ``QuerySet``, adding filter
+conditions. The two most common ways to refine a ``QuerySet`` are:
+
+ ``filter(**kwargs)``
+ Returns a new ``QuerySet`` containing objects that match the given
+ lookup parameters.
+
+ ``exclude(**kwargs)``
+ Returns a new ``QuerySet`` containing objects that do *not* match the
+ given lookup parameters.
+
+The lookup parameters (``**kwargs`` in the above function definitions) should
+be in the format described in `Field lookups`_ below.
+
+For example, to get a ``QuerySet`` of blog entries from the year 2006, use
+``filter()`` like so::
+
+ Entry.objects.filter(pub_date__year=2006)
+
+We don't have to add an ``all()`` -- ``Entry.objects.all().filter(...)``. That
+would still work, but you only need ``all()`` when you want all objects from the
+root ``QuerySet``.
+
+.. _chaining-filters:
+
+Chaining filters
+~~~~~~~~~~~~~~~~
+
+The result of refining a ``QuerySet`` is itself a ``QuerySet``, so it's
+possible to chain refinements together. For example::
+
+ >>> Entry.objects.filter(
+ ... headline__startswith='What'
+ ... ).exclude(
+ ... pub_date__gte=datetime.now()
+ ... ).filter(
+ ... pub_date__gte=datetime(2005, 1, 1)
+ ... )
+
+This takes the initial ``QuerySet`` of all entries in the database, adds a
+filter, then an exclusion, then another filter. The final result is a
+``QuerySet`` containing all entries with a headline that starts with "What",
+that were published between January 1, 2005, and the current day.
+
+.. _filtered-querysets-are-unique:
+
+Filtered QuerySets are unique
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Each time you refine a ``QuerySet``, you get a brand-new ``QuerySet`` that is
+in no way bound to the previous ``QuerySet``. Each refinement creates a
+separate and distinct ``QuerySet`` that can be stored, used and reused.
+
+Example::
+
+ >> q1 = Entry.objects.filter(headline__startswith="What")
+ >> q2 = q1.exclude(pub_date__gte=datetime.now())
+ >> q3 = q1.filter(pub_date__gte=datetime.now())
+
+These three ``QuerySets`` are separate. The first is a base ``QuerySet``
+containing all entries that contain a headline starting with "What". The second
+is a subset of the first, with an additional criteria that excludes records
+whose ``pub_date`` is greater than now. The third is a subset of the first,
+with an additional criteria that selects only the records whose ``pub_date`` is
+greater than now. The initial ``QuerySet`` (``q1``) is unaffected by the
+refinement process.
+
+.. _querysets-are-lazy:
+
+QuerySets are lazy
+~~~~~~~~~~~~~~~~~~
+
+``QuerySets`` are lazy -- the act of creating a ``QuerySet`` doesn't involve any
+database activity. You can stack filters together all day long, and Django won't
+actually run the query until the ``QuerySet`` is *evaluated*. Take a look at
+this example::
+
+ >>> q = Entry.objects.filter(headline__startswith="What")
+ >>> q = q.filter(pub_date__lte=datetime.now())
+ >>> q = q.exclude(body_text__icontains="food")
+ >>> print q
+
+Though this looks like three database hits, in fact it hits the database only
+once, at the last line (``print q``). In general, the results of a ``QuerySet``
+aren't fetched from the database until you "ask" for them. When you do, the
+``QuerySet`` is *evaluated* by accessing the database. For more details on
+exactly when evaluation takes place, see :ref:`when-querysets-are-evaluated`.
+
+
+.. _retrieving-single-object-with-get:
+
+Retrieving a single object with get
+-----------------------------------
+
+``.filter()`` will always give you a ``QuerySet``, even if only a single
+object matches the query - in this case, it will be a ``QuerySet`` containing
+a single element.
+
+If you know there is only one object that matches your query, you can use
+the ``get()`` method on a `Manager` which returns the object directly::
+
+ >>> one_entry = Entry.objects.get(pk=1)
+
+You can use any query expression with ``get()``, just like with ``filter()`` -
+again, see `Field lookups`_ below.
+
+Note that there is a difference between using ``.get()``, and using
+``.filter()`` with a slice of ``[0]``. If there are no results that match the
+query, ``.get()`` will raise a ``DoesNotExist`` exception. This exception is an
+attribute of the model class that the query is being performed on - so in the
+code above, if there is no ``Entry`` object with a primary key of 1, Django will
+raise ``Entry.DoesNotExist``.
+
+Similarly, Django will complain if more than one item matches the ``get()``
+query. In this case, it will raise ``MultipleObjectsReturned``, which again is
+an attribute of the model class itself.
+
+
+Other QuerySet methods
+----------------------
+
+Most of the time you'll use ``all()``, ``get()``, ``filter()`` and ``exclude()``
+when you need to look up objects from the database. However, that's far from all
+there is; see the :ref:`QuerySet API Reference <queryset-api>` for a complete
+list of all the various ``QuerySet`` methods.
+
+.. _limiting-querysets:
+
+Limiting QuerySets
+------------------
+
+Use a subset of Python's array-slicing syntax to limit your ``QuerySet`` to a
+certain number of results. This is the equivalent of SQL's ``LIMIT`` and
+``OFFSET`` clauses.
+
+For example, this returns the first 5 objects (``LIMIT 5``)::
+
+ >>> Entry.objects.all()[:5]
+
+This returns the sixth through tenth objects (``OFFSET 5 LIMIT 5``)::
+
+ >>> Entry.objects.all()[5:10]
+
+Negative indexing (i.e. ``Entry.objects.all()[-1]``) is not supported.
+
+Generally, slicing a ``QuerySet`` returns a new ``QuerySet`` -- it doesn't
+evaluate the query. An exception is if you use the "step" parameter of Python
+slice syntax. For example, this would actually execute the query in order to
+return a list of every *second* object of the first 10::
+
+ >>> Entry.objects.all()[:10:2]
+
+To retrieve a *single* object rather than a list
+(e.g. ``SELECT foo FROM bar LIMIT 1``), use a simple index instead of a
+slice. For example, this returns the first ``Entry`` in the database, after
+ordering entries alphabetically by headline::
+
+ >>> Entry.objects.order_by('headline')[0]
+
+This is roughly equivalent to::
+
+ >>> Entry.objects.order_by('headline')[0:1].get()
+
+Note, however, that the first of these will raise ``IndexError`` while the
+second will raise ``DoesNotExist`` if no objects match the given criteria. See
+:meth:`~django.db.models.QuerySet.get` for more details.
+
+.. _field-lookups-intro:
+
+Field lookups
+-------------
+
+Field lookups are how you specify the meat of an SQL ``WHERE`` clause. They're
+specified as keyword arguments to the ``QuerySet`` methods ``filter()``,
+``exclude()`` and ``get()``.
+
+Basic lookups keyword arguments take the form ``field__lookuptype=value``.
+(That's a double-underscore). For example::
+
+ >>> Entry.objects.filter(pub_date__lte='2006-01-01')
+
+translates (roughly) into the following SQL::
+
+ SELECT * FROM blog_entry WHERE pub_date <= '2006-01-01';
+
+.. admonition:: How this is possible
+
+ Python has the ability to define functions that accept arbitrary name-value
+ arguments whose names and values are evaluated at runtime. For more
+ information, see `Keyword Arguments`_ in the official Python tutorial.
+
+ .. _`Keyword Arguments`: http://docs.python.org/tutorial/controlflow.html#keyword-arguments
+
+If you pass an invalid keyword argument, a lookup function will raise
+``TypeError``.
+
+The database API supports about two dozen lookup types; a complete reference
+can be found in the :ref:`field lookup reference <field-lookups>`. To give you a taste of what's available, here's some of the more common lookups
+you'll probably use:
+
+ :lookup:`exact`
+ An "exact" match. For example::
+
+ >>> Entry.objects.get(headline__exact="Man bites dog")
+
+ Would generate SQL along these lines:
+
+ .. code-block:: sql
+
+ SELECT ... WHERE headline = 'Man bites dog';
+
+ If you don't provide a lookup type -- that is, if your keyword argument
+ doesn't contain a double underscore -- the lookup type is assumed to be
+ ``exact``.
+
+ For example, the following two statements are equivalent::
+
+ >>> Blog.objects.get(id__exact=14) # Explicit form
+ >>> Blog.objects.get(id=14) # __exact is implied
+
+ This is for convenience, because ``exact`` lookups are the common case.
+
+ :lookup:`iexact`
+ A case-insensitive match. So, the query::
+
+ >>> Blog.objects.get(name__iexact="beatles blog")
+
+ Would match a ``Blog`` titled "Beatles Blog", "beatles blog", or even
+ "BeAtlES blOG".
+
+ :lookup:`contains`
+ Case-sensitive containment test. For example::
+
+ Entry.objects.get(headline__contains='Lennon')
+
+ Roughly translates to this SQL:
+
+ .. code-block:: sql
+
+ SELECT ... WHERE headline LIKE '%Lennon%';
+
+ Note this will match the headline ``'Today Lennon honored'`` but not
+ ``'today lennon honored'``.
+
+ There's also a case-insensitive version, :lookup:`icontains`.
+
+ :lookup:`startswith`, :lookup:`endswith`
+ Starts-with and ends-with search, respectively. There are also
+ case-insensitive versions called :lookup:`istartswith` and
+ :lookup:`iendswith`.
+
+Again, this only scratches the surface. A complete reference can be found in the
+:ref:`field lookup reference <field-lookups>`.
+
+Lookups that span relationships
+-------------------------------
+
+Django offers a powerful and intuitive way to "follow" relationships in
+lookups, taking care of the SQL ``JOIN``\s for you automatically, behind the
+scenes. To span a relationship, just use the field name of related fields
+across models, separated by double underscores, until you get to the field you
+want.
+
+This example retrieves all ``Entry`` objects with a ``Blog`` whose ``name``
+is ``'Beatles Blog'``::
+
+ >>> Entry.objects.filter(blog__name__exact='Beatles Blog')
+
+This spanning can be as deep as you'd like.
+
+It works backwards, too. To refer to a "reverse" relationship, just use the
+lowercase name of the model.
+
+This example retrieves all ``Blog`` objects which have at least one ``Entry``
+whose ``headline`` contains ``'Lennon'``::
+
+ >>> Blog.objects.filter(entry__headline__contains='Lennon')
+
+If you are filtering across multiple relationships and one of the intermediate
+models doesn't have a value that meets the filter condition, Django will treat
+it as if there is an empty (all values are ``NULL``), but valid, object there.
+All this means is that no error will be raised. For example, in this filter::
+
+ Blog.objects.filter(entry__authors__name='Lennon')
+
+(if there was a related ``Author`` model), if there was no ``author``
+associated with an entry, it would be treated as if there was also no ``name``
+attached, rather than raising an error because of the missing ``author``.
+Usually this is exactly what you want to have happen. The only case where it
+might be confusing is if you are using ``isnull``. Thus::
+
+ Blog.objects.filter(entry__authors__name__isnull=True)
+
+will return ``Blog`` objects that have an empty ``name`` on the ``author`` and
+also those which have an empty ``author`` on the ``entry``. If you don't want
+those latter objects, you could write::
+
+ Blog.objects.filter(entry__authors__isnull=False,
+ entry__authors__name__isnull=True)
+
+Spanning multi-valued relationships
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.0
+
+When you are filtering an object based on a ``ManyToManyField`` or a reverse
+``ForeignKey``, there are two different sorts of filter you may be
+interested in. Consider the ``Blog``/``Entry`` relationship (``Blog`` to
+``Entry`` is a one-to-many relation). We might be interested in finding blogs
+that have an entry which has both *"Lennon"* in the headline and was published
+in 2008. Or we might want to find blogs that have an entry with *"Lennon"* in
+the headline as well as an entry that was published in 2008. Since there are
+multiple entries associated with a single ``Blog``, both of these queries are
+possible and make sense in some situations.
+
+The same type of situation arises with a ``ManyToManyField``. For example, if
+an ``Entry`` has a ``ManyToManyField`` called ``tags``, we might want to find
+entries linked to tags called *"music"* and *"bands"* or we might want an
+entry that contains a tag with a name of *"music"* and a status of *"public"*.
+
+To handle both of these situations, Django has a consistent way of processing
+``filter()`` and ``exclude()`` calls. Everything inside a single ``filter()``
+call is applied simultaneously to filter out items matching all those
+requirements. Successive ``filter()`` calls further restrict the set of
+objects, but for multi-valued relations, they apply to any object linked to
+the primary model, not necessarily those objects that were selected by an
+earlier ``filter()`` call.
+
+That may sound a bit confusing, so hopefully an example will clarify. To
+select all blogs that contain entries with both *"Lennon"* in the headline
+and that were published in 2008 (the same entry satisfying both conditions),
+we would write::
+
+ Blog.objects.filter(entry__headline__contains='Lennon',
+ entry__pub_date__year=2008)
+
+To select all blogs that contain an entry with *"Lennon"* in the headline
+**as well as** an entry that was published in 2008, we would write::
+
+ Blog.objects.filter(entry__headline__contains='Lennon').filter(
+ entry__pub_date__year=2008)
+
+In this second example, the first filter restricted the queryset to all those
+blogs linked to that particular type of entry. The second filter restricted
+the set of blogs *further* to those that are also linked to the second type of
+entry. The entries select by the second filter may or may not be the same as
+the entries in the first filter. We are filtering the ``Blog`` items with each
+filter statement, not the ``Entry`` items.
+
+All of this behavior also applies to ``exclude()``: all the conditions in a
+single ``exclude()`` statement apply to a single instance (if those conditions
+are talking about the same multi-valued relation). Conditions in subsequent
+``filter()`` or ``exclude()`` calls that refer to the same relation may end up
+filtering on different linked objects.
+
+.. _query-expressions:
+
+Filters can reference fields on the model
+-----------------------------------------
+
+.. versionadded:: 1.1
+
+In the examples given so far, we have constructed filters that compare
+the value of a model field with a constant. But what if you want to compare
+the value of a model field with another field on the same model?
+
+Django provides the ``F()`` object to allow such comparisons. Instances
+of ``F()`` act as a reference to a model field within a query. These
+references can then be used in query filters to compare the values of two
+different fields on the same model instance.
+
+For example, to find a list of all blog entries that have had more comments
+than pingbacks, we construct an ``F()`` object to reference the comment count,
+and use that ``F()`` object in the query::
+
+ >>> from django.db.models import F
+ >>> Entry.objects.filter(n_comments__gt=F('n_pingbacks'))
+
+Django supports the use of addition, subtraction, multiplication,
+division and modulo arithmetic with ``F()`` objects, both with constants
+and with other ``F()`` objects. To find all the blog entries with more than
+*twice* as many comments as pingbacks, we modify the query::
+
+ >>> Entry.objects.filter(n_comments__gt=F('n_pingbacks') * 2)
+
+To find all the entries where the rating of the entry is less than the
+sum of the pingback count and comment count, we would issue the
+query::
+
+ >>> Entry.objects.filter(rating__lt=F('n_comments') + F('n_pingbacks'))
+
+You can also use the double underscore notation to span relationships in
+an ``F()`` object. An ``F()`` object with a double underscore will introduce
+any joins needed to access the related object. For example, to retrieve all
+the entries where the author's name is the same as the blog name, we could
+issue the query:
+
+ >>> Entry.objects.filter(authors__name=F('blog__name'))
+
+The pk lookup shortcut
+----------------------
+
+For convenience, Django provides a ``pk`` lookup shortcut, which stands for
+"primary key".
+
+In the example ``Blog`` model, the primary key is the ``id`` field, so these
+three statements are equivalent::
+
+ >>> Blog.objects.get(id__exact=14) # Explicit form
+ >>> Blog.objects.get(id=14) # __exact is implied
+ >>> Blog.objects.get(pk=14) # pk implies id__exact
+
+The use of ``pk`` isn't limited to ``__exact`` queries -- any query term
+can be combined with ``pk`` to perform a query on the primary key of a model::
+
+ # Get blogs entries with id 1, 4 and 7
+ >>> Blog.objects.filter(pk__in=[1,4,7])
+
+ # Get all blog entries with id > 14
+ >>> Blog.objects.filter(pk__gt=14)
+
+``pk`` lookups also work across joins. For example, these three statements are
+equivalent::
+
+ >>> Entry.objects.filter(blog__id__exact=3) # Explicit form
+ >>> Entry.objects.filter(blog__id=3) # __exact is implied
+ >>> Entry.objects.filter(blog__pk=3) # __pk implies __id__exact
+
+Escaping percent signs and underscores in LIKE statements
+---------------------------------------------------------
+
+The field lookups that equate to ``LIKE`` SQL statements (``iexact``,
+``contains``, ``icontains``, ``startswith``, ``istartswith``, ``endswith``
+and ``iendswith``) will automatically escape the two special characters used in
+``LIKE`` statements -- the percent sign and the underscore. (In a ``LIKE``
+statement, the percent sign signifies a multiple-character wildcard and the
+underscore signifies a single-character wildcard.)
+
+This means things should work intuitively, so the abstraction doesn't leak.
+For example, to retrieve all the entries that contain a percent sign, just use
+the percent sign as any other character::
+
+ >>> Entry.objects.filter(headline__contains='%')
+
+Django takes care of the quoting for you; the resulting SQL will look something
+like this:
+
+.. code-block:: sql
+
+ SELECT ... WHERE headline LIKE '%\%%';
+
+Same goes for underscores. Both percentage signs and underscores are handled
+for you transparently.
+
+.. _caching-and-querysets:
+
+Caching and QuerySets
+---------------------
+
+Each ``QuerySet`` contains a cache, to minimize database access. It's important
+to understand how it works, in order to write the most efficient code.
+
+In a newly created ``QuerySet``, the cache is empty. The first time a
+``QuerySet`` is evaluated -- and, hence, a database query happens -- Django
+saves the query results in the ``QuerySet``'s cache and returns the results
+that have been explicitly requested (e.g., the next element, if the
+``QuerySet`` is being iterated over). Subsequent evaluations of the
+``QuerySet`` reuse the cached results.
+
+Keep this caching behavior in mind, because it may bite you if you don't use
+your ``QuerySet``\s correctly. For example, the following will create two
+``QuerySet``\s, evaluate them, and throw them away::
+
+ >>> print [e.headline for e in Entry.objects.all()]
+ >>> print [e.pub_date for e in Entry.objects.all()]
+
+That means the same database query will be executed twice, effectively doubling
+your database load. Also, there's a possibility the two lists may not include
+the same database records, because an ``Entry`` may have been added or deleted
+in the split second between the two requests.
+
+To avoid this problem, simply save the ``QuerySet`` and reuse it::
+
+ >>> queryset = Entry.objects.all()
+ >>> print [p.headline for p in queryset] # Evaluate the query set.
+ >>> print [p.pub_date for p in queryset] # Re-use the cache from the evaluation.
+
+.. _complex-lookups-with-q:
+
+Complex lookups with Q objects
+==============================
+
+Keyword argument queries -- in ``filter()``, etc. -- are "AND"ed together. If
+you need to execute more complex queries (for example, queries with ``OR``
+statements), you can use ``Q`` objects.
+
+A ``Q`` object (``django.db.models.Q``) is an object used to encapsulate a
+collection of keyword arguments. These keyword arguments are specified as in
+"Field lookups" above.
+
+For example, this ``Q`` object encapsulates a single ``LIKE`` query::
+
+ Q(question__startswith='What')
+
+``Q`` objects can be combined using the ``&`` and ``|`` operators. When an
+operator is used on two ``Q`` objects, it yields a new ``Q`` object.
+
+For example, this statement yields a single ``Q`` object that represents the
+"OR" of two ``"question__startswith"`` queries::
+
+ Q(question__startswith='Who') | Q(question__startswith='What')
+
+This is equivalent to the following SQL ``WHERE`` clause::
+
+ WHERE question LIKE 'Who%' OR question LIKE 'What%'
+
+You can compose statements of arbitrary complexity by combining ``Q`` objects
+with the ``&`` and ``|`` operators and use parenthetical grouping. Also, ``Q``
+objects can be negated using the ``~`` operator, allowing for combined lookups
+that combine both a normal query and a negated (``NOT``) query::
+
+ Q(question__startswith='Who') | ~Q(pub_date__year=2005)
+
+Each lookup function that takes keyword-arguments (e.g. ``filter()``,
+``exclude()``, ``get()``) can also be passed one or more ``Q`` objects as
+positional (not-named) arguments. If you provide multiple ``Q`` object
+arguments to a lookup function, the arguments will be "AND"ed together. For
+example::
+
+ Poll.objects.get(
+ Q(question__startswith='Who'),
+ Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6))
+ )
+
+... roughly translates into the SQL::
+
+ SELECT * from polls WHERE question LIKE 'Who%'
+ AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')
+
+Lookup functions can mix the use of ``Q`` objects and keyword arguments. All
+arguments provided to a lookup function (be they keyword arguments or ``Q``
+objects) are "AND"ed together. However, if a ``Q`` object is provided, it must
+precede the definition of any keyword arguments. For example::
+
+ Poll.objects.get(
+ Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),
+ question__startswith='Who')
+
+... would be a valid query, equivalent to the previous example; but::
+
+ # INVALID QUERY
+ Poll.objects.get(
+ question__startswith='Who',
+ Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))
+
+... would not be valid.
+
+.. seealso::
+
+ The `OR lookups examples`_ in the Django unit tests show some possible uses
+ of ``Q``.
+
+ .. _OR lookups examples: http://code.djangoproject.com/browser/django/trunk/tests/modeltests/or_lookups/tests.py
+
+Comparing objects
+=================
+
+To compare two model instances, just use the standard Python comparison operator,
+the double equals sign: ``==``. Behind the scenes, that compares the primary
+key values of two models.
+
+Using the ``Entry`` example above, the following two statements are equivalent::
+
+ >>> some_entry == other_entry
+ >>> some_entry.id == other_entry.id
+
+If a model's primary key isn't called ``id``, no problem. Comparisons will
+always use the primary key, whatever it's called. For example, if a model's
+primary key field is called ``name``, these two statements are equivalent::
+
+ >>> some_obj == other_obj
+ >>> some_obj.name == other_obj.name
+
+.. _topics-db-queries-delete:
+
+Deleting objects
+================
+
+The delete method, conveniently, is named ``delete()``. This method immediately
+deletes the object and has no return value. Example::
+
+ e.delete()
+
+You can also delete objects in bulk. Every ``QuerySet`` has a ``delete()``
+method, which deletes all members of that ``QuerySet``.
+
+For example, this deletes all ``Entry`` objects with a ``pub_date`` year of
+2005::
+
+ Entry.objects.filter(pub_date__year=2005).delete()
+
+Keep in mind that this will, whenever possible, be executed purely in
+SQL, and so the ``delete()`` methods of individual object instances
+will not necessarily be called during the process. If you've provided
+a custom ``delete()`` method on a model class and want to ensure that
+it is called, you will need to "manually" delete instances of that
+model (e.g., by iterating over a ``QuerySet`` and calling ``delete()``
+on each object individually) rather than using the bulk ``delete()``
+method of a ``QuerySet``.
+
+When Django deletes an object, it emulates the behavior of the SQL
+constraint ``ON DELETE CASCADE`` -- in other words, any objects which
+had foreign keys pointing at the object to be deleted will be deleted
+along with it. For example::
+
+ b = Blog.objects.get(pk=1)
+ # This will delete the Blog and all of its Entry objects.
+ b.delete()
+
+Note that ``delete()`` is the only ``QuerySet`` method that is not exposed on a
+``Manager`` itself. This is a safety mechanism to prevent you from accidentally
+requesting ``Entry.objects.delete()``, and deleting *all* the entries. If you
+*do* want to delete all the objects, then you have to explicitly request a
+complete query set::
+
+ Entry.objects.all().delete()
+
+.. _topics-db-queries-update:
+
+Updating multiple objects at once
+=================================
+
+.. versionadded:: 1.0
+
+Sometimes you want to set a field to a particular value for all the objects in
+a ``QuerySet``. You can do this with the ``update()`` method. For example::
+
+ # Update all the headlines with pub_date in 2007.
+ Entry.objects.filter(pub_date__year=2007).update(headline='Everything is the same')
+
+You can only set non-relation fields and ``ForeignKey`` fields using this
+method. To update a non-relation field, provide the new value as a constant.
+To update ``ForeignKey`` fields, set the new value to be the new model
+instance you want to point to. For example::
+
+ >>> b = Blog.objects.get(pk=1)
+
+ # Change every Entry so that it belongs to this Blog.
+ >>> Entry.objects.all().update(blog=b)
+
+The ``update()`` method is applied instantly and returns the number of rows
+affected by the query. The only restriction on the ``QuerySet`` that is
+updated is that it can only access one database table, the model's main
+table. You can filter based on related fields, but you can only update columns
+in the model's main table. Example::
+
+ >>> b = Blog.objects.get(pk=1)
+
+ # Update all the headlines belonging to this Blog.
+ >>> Entry.objects.select_related().filter(blog=b).update(headline='Everything is the same')
+
+Be aware that the ``update()`` method is converted directly to an SQL
+statement. It is a bulk operation for direct updates. It doesn't run any
+``save()`` methods on your models, or emit the ``pre_save`` or ``post_save``
+signals (which are a consequence of calling ``save()``). If you want to save
+every item in a ``QuerySet`` and make sure that the ``save()`` method is
+called on each instance, you don't need any special function to handle that.
+Just loop over them and call ``save()``::
+
+ for item in my_queryset:
+ item.save()
+
+.. versionadded:: 1.1
+
+Calls to update can also use :ref:`F() objects <query-expressions>` to update
+one field based on the value of another field in the model. This is especially
+useful for incrementing counters based upon their current value. For example, to
+increment the pingback count for every entry in the blog::
+
+ >>> Entry.objects.all().update(n_pingbacks=F('n_pingbacks') + 1)
+
+However, unlike ``F()`` objects in filter and exclude clauses, you can't
+introduce joins when you use ``F()`` objects in an update -- you can only
+reference fields local to the model being updated. If you attempt to introduce
+a join with an ``F()`` object, a ``FieldError`` will be raised::
+
+ # THIS WILL RAISE A FieldError
+ >>> Entry.objects.update(headline=F('blog__name'))
+
+Related objects
+===============
+
+When you define a relationship in a model (i.e., a ``ForeignKey``,
+``OneToOneField``, or ``ManyToManyField``), instances of that model will have
+a convenient API to access the related object(s).
+
+Using the models at the top of this page, for example, an ``Entry`` object ``e``
+can get its associated ``Blog`` object by accessing the ``blog`` attribute:
+``e.blog``.
+
+(Behind the scenes, this functionality is implemented by Python descriptors_.
+This shouldn't really matter to you, but we point it out here for the curious.)
+
+Django also creates API accessors for the "other" side of the relationship --
+the link from the related model to the model that defines the relationship.
+For example, a ``Blog`` object ``b`` has access to a list of all related
+``Entry`` objects via the ``entry_set`` attribute: ``b.entry_set.all()``.
+
+All examples in this section use the sample ``Blog``, ``Author`` and ``Entry``
+models defined at the top of this page.
+
+.. _descriptors: http://users.rcn.com/python/download/Descriptor.htm
+
+One-to-many relationships
+-------------------------
+
+Forward
+~~~~~~~
+
+If a model has a ``ForeignKey``, instances of that model will have access to
+the related (foreign) object via a simple attribute of the model.
+
+Example::
+
+ >>> e = Entry.objects.get(id=2)
+ >>> e.blog # Returns the related Blog object.
+
+You can get and set via a foreign-key attribute. As you may expect, changes to
+the foreign key aren't saved to the database until you call ``save()``.
+Example::
+
+ >>> e = Entry.objects.get(id=2)
+ >>> e.blog = some_blog
+ >>> e.save()
+
+If a ``ForeignKey`` field has ``null=True`` set (i.e., it allows ``NULL``
+values), you can assign ``None`` to it. Example::
+
+ >>> e = Entry.objects.get(id=2)
+ >>> e.blog = None
+ >>> e.save() # "UPDATE blog_entry SET blog_id = NULL ...;"
+
+Forward access to one-to-many relationships is cached the first time the
+related object is accessed. Subsequent accesses to the foreign key on the same
+object instance are cached. Example::
+
+ >>> e = Entry.objects.get(id=2)
+ >>> print e.blog # Hits the database to retrieve the associated Blog.
+ >>> print e.blog # Doesn't hit the database; uses cached version.
+
+Note that the ``select_related()`` ``QuerySet`` method recursively prepopulates
+the cache of all one-to-many relationships ahead of time. Example::
+
+ >>> e = Entry.objects.select_related().get(id=2)
+ >>> print e.blog # Doesn't hit the database; uses cached version.
+ >>> print e.blog # Doesn't hit the database; uses cached version.
+
+.. _backwards-related-objects:
+
+Following relationships "backward"
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If a model has a ``ForeignKey``, instances of the foreign-key model will have
+access to a ``Manager`` that returns all instances of the first model. By
+default, this ``Manager`` is named ``FOO_set``, where ``FOO`` is the source
+model name, lowercased. This ``Manager`` returns ``QuerySets``, which can be
+filtered and manipulated as described in the "Retrieving objects" section
+above.
+
+Example::
+
+ >>> b = Blog.objects.get(id=1)
+ >>> b.entry_set.all() # Returns all Entry objects related to Blog.
+
+ # b.entry_set is a Manager that returns QuerySets.
+ >>> b.entry_set.filter(headline__contains='Lennon')
+ >>> b.entry_set.count()
+
+You can override the ``FOO_set`` name by setting the ``related_name``
+parameter in the ``ForeignKey()`` definition. For example, if the ``Entry``
+model was altered to ``blog = ForeignKey(Blog, related_name='entries')``, the
+above example code would look like this::
+
+ >>> b = Blog.objects.get(id=1)
+ >>> b.entries.all() # Returns all Entry objects related to Blog.
+
+ # b.entries is a Manager that returns QuerySets.
+ >>> b.entries.filter(headline__contains='Lennon')
+ >>> b.entries.count()
+
+You cannot access a reverse ``ForeignKey`` ``Manager`` from the class; it must
+be accessed from an instance::
+
+ >>> Blog.entry_set
+ Traceback:
+ ...
+ AttributeError: "Manager must be accessed via instance".
+
+In addition to the ``QuerySet`` methods defined in "Retrieving objects" above,
+the ``ForeignKey`` ``Manager`` has additional methods used to handle the set of
+related objects. A synopsis of each is below, and complete details can be found
+in the :doc:`related objects reference </ref/models/relations>`.
+
+``add(obj1, obj2, ...)``
+ Adds the specified model objects to the related object set.
+
+``create(**kwargs)``
+ Creates a new object, saves it and puts it in the related object set.
+ Returns the newly created object.
+
+``remove(obj1, obj2, ...)``
+ Removes the specified model objects from the related object set.
+
+``clear()``
+ Removes all objects from the related object set.
+
+To assign the members of a related set in one fell swoop, just assign to it
+from any iterable object. The iterable can contain object instances, or just
+a list of primary key values. For example::
+
+ b = Blog.objects.get(id=1)
+ b.entry_set = [e1, e2]
+
+In this example, ``e1`` and ``e2`` can be full Entry instances, or integer
+primary key values.
+
+If the ``clear()`` method is available, any pre-existing objects will be
+removed from the ``entry_set`` before all objects in the iterable (in this
+case, a list) are added to the set. If the ``clear()`` method is *not*
+available, all objects in the iterable will be added without removing any
+existing elements.
+
+Each "reverse" operation described in this section has an immediate effect on
+the database. Every addition, creation and deletion is immediately and
+automatically saved to the database.
+
+Many-to-many relationships
+--------------------------
+
+Both ends of a many-to-many relationship get automatic API access to the other
+end. The API works just as a "backward" one-to-many relationship, above.
+
+The only difference is in the attribute naming: The model that defines the
+``ManyToManyField`` uses the attribute name of that field itself, whereas the
+"reverse" model uses the lowercased model name of the original model, plus
+``'_set'`` (just like reverse one-to-many relationships).
+
+An example makes this easier to understand::
+
+ e = Entry.objects.get(id=3)
+ e.authors.all() # Returns all Author objects for this Entry.
+ e.authors.count()
+ e.authors.filter(name__contains='John')
+
+ a = Author.objects.get(id=5)
+ a.entry_set.all() # Returns all Entry objects for this Author.
+
+Like ``ForeignKey``, ``ManyToManyField`` can specify ``related_name``. In the
+above example, if the ``ManyToManyField`` in ``Entry`` had specified
+``related_name='entries'``, then each ``Author`` instance would have an
+``entries`` attribute instead of ``entry_set``.
+
+One-to-one relationships
+------------------------
+
+One-to-one relationships are very similar to many-to-one relationships. If you
+define a :class:`~django.db.models.OneToOneField` on your model, instances of
+that model will have access to the related object via a simple attribute of the
+model.
+
+For example::
+
+ class EntryDetail(models.Model):
+ entry = models.OneToOneField(Entry)
+ details = models.TextField()
+
+ ed = EntryDetail.objects.get(id=2)
+ ed.entry # Returns the related Entry object.
+
+The difference comes in "reverse" queries. The related model in a one-to-one
+relationship also has access to a :class:`~django.db.models.Manager` object, but
+that :class:`~django.db.models.Manager` represents a single object, rather than
+a collection of objects::
+
+ e = Entry.objects.get(id=2)
+ e.entrydetail # returns the related EntryDetail object
+
+If no object has been assigned to this relationship, Django will raise
+a ``DoesNotExist`` exception.
+
+Instances can be assigned to the reverse relationship in the same way as
+you would assign the forward relationship::
+
+ e.entrydetail = ed
+
+How are the backward relationships possible?
+--------------------------------------------
+
+Other object-relational mappers require you to define relationships on both
+sides. The Django developers believe this is a violation of the DRY (Don't
+Repeat Yourself) principle, so Django only requires you to define the
+relationship on one end.
+
+But how is this possible, given that a model class doesn't know which other
+model classes are related to it until those other model classes are loaded?
+
+The answer lies in the :setting:`INSTALLED_APPS` setting. The first time any model is
+loaded, Django iterates over every model in :setting:`INSTALLED_APPS` and creates the
+backward relationships in memory as needed. Essentially, one of the functions
+of :setting:`INSTALLED_APPS` is to tell Django the entire model domain.
+
+Queries over related objects
+----------------------------
+
+Queries involving related objects follow the same rules as queries involving
+normal value fields. When specifying the value for a query to match, you may
+use either an object instance itself, or the primary key value for the object.
+
+For example, if you have a Blog object ``b`` with ``id=5``, the following
+three queries would be identical::
+
+ Entry.objects.filter(blog=b) # Query using object instance
+ Entry.objects.filter(blog=b.id) # Query using id from instance
+ Entry.objects.filter(blog=5) # Query using id directly
+
+Falling back to raw SQL
+=======================
+
+If you find yourself needing to write an SQL query that is too complex for
+Django's database-mapper to handle, you can fall back on writing SQL by hand.
+Django has a couple of options for writing raw SQL queries; see
+:doc:`/topics/db/sql`.
+
+Finally, it's important to note that the Django database layer is merely an
+interface to your database. You can access your database via other tools,
+programming languages or database frameworks; there's nothing Django-specific
+about your database.
diff --git a/parts/django/docs/topics/db/sql.txt b/parts/django/docs/topics/db/sql.txt
new file mode 100644
index 0000000..cac9a72
--- /dev/null
+++ b/parts/django/docs/topics/db/sql.txt
@@ -0,0 +1,279 @@
+==========================
+Performing raw SQL queries
+==========================
+
+.. currentmodule:: django.db.models
+
+When the :doc:`model query APIs </topics/db/queries>` don't go far enough, you
+can fall back to writing raw SQL. Django gives you two ways of performing raw
+SQL queries: you can use :meth:`Manager.raw()` to `perform raw queries and
+return model instances`__, or you can avoid the model layer entirely and
+`execute custom SQL directly`__.
+
+__ `performing raw queries`_
+__ `executing custom SQL directly`_
+
+Performing raw queries
+======================
+
+.. versionadded:: 1.2
+
+The ``raw()`` manager method can be used to perform raw SQL queries that
+return model instances:
+
+.. method:: Manager.raw(raw_query, params=None, translations=None)
+
+This method method takes a raw SQL query, executes it, and returns a
+:class:`~django.db.models.query.RawQuerySet` instance. This
+:class:`~django.db.models.query.RawQuerySet` instance can be iterated
+over just like an normal QuerySet to provide object instances.
+
+This is best illustrated with an example. Suppose you've got the following model::
+
+ class Person(models.Model):
+ first_name = models.CharField(...)
+ last_name = models.CharField(...)
+ birth_date = models.DateField(...)
+
+You could then execute custom SQL like so::
+
+ >>> for p in Person.objects.raw('SELECT * FROM myapp_person'):
+ ... print p
+ John Smith
+ Jane Jones
+
+.. admonition:: Model table names
+
+ Where'd the name of the ``Person`` table come from in that example?
+
+ By default, Django figures out a database table name by joining the
+ model's "app label" -- the name you used in ``manage.py startapp`` -- to
+ the model's class name, with an underscore between them. In the example
+ we've assumed that the ``Person`` model lives in an app named ``myapp``,
+ so its table would be ``myapp_person``.
+
+ For more details check out the documentation for the
+ :attr:`~Options.db_table` option, which also lets you manually set the
+ database table name.
+
+Of course, this example isn't very exciting -- it's exactly the same as
+running ``Person.objects.all()``. However, ``raw()`` has a bunch of other
+options that make it very powerful.
+
+Mapping query fields to model fields
+------------------------------------
+
+``raw()`` automatically maps fields in the query to fields on the model.
+
+The order of fields in your query doesn't matter. In other words, both
+of the following queries work identically::
+
+ >>> Person.objects.raw('SELECT id, first_name, last_name, birth_date FROM myapp_person')
+ ...
+ >>> Person.objects.raw('SELECT last_name, birth_date, first_name, id FROM myapp_person')
+ ...
+
+Matching is done by name. This means that you can use SQL's ``AS`` clauses to
+map fields in the query to model fields. So if you had some other table that
+had ``Person`` data in it, you could easily map it into ``Person`` instances::
+
+ >>> Person.objects.raw('''SELECT first AS first_name,
+ ... last AS last_name,
+ ... bd AS birth_date,
+ ... pk as id,
+ ... FROM some_other_table''')
+
+As long as the names match, the model instances will be created correctly.
+
+Alternatively, you can map fields in the query to model fields using the
+``translations`` argument to ``raw()``. This is a dictionary mapping names of
+fields in the query to names of fields on the model. For example, the above
+query could also be written::
+
+ >>> name_map = {'first': 'first_name', 'last': 'last_name', 'bd': 'birth_date', 'pk': 'id'}
+ >>> Person.objects.raw('SELECT * FROM some_other_table', translations=name_map)
+
+Index lookups
+-------------
+
+``raw()`` supports indexing, so if you need only the first result you can
+write::
+
+ >>> first_person = Person.objects.raw('SELECT * from myapp_person')[0]
+
+However, the indexing and slicing are not performed at the database level. If
+you have a big amount of ``Person`` objects in your database, it is more
+efficient to limit the query at the SQL level::
+
+ >>> first_person = Person.objects.raw('SELECT * from myapp_person LIMIT 1')[0]
+
+Deferring model fields
+----------------------
+
+Fields may also be left out::
+
+ >>> people = Person.objects.raw('SELECT id, first_name FROM myapp_person')
+
+The ``Person`` objects returned by this query will be deferred model instances
+(see :meth:`~django.db.models.QuerySet.defer()`). This means that the fields
+that are omitted from the query will be loaded on demand. For example::
+
+ >>> for p in Person.objects.raw('SELECT id, first_name FROM myapp_person'):
+ ... print p.first_name, # This will be retrieved by the original query
+ ... print p.last_name # This will be retrieved on demand
+ ...
+ John Smith
+ Jane Jones
+
+From outward appearances, this looks like the query has retrieved both
+the first name and last name. However, this example actually issued 3
+queries. Only the first names were retrieved by the raw() query -- the
+last names were both retrieved on demand when they were printed.
+
+There is only one field that you can't leave out - the primary key
+field. Django uses the primary key to identify model instances, so it
+must always be included in a raw query. An ``InvalidQuery`` exception
+will be raised if you forget to include the primary key.
+
+Adding annotations
+------------------
+
+You can also execute queries containing fields that aren't defined on the
+model. For example, we could use `PostgreSQL's age() function`__ to get a list
+of people with their ages calculated by the database::
+
+ >>> people = Person.objects.raw('SELECT *, age(birth_date) AS age FROM myapp_person')
+ >>> for p in people:
+ ... print "%s is %s." % (p.first_name, p.age)
+ John is 37.
+ Jane is 42.
+ ...
+
+__ http://www.postgresql.org/docs/8.4/static/functions-datetime.html
+
+Passing parameters into ``raw()``
+---------------------------------
+
+If you need to perform parameterized queries, you can use the ``params``
+argument to ``raw()``::
+
+ >>> lname = 'Doe'
+ >>> Person.objects.raw('SELECT * FROM myapp_person WHERE last_name = %s', [lname])
+
+``params`` is a list of parameters. You'll use ``%s`` placeholders in the
+query string (regardless of your database engine); they'll be replaced with
+parameters from the ``params`` list.
+
+.. warning::
+
+ **Do not use string formatting on raw queries!**
+
+ It's tempting to write the above query as::
+
+ >>> query = 'SELECT * FROM myapp_person WHERE last_name = %s' % lname
+ >>> Person.objects.raw(query)
+
+ **Don't.**
+
+ Using the ``params`` list completely protects you from `SQL injection
+ attacks`__, a common exploit where attackers inject arbitrary SQL into
+ your database. If you use string interpolation, sooner or later you'll
+ fall victim to SQL injection. As long as you remember to always use the
+ ``params`` list you'll be protected.
+
+__ http://en.wikipedia.org/wiki/SQL_injection
+
+Executing custom SQL directly
+=============================
+
+Sometimes even :meth:`Manager.raw` isn't quite enough: you might need to
+perform queries that don't map cleanly to models, or directly execute
+``UPDATE``, ``INSERT``, or ``DELETE`` queries.
+
+In these cases, you can always access the database directly, routing around
+the model layer entirely.
+
+The object ``django.db.connection`` represents the
+default database connection, and ``django.db.transaction`` represents the
+default database transaction. To use the database connection, call
+``connection.cursor()`` to get a cursor object. Then, call
+``cursor.execute(sql, [params])`` to execute the SQL and ``cursor.fetchone()``
+or ``cursor.fetchall()`` to return the resulting rows. After performing a data
+changing operation, you should then call
+``transaction.commit_unless_managed()`` to ensure your changes are committed
+to the database. If your query is purely a data retrieval operation, no commit
+is required. For example::
+
+ def my_custom_sql():
+ from django.db import connection, transaction
+ cursor = connection.cursor()
+
+ # Data modifying operation - commit required
+ cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [self.baz])
+ transaction.commit_unless_managed()
+
+ # Data retrieval operation - no commit required
+ cursor.execute("SELECT foo FROM bar WHERE baz = %s", [self.baz])
+ row = cursor.fetchone()
+
+ return row
+
+If you are using more than one database you can use
+``django.db.connections`` to obtain the connection (and cursor) for a
+specific database. ``django.db.connections`` is a dictionary-like
+object that allows you to retrieve a specific connection using it's
+alias::
+
+ from django.db import connections
+ cursor = connections['my_db_alias'].cursor()
+
+.. _transactions-and-raw-sql:
+
+Transactions and raw SQL
+------------------------
+If you are using transaction decorators (such as ``commit_on_success``) to
+wrap your views and provide transaction control, you don't have to make a
+manual call to ``transaction.commit_unless_managed()`` -- you can manually
+commit if you want to, but you aren't required to, since the decorator will
+commit for you. However, if you don't manually commit your changes, you will
+need to manually mark the transaction as dirty, using
+``transaction.set_dirty()``::
+
+ @commit_on_success
+ def my_custom_sql_view(request, value):
+ from django.db import connection, transaction
+ cursor = connection.cursor()
+
+ # Data modifying operation
+ cursor.execute("UPDATE bar SET foo = 1 WHERE baz = %s", [value])
+
+ # Since we modified data, mark the transaction as dirty
+ transaction.set_dirty()
+
+ # Data retrieval operation. This doesn't dirty the transaction,
+ # so no call to set_dirty() is required.
+ cursor.execute("SELECT foo FROM bar WHERE baz = %s", [value])
+ row = cursor.fetchone()
+
+ return render_to_response('template.html', {'row': row})
+
+The call to ``set_dirty()`` is made automatically when you use the Django ORM
+to make data modifying database calls. However, when you use raw SQL, Django
+has no way of knowing if your SQL modifies data or not. The manual call to
+``set_dirty()`` ensures that Django knows that there are modifications that
+must be committed.
+
+Connections and cursors
+-----------------------
+
+``connection`` and ``cursor`` mostly implement the standard `Python DB-API`_
+(except when it comes to :doc:`transaction handling </topics/db/transactions>`).
+If you're not familiar with the Python DB-API, note that the SQL statement in
+``cursor.execute()`` uses placeholders, ``"%s"``, rather than adding parameters
+directly within the SQL. If you use this technique, the underlying database
+library will automatically add quotes and escaping to your parameter(s) as
+necessary. (Also note that Django expects the ``"%s"`` placeholder, *not* the
+``"?"`` placeholder, which is used by the SQLite Python bindings. This is for
+the sake of consistency and sanity.)
+
+.. _Python DB-API: http://www.python.org/dev/peps/pep-0249/
diff --git a/parts/django/docs/topics/db/transactions.txt b/parts/django/docs/topics/db/transactions.txt
new file mode 100644
index 0000000..be9d9a8
--- /dev/null
+++ b/parts/django/docs/topics/db/transactions.txt
@@ -0,0 +1,328 @@
+==============================
+Managing database transactions
+==============================
+
+.. currentmodule:: django.db
+
+Django gives you a few ways to control how database transactions are managed,
+if you're using a database that supports transactions.
+
+Django's default transaction behavior
+=====================================
+
+Django's default behavior is to run with an open transaction which it
+commits automatically when any built-in, data-altering model function is
+called. For example, if you call ``model.save()`` or ``model.delete()``, the
+change will be committed immediately.
+
+This is much like the auto-commit setting for most databases. As soon as you
+perform an action that needs to write to the database, Django produces the
+``INSERT``/``UPDATE``/``DELETE`` statements and then does the ``COMMIT``.
+There's no implicit ``ROLLBACK``.
+
+Tying transactions to HTTP requests
+===================================
+
+The recommended way to handle transactions in Web requests is to tie them to
+the request and response phases via Django's ``TransactionMiddleware``.
+
+It works like this: When a request starts, Django starts a transaction. If the
+response is produced without problems, Django commits any pending transactions.
+If the view function produces an exception, Django rolls back any pending
+transactions.
+
+To activate this feature, just add the ``TransactionMiddleware`` middleware to
+your :setting:`MIDDLEWARE_CLASSES` setting::
+
+ MIDDLEWARE_CLASSES = (
+ 'django.middleware.cache.UpdateCacheMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ 'django.middleware.transaction.TransactionMiddleware',
+ 'django.middleware.cache.FetchFromCacheMiddleware',
+ )
+
+The order is quite important. The transaction middleware applies not only to
+view functions, but also for all middleware modules that come after it. So if
+you use the session middleware after the transaction middleware, session
+creation will be part of the transaction.
+
+The various cache middlewares are an exception:
+:class:`~django.middleware.cache.CacheMiddleware`,
+:class:`~django.middleware.cache.UpdateCacheMiddleware`, and
+:class:`~django.middleware.cache.FetchFromCacheMiddleware` are never affected.
+Even when using database caching, Django's cache backend uses its own
+database cursor (which is mapped to its own database connection internally).
+
+Controlling transaction management in views
+===========================================
+
+For most people, implicit request-based transactions work wonderfully. However,
+if you need more fine-grained control over how transactions are managed, you
+can use Python decorators to change the way transactions are handled by a
+particular view function. All of the decorators take an option ``using``
+parameter which should be the alias for a database connection for which the
+behavior applies to. If no alias is specified then the ``"default"`` database
+is used.
+
+.. note::
+
+ Although the examples below use view functions as examples, these
+ decorators can be applied to non-view functions as well.
+
+.. _topics-db-transactions-autocommit:
+
+``django.db.transaction.autocommit``
+------------------------------------
+
+Use the ``autocommit`` decorator to switch a view function to Django's default
+commit behavior, regardless of the global transaction setting.
+
+Example::
+
+ from django.db import transaction
+
+ @transaction.autocommit
+ def viewfunc(request):
+ ....
+
+ @transaction.autocommit(using="my_other_database")
+ def viewfunc2(request):
+ ....
+
+Within ``viewfunc()``, transactions will be committed as soon as you call
+``model.save()``, ``model.delete()``, or any other function that writes to the
+database. ``viewfunc2()`` will have this same behavior, but for the
+``"my_other_database"`` connection.
+
+``django.db.transaction.commit_on_success``
+-------------------------------------------
+
+Use the ``commit_on_success`` decorator to use a single transaction for
+all the work done in a function::
+
+ from django.db import transaction
+
+ @transaction.commit_on_success
+ def viewfunc(request):
+ ....
+
+ @transaction.commit_on_success(using="my_other_database")
+ def viewfunc2(request):
+ ....
+
+If the function returns successfully, then Django will commit all work done
+within the function at that point. If the function raises an exception, though,
+Django will roll back the transaction.
+
+``django.db.transaction.commit_manually``
+-----------------------------------------
+
+Use the ``commit_manually`` decorator if you need full control over
+transactions. It tells Django you'll be managing the transaction on your own.
+
+If your view changes data and doesn't ``commit()`` or ``rollback()``, Django
+will raise a ``TransactionManagementError`` exception.
+
+Manual transaction management looks like this::
+
+ from django.db import transaction
+
+ @transaction.commit_manually
+ def viewfunc(request):
+ ...
+ # You can commit/rollback however and whenever you want
+ transaction.commit()
+ ...
+
+ # But you've got to remember to do it yourself!
+ try:
+ ...
+ except:
+ transaction.rollback()
+ else:
+ transaction.commit()
+
+ @transaction.commit_manually(using="my_other_database")
+ def viewfunc2(request):
+ ....
+
+.. admonition:: An important note to users of earlier Django releases:
+
+ The database ``connection.commit()`` and ``connection.rollback()`` methods
+ (called ``db.commit()`` and ``db.rollback()`` in 0.91 and earlier) no
+ longer exist. They've been replaced by ``transaction.commit()`` and
+ ``transaction.rollback()``.
+
+How to globally deactivate transaction management
+=================================================
+
+Control freaks can totally disable all transaction management by setting
+``DISABLE_TRANSACTION_MANAGEMENT`` to ``True`` in the Django settings file.
+
+If you do this, Django won't provide any automatic transaction management
+whatsoever. Middleware will no longer implicitly commit transactions, and
+you'll need to roll management yourself. This even requires you to commit
+changes done by middleware somewhere else.
+
+Thus, this is best used in situations where you want to run your own
+transaction-controlling middleware or do something really strange. In almost
+all situations, you'll be better off using the default behavior, or the
+transaction middleware, and only modify selected functions as needed.
+
+.. _topics-db-transactions-savepoints:
+
+Savepoints
+==========
+
+A savepoint is a marker within a transaction that enables you to roll back
+part of a transaction, rather than the full transaction. Savepoints are
+available to the PostgreSQL 8 and Oracle backends. Other backends will
+provide the savepoint functions, but they are empty operations - they won't
+actually do anything.
+
+Savepoints aren't especially useful if you are using the default
+``autocommit`` behaviour of Django. However, if you are using
+``commit_on_success`` or ``commit_manually``, each open transaction will build
+up a series of database operations, awaiting a commit or rollback. If you
+issue a rollback, the entire transaction is rolled back. Savepoints provide
+the ability to perform a fine-grained rollback, rather than the full rollback
+that would be performed by ``transaction.rollback()``.
+
+Each of these functions takes a ``using`` argument which should be the name of
+a database for which the behavior applies. If no ``using`` argument is
+provided then the ``"default"`` database is used.
+
+Savepoints are controlled by three methods on the transaction object:
+
+.. method:: transaction.savepoint(using=None)
+
+ Creates a new savepoint. This marks a point in the transaction that
+ is known to be in a "good" state.
+
+ Returns the savepoint ID (sid).
+
+.. method:: transaction.savepoint_commit(sid, using=None)
+
+ Updates the savepoint to include any operations that have been performed
+ since the savepoint was created, or since the last commit.
+
+.. method:: transaction.savepoint_rollback(sid, using=None)
+
+ Rolls the transaction back to the last point at which the savepoint was
+ committed.
+
+The following example demonstrates the use of savepoints::
+
+ from django.db import transaction
+
+ @transaction.commit_manually
+ def viewfunc(request):
+
+ a.save()
+ # open transaction now contains a.save()
+ sid = transaction.savepoint()
+
+ b.save()
+ # open transaction now contains a.save() and b.save()
+
+ if want_to_keep_b:
+ transaction.savepoint_commit(sid)
+ # open transaction still contains a.save() and b.save()
+ else:
+ transaction.savepoint_rollback(sid)
+ # open transaction now contains only a.save()
+
+ transaction.commit()
+
+Transactions in MySQL
+=====================
+
+If you're using MySQL, your tables may or may not support transactions; it
+depends on your MySQL version and the table types you're using. (By
+"table types," we mean something like "InnoDB" or "MyISAM".) MySQL transaction
+peculiarities are outside the scope of this article, but the MySQL site has
+`information on MySQL transactions`_.
+
+If your MySQL setup does *not* support transactions, then Django will function
+in auto-commit mode: Statements will be executed and committed as soon as
+they're called. If your MySQL setup *does* support transactions, Django will
+handle transactions as explained in this document.
+
+.. _information on MySQL transactions: http://dev.mysql.com/doc/refman/5.0/en/sql-syntax-transactions.html
+
+Handling exceptions within PostgreSQL transactions
+==================================================
+
+When a call to a PostgreSQL cursor raises an exception (typically
+``IntegrityError``), all subsequent SQL in the same transaction will fail with
+the error "current transaction is aborted, queries ignored until end of
+transaction block". Whilst simple use of ``save()`` is unlikely to raise an
+exception in PostgreSQL, there are more advanced usage patterns which
+might, such as saving objects with unique fields, saving using the
+force_insert/force_update flag, or invoking custom SQL.
+
+There are several ways to recover from this sort of error.
+
+Transaction rollback
+--------------------
+
+The first option is to roll back the entire transaction. For example::
+
+ a.save() # Succeeds, but may be undone by transaction rollback
+ try:
+ b.save() # Could throw exception
+ except IntegrityError:
+ transaction.rollback()
+ c.save() # Succeeds, but a.save() may have been undone
+
+Calling ``transaction.rollback()`` rolls back the entire transaction. Any
+uncommitted database operations will be lost. In this example, the changes
+made by ``a.save()`` would be lost, even though that operation raised no error
+itself.
+
+Savepoint rollback
+------------------
+
+If you are using PostgreSQL 8 or later, you can use :ref:`savepoints
+<topics-db-transactions-savepoints>` to control the extent of a rollback.
+Before performing a database operation that could fail, you can set or update
+the savepoint; that way, if the operation fails, you can roll back the single
+offending operation, rather than the entire transaction. For example::
+
+ a.save() # Succeeds, and never undone by savepoint rollback
+ try:
+ sid = transaction.savepoint()
+ b.save() # Could throw exception
+ transaction.savepoint_commit(sid)
+ except IntegrityError:
+ transaction.savepoint_rollback(sid)
+ c.save() # Succeeds, and a.save() is never undone
+
+In this example, ``a.save()`` will not be undone in the case where
+``b.save()`` raises an exception.
+
+Database-level autocommit
+-------------------------
+
+.. versionadded:: 1.1
+
+With PostgreSQL 8.2 or later, there is an advanced option to run PostgreSQL
+with :doc:`database-level autocommit </ref/databases>`. If you use this option,
+there is no constantly open transaction, so it is always possible to continue
+after catching an exception. For example::
+
+ a.save() # succeeds
+ try:
+ b.save() # Could throw exception
+ except IntegrityError:
+ pass
+ c.save() # succeeds
+
+.. note::
+
+ This is not the same as the :ref:`autocommit decorator
+ <topics-db-transactions-autocommit>`. When using database level autocommit
+ there is no database transaction at all. The ``autocommit`` decorator
+ still uses transactions, automatically committing each transaction when
+ a database modifying operation occurs.
diff --git a/parts/django/docs/topics/email.txt b/parts/django/docs/topics/email.txt
new file mode 100644
index 0000000..36bebfb
--- /dev/null
+++ b/parts/django/docs/topics/email.txt
@@ -0,0 +1,618 @@
+==============
+Sending e-mail
+==============
+
+.. module:: django.core.mail
+ :synopsis: Helpers to easily send e-mail.
+
+Although Python makes sending e-mail relatively easy via the `smtplib
+library`_, Django provides a couple of light wrappers over it. These wrappers
+are provided to make sending e-mail extra quick, to make it easy to test
+e-mail sending during development, and to provide support for platforms that
+can't use SMTP.
+
+The code lives in the ``django.core.mail`` module.
+
+.. _smtplib library: http://docs.python.org/library/smtplib.html
+
+Quick example
+=============
+
+In two lines::
+
+ from django.core.mail import send_mail
+
+ send_mail('Subject here', 'Here is the message.', 'from@example.com',
+ ['to@example.com'], fail_silently=False)
+
+Mail is sent using the SMTP host and port specified in the
+:setting:`EMAIL_HOST` and :setting:`EMAIL_PORT` settings. The
+:setting:`EMAIL_HOST_USER` and :setting:`EMAIL_HOST_PASSWORD` settings, if
+set, are used to authenticate to the SMTP server, and the
+:setting:`EMAIL_USE_TLS` setting controls whether a secure connection is used.
+
+.. note::
+
+ The character set of e-mail sent with ``django.core.mail`` will be set to
+ the value of your :setting:`DEFAULT_CHARSET` setting.
+
+send_mail()
+===========
+
+.. function:: send_mail(subject, message, from_email, recipient_list, fail_silently=False, auth_user=None, auth_password=None, connection=None)
+
+The simplest way to send e-mail is using
+``django.core.mail.send_mail()``.
+
+The ``subject``, ``message``, ``from_email`` and ``recipient_list`` parameters
+are required.
+
+ * ``subject``: A string.
+ * ``message``: A string.
+ * ``from_email``: A string.
+ * ``recipient_list``: A list of strings, each an e-mail address. Each
+ member of ``recipient_list`` will see the other recipients in the "To:"
+ field of the e-mail message.
+ * ``fail_silently``: A boolean. If it's ``False``, ``send_mail`` will raise
+ an ``smtplib.SMTPException``. See the `smtplib docs`_ for a list of
+ possible exceptions, all of which are subclasses of ``SMTPException``.
+ * ``auth_user``: The optional username to use to authenticate to the SMTP
+ server. If this isn't provided, Django will use the value of the
+ :setting:`EMAIL_HOST_USER` setting.
+ * ``auth_password``: The optional password to use to authenticate to the
+ SMTP server. If this isn't provided, Django will use the value of the
+ :setting:`EMAIL_HOST_PASSWORD` setting.
+ * ``connection``: The optional e-mail backend to use to send the mail.
+ If unspecified, an instance of the default backend will be used.
+ See the documentation on :ref:`E-mail backends <topic-email-backends>`
+ for more details.
+
+.. _smtplib docs: http://docs.python.org/library/smtplib.html
+
+send_mass_mail()
+================
+
+.. function:: send_mass_mail(datatuple, fail_silently=False, auth_user=None, auth_password=None, connection=None)
+
+``django.core.mail.send_mass_mail()`` is intended to handle mass e-mailing.
+
+``datatuple`` is a tuple in which each element is in this format::
+
+ (subject, message, from_email, recipient_list)
+
+``fail_silently``, ``auth_user`` and ``auth_password`` have the same functions
+as in :meth:`~django.core.mail.send_mail()`.
+
+Each separate element of ``datatuple`` results in a separate e-mail message.
+As in :meth:`~django.core.mail.send_mail()`, recipients in the same
+``recipient_list`` will all see the other addresses in the e-mail messages'
+"To:" field.
+
+For example, the following code would send two different messages to
+two different sets of recipients; however, only one connection to the
+mail server would be opened::
+
+ message1 = ('Subject here', 'Here is the message', 'from@example.com, ['first@example.com', 'other@example.com'])
+ message2 = ('Another Subject', 'Here is another message', 'from@example.com', ['second@test.com'])
+ send_mass_mail((message1, message2), fail_silently=False)
+
+send_mass_mail() vs. send_mail()
+--------------------------------
+
+The main difference between :meth:`~django.core.mail.send_mass_mail()` and
+:meth:`~django.core.mail.send_mail()` is that
+:meth:`~django.core.mail.send_mail()` opens a connection to the mail server
+each time it's executed, while :meth:`~django.core.mail.send_mass_mail()` uses
+a single connection for all of its messages. This makes
+:meth:`~django.core.mail.send_mass_mail()` slightly more efficient.
+
+mail_admins()
+=============
+
+.. function:: mail_admins(subject, message, fail_silently=False, connection=None)
+
+``django.core.mail.mail_admins()`` is a shortcut for sending an e-mail to the
+site admins, as defined in the :setting:`ADMINS` setting.
+
+``mail_admins()`` prefixes the subject with the value of the
+:setting:`EMAIL_SUBJECT_PREFIX` setting, which is ``"[Django] "`` by default.
+
+The "From:" header of the e-mail will be the value of the
+:setting:`SERVER_EMAIL` setting.
+
+This method exists for convenience and readability.
+
+mail_managers()
+===============
+
+.. function:: mail_managers(subject, message, fail_silently=False, connection=None)
+
+``django.core.mail.mail_managers()`` is just like ``mail_admins()``, except it
+sends an e-mail to the site managers, as defined in the :setting:`MANAGERS`
+setting.
+
+Examples
+========
+
+This sends a single e-mail to john@example.com and jane@example.com, with them
+both appearing in the "To:"::
+
+ send_mail('Subject', 'Message.', 'from@example.com',
+ ['john@example.com', 'jane@example.com'])
+
+This sends a message to john@example.com and jane@example.com, with them both
+receiving a separate e-mail::
+
+ datatuple = (
+ ('Subject', 'Message.', 'from@example.com', ['john@example.com']),
+ ('Subject', 'Message.', 'from@example.com', ['jane@example.com']),
+ )
+ send_mass_mail(datatuple)
+
+Preventing header injection
+===========================
+
+`Header injection`_ is a security exploit in which an attacker inserts extra
+e-mail headers to control the "To:" and "From:" in e-mail messages that your
+scripts generate.
+
+The Django e-mail functions outlined above all protect against header injection
+by forbidding newlines in header values. If any ``subject``, ``from_email`` or
+``recipient_list`` contains a newline (in either Unix, Windows or Mac style),
+the e-mail function (e.g. :meth:`~django.core.mail.send_mail()`) will raise
+``django.core.mail.BadHeaderError`` (a subclass of ``ValueError``) and, hence,
+will not send the e-mail. It's your responsibility to validate all data before
+passing it to the e-mail functions.
+
+If a ``message`` contains headers at the start of the string, the headers will
+simply be printed as the first bit of the e-mail message.
+
+Here's an example view that takes a ``subject``, ``message`` and ``from_email``
+from the request's POST data, sends that to admin@example.com and redirects to
+"/contact/thanks/" when it's done::
+
+ from django.core.mail import send_mail, BadHeaderError
+
+ def send_email(request):
+ subject = request.POST.get('subject', '')
+ message = request.POST.get('message', '')
+ from_email = request.POST.get('from_email', '')
+ if subject and message and from_email:
+ try:
+ send_mail(subject, message, from_email, ['admin@example.com'])
+ except BadHeaderError:
+ return HttpResponse('Invalid header found.')
+ return HttpResponseRedirect('/contact/thanks/')
+ else:
+ # In reality we'd use a form class
+ # to get proper validation errors.
+ return HttpResponse('Make sure all fields are entered and valid.')
+
+.. _Header injection: http://www.nyphp.org/phundamentals/email_header_injection.php
+
+.. _emailmessage-and-smtpconnection:
+
+The EmailMessage class
+======================
+
+.. versionadded:: 1.0
+
+Django's :meth:`~django.core.mail.send_mail()` and
+:meth:`~django.core.mail.send_mass_mail()` functions are actually thin
+wrappers that make use of the :class:`~django.core.mail.EmailMessage` class.
+
+Not all features of the :class:`~django.core.mail.EmailMessage` class are
+available through the :meth:`~django.core.mail.send_mail()` and related
+wrapper functions. If you wish to use advanced features, such as BCC'ed
+recipients, file attachments, or multi-part e-mail, you'll need to create
+:class:`~django.core.mail.EmailMessage` instances directly.
+
+.. note::
+ This is a design feature. :meth:`~django.core.mail.send_mail()` and
+ related functions were originally the only interface Django provided.
+ However, the list of parameters they accepted was slowly growing over
+ time. It made sense to move to a more object-oriented design for e-mail
+ messages and retain the original functions only for backwards
+ compatibility.
+
+:class:`~django.core.mail.EmailMessage` is responsible for creating the e-mail
+message itself. The :ref:`e-mail backend <topic-email-backends>` is then
+responsible for sending the e-mail.
+
+For convenience, :class:`~django.core.mail.EmailMessage` provides a simple
+``send()`` method for sending a single e-mail. If you need to send multiple
+messages, the e-mail backend API :ref:`provides an alternative
+<topics-sending-multiple-emails>`.
+
+EmailMessage Objects
+--------------------
+
+.. class:: EmailMessage
+
+The :class:`~django.core.mail.EmailMessage` class is initialized with the
+following parameters (in the given order, if positional arguments are used).
+All parameters are optional and can be set at any time prior to calling the
+``send()`` method.
+
+ * ``subject``: The subject line of the e-mail.
+
+ * ``body``: The body text. This should be a plain text message.
+
+ * ``from_email``: The sender's address. Both ``fred@example.com`` and
+ ``Fred <fred@example.com>`` forms are legal. If omitted, the
+ :setting:`DEFAULT_FROM_EMAIL` setting is used.
+
+ * ``to``: A list or tuple of recipient addresses.
+
+ * ``bcc``: A list or tuple of addresses used in the "Bcc" header when
+ sending the e-mail.
+
+ * ``connection``: An e-mail backend instance. Use this parameter if
+ you want to use the same connection for multiple messages. If omitted, a
+ new connection is created when ``send()`` is called.
+
+ * ``attachments``: A list of attachments to put on the message. These can
+ be either ``email.MIMEBase.MIMEBase`` instances, or ``(filename,
+ content, mimetype)`` triples.
+
+ * ``headers``: A dictionary of extra headers to put on the message. The
+ keys are the header name, values are the header values. It's up to the
+ caller to ensure header names and values are in the correct format for
+ an e-mail message.
+
+For example::
+
+ email = EmailMessage('Hello', 'Body goes here', 'from@example.com',
+ ['to1@example.com', 'to2@example.com'], ['bcc@example.com'],
+ headers = {'Reply-To': 'another@example.com'})
+
+The class has the following methods:
+
+ * ``send(fail_silently=False)`` sends the message. If a connection was
+ specified when the e-mail was constructed, that connection will be used.
+ Otherwise, an instance of the default backend will be instantiated and
+ used. If the keyword argument ``fail_silently`` is ``True``, exceptions
+ raised while sending the message will be quashed.
+
+ * ``message()`` constructs a ``django.core.mail.SafeMIMEText`` object (a
+ subclass of Python's ``email.MIMEText.MIMEText`` class) or a
+ ``django.core.mail.SafeMIMEMultipart`` object holding the message to be
+ sent. If you ever need to extend the
+ :class:`~django.core.mail.EmailMessage` class, you'll probably want to
+ override this method to put the content you want into the MIME object.
+
+ * ``recipients()`` returns a list of all the recipients of the message,
+ whether they're recorded in the ``to`` or ``bcc`` attributes. This is
+ another method you might need to override when subclassing, because the
+ SMTP server needs to be told the full list of recipients when the message
+ is sent. If you add another way to specify recipients in your class, they
+ need to be returned from this method as well.
+
+ * ``attach()`` creates a new file attachment and adds it to the message.
+ There are two ways to call ``attach()``:
+
+ * You can pass it a single argument that is an
+ ``email.MIMEBase.MIMEBase`` instance. This will be inserted directly
+ into the resulting message.
+
+ * Alternatively, you can pass ``attach()`` three arguments:
+ ``filename``, ``content`` and ``mimetype``. ``filename`` is the name
+ of the file attachment as it will appear in the e-mail, ``content`` is
+ the data that will be contained inside the attachment and
+ ``mimetype`` is the optional MIME type for the attachment. If you
+ omit ``mimetype``, the MIME content type will be guessed from the
+ filename of the attachment.
+
+ For example::
+
+ message.attach('design.png', img_data, 'image/png')
+
+ * ``attach_file()`` creates a new attachment using a file from your
+ filesystem. Call it with the path of the file to attach and, optionally,
+ the MIME type to use for the attachment. If the MIME type is omitted, it
+ will be guessed from the filename. The simplest use would be::
+
+ message.attach_file('/images/weather_map.png')
+
+.. _DEFAULT_FROM_EMAIL: ../settings/#default-from-email
+
+Sending alternative content types
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It can be useful to include multiple versions of the content in an e-mail; the
+classic example is to send both text and HTML versions of a message. With
+Django's e-mail library, you can do this using the ``EmailMultiAlternatives``
+class. This subclass of :class:`~django.core.mail.EmailMessage` has an
+``attach_alternative()`` method for including extra versions of the message
+body in the e-mail. All the other methods (including the class initialization)
+are inherited directly from :class:`~django.core.mail.EmailMessage`.
+
+To send a text and HTML combination, you could write::
+
+ from django.core.mail import EmailMultiAlternatives
+
+ subject, from_email, to = 'hello', 'from@example.com', 'to@example.com'
+ text_content = 'This is an important message.'
+ html_content = '<p>This is an <strong>important</strong> message.</p>'
+ msg = EmailMultiAlternatives(subject, text_content, from_email, [to])
+ msg.attach_alternative(html_content, "text/html")
+ msg.send()
+
+By default, the MIME type of the ``body`` parameter in an
+:class:`~django.core.mail.EmailMessage` is ``"text/plain"``. It is good
+practice to leave this alone, because it guarantees that any recipient will be
+able to read the e-mail, regardless of their mail client. However, if you are
+confident that your recipients can handle an alternative content type, you can
+use the ``content_subtype`` attribute on the
+:class:`~django.core.mail.EmailMessage` class to change the main content type.
+The major type will always be ``"text"``, but you can change the
+subtype. For example::
+
+ msg = EmailMessage(subject, html_content, from_email, [to])
+ msg.content_subtype = "html" # Main content is now text/html
+ msg.send()
+
+.. _topic-email-backends:
+
+E-Mail Backends
+===============
+
+.. versionadded:: 1.2
+
+The actual sending of an e-mail is handled by the e-mail backend.
+
+The e-mail backend class has the following methods:
+
+ * ``open()`` instantiates an long-lived e-mail-sending connection.
+
+ * ``close()`` closes the current e-mail-sending connection.
+
+ * ``send_messages(email_messages)`` sends a list of
+ :class:`~django.core.mail.EmailMessage` objects. If the connection is
+ not open, this call will implicitly open the connection, and close the
+ connection afterwards. If the connection is already open, it will be
+ left open after mail has been sent.
+
+Obtaining an instance of an e-mail backend
+------------------------------------------
+
+The :meth:`get_connection` function in ``django.core.mail`` returns an
+instance of the e-mail backend that you can use.
+
+.. currentmodule:: django.core.mail
+
+.. function:: get_connection(backend=None, fail_silently=False, *args, **kwargs)
+
+By default, a call to ``get_connection()`` will return an instance of the
+e-mail backend specified in :setting:`EMAIL_BACKEND`. If you specify the
+``backend`` argument, an instance of that backend will be instantiated.
+
+The ``fail_silently`` argument controls how the backend should handle errors.
+If ``fail_silently`` is True, exceptions during the e-mail sending process
+will be silently ignored.
+
+All other arguments are passed directly to the constructor of the
+e-mail backend.
+
+Django ships with several e-mail sending backends. With the exception of the
+SMTP backend (which is the default), these backends are only useful during
+testing and development. If you have special e-mail sending requirements, you
+can :ref:`write your own e-mail backend <topic-custom-email-backend>`.
+
+.. _topic-email-smtp-backend:
+
+SMTP backend
+~~~~~~~~~~~~
+
+This is the default backend. E-mail will be sent through a SMTP server.
+The server address and authentication credentials are set in the
+:setting:`EMAIL_HOST`, :setting:`EMAIL_PORT`, :setting:`EMAIL_HOST_USER`,
+:setting:`EMAIL_HOST_PASSWORD` and :setting:`EMAIL_USE_TLS` settings in your
+settings file.
+
+The SMTP backend is the default configuration inherited by Django. If you
+want to specify it explicitly, put the following in your settings::
+
+ EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
+
+.. admonition:: SMTPConnection objects
+
+ Prior to version 1.2, Django provided a
+ :class:`~django.core.mail.SMTPConnection` class. This class provided a way
+ to directly control the use of SMTP to send e-mail. This class has been
+ deprecated in favor of the generic e-mail backend API.
+
+ For backwards compatibility :class:`~django.core.mail.SMTPConnection` is
+ still available in ``django.core.mail`` as an alias for the SMTP backend.
+ New code should use :meth:`~django.core.mail.get_connection` instead.
+
+.. _topic-email-console-backend:
+
+Console backend
+~~~~~~~~~~~~~~~
+
+Instead of sending out real e-mails the console backend just writes the
+e-mails that would be send to the standard output. By default, the console
+backend writes to ``stdout``. You can use a different stream-like object by
+providing the ``stream`` keyword argument when constructing the connection.
+
+To specify this backend, put the following in your settings::
+
+ EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
+
+This backend is not intended for use in production -- it is provided as a
+convenience that can be used during development.
+
+.. _topic-email-file-backend:
+
+File backend
+~~~~~~~~~~~~
+
+The file backend writes e-mails to a file. A new file is created for each new
+session that is opened on this backend. The directory to which the files are
+written is either taken from the :setting:`EMAIL_FILE_PATH` setting or from
+the ``file_path`` keyword when creating a connection with
+:meth:`~django.core.mail.get_connection`.
+
+To specify this backend, put the following in your settings::
+
+ EMAIL_BACKEND = 'django.core.mail.backends.filebased.EmailBackend'
+ EMAIL_FILE_PATH = '/tmp/app-messages' # change this to a proper location
+
+This backend is not intended for use in production -- it is provided as a
+convenience that can be used during development.
+
+.. _topic-email-memory-backend:
+
+In-memory backend
+~~~~~~~~~~~~~~~~~
+
+The ``'locmem'`` backend stores messages in a special attribute of the
+``django.core.mail`` module. The ``outbox`` attribute is created when the
+first message is sent. It's a list with an
+:class:`~django.core.mail.EmailMessage` instance for each message that would
+be send.
+
+To specify this backend, put the following in your settings::
+
+ EMAIL_BACKEND = 'django.core.mail.backends.locmem.EmailBackend'
+
+This backend is not intended for use in production -- it is provided as a
+convenience that can be used during development and testing.
+
+.. _topic-email-dummy-backend:
+
+Dummy backend
+~~~~~~~~~~~~~
+
+As the name suggests the dummy backend does nothing with your messages. To
+specify this backend, put the following in your settings::
+
+ EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
+
+This backend is not intended for use in production -- it is provided as a
+convenience that can be used during development.
+
+.. _topic-custom-email-backend:
+
+Defining a custom e-mail backend
+--------------------------------
+
+If you need to change how e-mails are sent you can write your own e-mail
+backend. The ``EMAIL_BACKEND`` setting in your settings file is then the
+Python import path for your backend class.
+
+Custom e-mail backends should subclass ``BaseEmailBackend`` that is located in
+the ``django.core.mail.backends.base`` module. A custom e-mail backend must
+implement the ``send_messages(email_messages)`` method. This method receives a
+list of :class:`~django.core.mail.EmailMessage` instances and returns the
+number of successfully delivered messages. If your backend has any concept of
+a persistent session or connection, you should also implement the ``open()``
+and ``close()`` methods. Refer to ``smtp.EmailBackend`` for a reference
+implementation.
+
+.. _topics-sending-multiple-emails:
+
+Sending multiple e-mails
+------------------------
+
+Establishing and closing an SMTP connection (or any other network connection,
+for that matter) is an expensive process. If you have a lot of e-mails to send,
+it makes sense to reuse an SMTP connection, rather than creating and
+destroying a connection every time you want to send an e-mail.
+
+There are two ways you tell an e-mail backend to reuse a connection.
+
+Firstly, you can use the ``send_messages()`` method. ``send_messages()`` takes
+a list of :class:`~django.core.mail.EmailMessage` instances (or subclasses),
+and sends them all using a single connection.
+
+For example, if you have a function called ``get_notification_email()`` that
+returns a list of :class:`~django.core.mail.EmailMessage` objects representing
+some periodic e-mail you wish to send out, you could send these e-mails using
+a single call to send_messages::
+
+ from django.core import mail
+ connection = mail.get_connection() # Use default e-mail connection
+ messages = get_notification_email()
+ connection.send_messages(messages)
+
+In this example, the call to ``send_messages()`` opens a connection on the
+backend, sends the list of messages, and then closes the connection again.
+
+The second approach is to use the ``open()`` and ``close()`` methods on the
+e-mail backend to manually control the connection. ``send_messages()`` will not
+manually open or close the connection if it is already open, so if you
+manually open the connection, you can control when it is closed. For example::
+
+ from django.core import mail
+ connection = mail.get_connection()
+
+ # Manually open the connection
+ connection.open()
+
+ # Construct an e-mail message that uses the connection
+ email1 = mail.EmailMessage('Hello', 'Body goes here', 'from@example.com',
+ ['to1@example.com'], connection=connection)
+ email1.send() # Send the e-mail
+
+ # Construct two more messages
+ email2 = mail.EmailMessage('Hello', 'Body goes here', 'from@example.com',
+ ['to2@example.com'])
+ email3 = mail.EmailMessage('Hello', 'Body goes here', 'from@example.com',
+ ['to3@example.com'])
+
+ # Send the two e-mails in a single call -
+ connection.send_messages([email2, email3])
+ # The connection was already open so send_messages() doesn't close it.
+ # We need to manually close the connection.
+ connection.close()
+
+
+Testing e-mail sending
+======================
+
+There are times when you do not want Django to send e-mails at
+all. For example, while developing a Web site, you probably don't want
+to send out thousands of e-mails -- but you may want to validate that
+e-mails will be sent to the right people under the right conditions,
+and that those e-mails will contain the correct content.
+
+The easiest way to test your project's use of e-mail is to use the ``console``
+e-mail backend. This backend redirects all e-mail to stdout, allowing you to
+inspect the content of mail.
+
+The ``file`` e-mail backend can also be useful during development -- this backend
+dumps the contents of every SMTP connection to a file that can be inspected
+at your leisure.
+
+Another approach is to use a "dumb" SMTP server that receives the e-mails
+locally and displays them to the terminal, but does not actually send
+anything. Python has a built-in way to accomplish this with a single command::
+
+ python -m smtpd -n -c DebuggingServer localhost:1025
+
+This command will start a simple SMTP server listening on port 1025 of
+localhost. This server simply prints to standard output all e-mail headers and
+the e-mail body. You then only need to set the :setting:`EMAIL_HOST` and
+:setting:`EMAIL_PORT` accordingly, and you are set.
+
+For a more detailed discussion of testing and processing of e-mails locally,
+see the Python documentation on the `SMTP Server`_.
+
+.. _SMTP Server: http://docs.python.org/library/smtpd.html
+
+SMTPConnection
+==============
+
+.. class:: SMTPConnection
+
+.. deprecated:: 1.2
+
+The ``SMTPConnection`` class has been deprecated in favor of the generic e-mail
+backend API.
+
+For backwards compatibility ``SMTPConnection`` is still available in
+``django.core.mail`` as an alias for the :ref:`SMTP backend
+<topic-email-smtp-backend>`. New code should use
+:meth:`~django.core.mail.get_connection` instead.
diff --git a/parts/django/docs/topics/files.txt b/parts/django/docs/topics/files.txt
new file mode 100644
index 0000000..d1926c6
--- /dev/null
+++ b/parts/django/docs/topics/files.txt
@@ -0,0 +1,147 @@
+==============
+Managing files
+==============
+
+.. versionadded:: 1.0
+
+This document describes Django's file access APIs.
+
+By default, Django stores files locally, using the :setting:`MEDIA_ROOT` and
+:setting:`MEDIA_URL` settings. The examples below assume that you're using these
+defaults.
+
+However, Django provides ways to write custom `file storage systems`_ that
+allow you to completely customize where and how Django stores files. The
+second half of this document describes how these storage systems work.
+
+.. _file storage systems: `File storage`_
+
+Using files in models
+=====================
+
+When you use a :class:`~django.db.models.FileField` or
+:class:`~django.db.models.ImageField`, Django provides a set of APIs you can use
+to deal with that file.
+
+Consider the following model, using an :class:`~django.db.models.ImageField` to
+store a photo::
+
+ class Car(models.Model):
+ name = models.CharField(max_length=255)
+ price = models.DecimalField(max_digits=5, decimal_places=2)
+ photo = models.ImageField(upload_to='cars')
+
+Any ``Car`` instance will have a ``photo`` attribute that you can use to get at
+the details of the attached photo::
+
+ >>> car = Car.objects.get(name="57 Chevy")
+ >>> car.photo
+ <ImageFieldFile: chevy.jpg>
+ >>> car.photo.name
+ u'cars/chevy.jpg'
+ >>> car.photo.path
+ u'/media/cars/chevy.jpg'
+ >>> car.photo.url
+ u'http://media.example.com/cars/chevy.jpg'
+
+This object -- ``car.photo`` in the example -- is a ``File`` object, which means
+it has all the methods and attributes described below.
+
+The ``File`` object
+===================
+
+Internally, Django uses a :class:`django.core.files.File` instance any time it
+needs to represent a file. This object is a thin wrapper around Python's
+`built-in file object`_ with some Django-specific additions.
+
+.. _built-in file object: http://docs.python.org/library/stdtypes.html#bltin-file-objects
+
+Most of the time you'll simply use a ``File`` that Django's given you (i.e. a
+file attached to a model as above, or perhaps an uploaded file).
+
+If you need to construct a ``File`` yourself, the easiest way is to create one
+using a Python built-in ``file`` object::
+
+ >>> from django.core.files import File
+
+ # Create a Python file object using open()
+ >>> f = open('/tmp/hello.world', 'w')
+ >>> myfile = File(f)
+
+Now you can use any of the documented attributes and methods
+of the :class:`~django.core.files.File` class.
+
+File storage
+============
+
+Behind the scenes, Django delegates decisions about how and where to store files
+to a file storage system. This is the object that actually understands things
+like file systems, opening and reading files, etc.
+
+Django's default file storage is given by the :setting:`DEFAULT_FILE_STORAGE`
+setting; if you don't explicitly provide a storage system, this is the one that
+will be used.
+
+See below for details of the built-in default file storage system, and see
+:doc:`/howto/custom-file-storage` for information on writing your own file
+storage system.
+
+Storage objects
+---------------
+
+Though most of the time you'll want to use a ``File`` object (which delegates to
+the proper storage for that file), you can use file storage systems directly.
+You can create an instance of some custom file storage class, or -- often more
+useful -- you can use the global default storage system::
+
+ >>> from django.core.files.storage import default_storage
+ >>> from django.core.files.base import ContentFile
+
+ >>> path = default_storage.save('/path/to/file', ContentFile('new content'))
+ >>> path
+ u'/path/to/file'
+
+ >>> default_storage.size(path)
+ 11
+ >>> default_storage.open(path).read()
+ 'new content'
+
+ >>> default_storage.delete(path)
+ >>> default_storage.exists(path)
+ False
+
+See :doc:`/ref/files/storage` for the file storage API.
+
+The built-in filesystem storage class
+-------------------------------------
+
+Django ships with a built-in ``FileSystemStorage`` class (defined in
+``django.core.files.storage``) which implements basic local filesystem file
+storage. Its initializer takes two arguments:
+
+====================== ===================================================
+Argument Description
+====================== ===================================================
+``location`` Optional. Absolute path to the directory that will
+ hold the files. If omitted, it will be set to the
+ value of your :setting:`MEDIA_ROOT` setting.
+``base_url`` Optional. URL that serves the files stored at this
+ location. If omitted, it will default to the value
+ of your :setting:`MEDIA_URL` setting.
+====================== ===================================================
+
+For example, the following code will store uploaded files under
+``/media/photos`` regardless of what your :setting:`MEDIA_ROOT` setting is::
+
+ from django.db import models
+ from django.core.files.storage import FileSystemStorage
+
+ fs = FileSystemStorage(location='/media/photos')
+
+ class Car(models.Model):
+ ...
+ photo = models.ImageField(storage=fs)
+
+:doc:`Custom storage systems </howto/custom-file-storage>` work the same way:
+you can pass them in as the ``storage`` argument to a
+:class:`~django.db.models.FileField`.
diff --git a/parts/django/docs/topics/forms/formsets.txt b/parts/django/docs/topics/forms/formsets.txt
new file mode 100644
index 0000000..72296bc
--- /dev/null
+++ b/parts/django/docs/topics/forms/formsets.txt
@@ -0,0 +1,440 @@
+.. _formsets:
+
+Formsets
+========
+
+A formset is a layer of abstraction to working with multiple forms on the same
+page. It can be best compared to a data grid. Let's say you have the following
+form::
+
+ >>> from django import forms
+ >>> class ArticleForm(forms.Form):
+ ... title = forms.CharField()
+ ... pub_date = forms.DateField()
+
+You might want to allow the user to create several articles at once. To create
+a formset out of an ``ArticleForm`` you would do::
+
+ >>> from django.forms.formsets import formset_factory
+ >>> ArticleFormSet = formset_factory(ArticleForm)
+
+You now have created a formset named ``ArticleFormSet``. The formset gives you
+the ability to iterate over the forms in the formset and display them as you
+would with a regular form::
+
+ >>> formset = ArticleFormSet()
+ >>> for form in formset.forms:
+ ... print form.as_table()
+ <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" id="id_form-0-title" /></td></tr>
+ <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" id="id_form-0-pub_date" /></td></tr>
+
+As you can see it only displayed one empty form. The number of empty forms
+that is displayed is controlled by the ``extra`` parameter. By default,
+``formset_factory`` defines one extra form; the following example will
+display two blank forms::
+
+ >>> ArticleFormSet = formset_factory(ArticleForm, extra=2)
+
+Using initial data with a formset
+---------------------------------
+
+Initial data is what drives the main usability of a formset. As shown above
+you can define the number of extra forms. What this means is that you are
+telling the formset how many additional forms to show in addition to the
+number of forms it generates from the initial data. Lets take a look at an
+example::
+
+ >>> ArticleFormSet = formset_factory(ArticleForm, extra=2)
+ >>> formset = ArticleFormSet(initial=[
+ ... {'title': u'Django is now open source',
+ ... 'pub_date': datetime.date.today()},
+ ... ])
+
+ >>> for form in formset.forms:
+ ... print form.as_table()
+ <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" value="Django is now open source" id="id_form-0-title" /></td></tr>
+ <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" value="2008-05-12" id="id_form-0-pub_date" /></td></tr>
+ <tr><th><label for="id_form-1-title">Title:</label></th><td><input type="text" name="form-1-title" id="id_form-1-title" /></td></tr>
+ <tr><th><label for="id_form-1-pub_date">Pub date:</label></th><td><input type="text" name="form-1-pub_date" id="id_form-1-pub_date" /></td></tr>
+ <tr><th><label for="id_form-2-title">Title:</label></th><td><input type="text" name="form-2-title" id="id_form-2-title" /></td></tr>
+ <tr><th><label for="id_form-2-pub_date">Pub date:</label></th><td><input type="text" name="form-2-pub_date" id="id_form-2-pub_date" /></td></tr>
+
+There are now a total of three forms showing above. One for the initial data
+that was passed in and two extra forms. Also note that we are passing in a
+list of dictionaries as the initial data.
+
+.. seealso::
+
+ :ref:`Creating formsets from models with model formsets <model-formsets>`.
+
+.. _formsets-max-num:
+
+Limiting the maximum number of forms
+------------------------------------
+
+The ``max_num`` parameter to ``formset_factory`` gives you the ability to
+limit the maximum number of empty forms the formset will display::
+
+ >>> ArticleFormSet = formset_factory(ArticleForm, extra=2, max_num=1)
+ >>> formset = ArticleFormset()
+ >>> for form in formset.forms:
+ ... print form.as_table()
+ <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" id="id_form-0-title" /></td></tr>
+ <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" id="id_form-0-pub_date" /></td></tr>
+
+.. versionchanged:: 1.2
+
+If the value of ``max_num`` is greater than the number of existing
+objects, up to ``extra`` additional blank forms will be added to the formset,
+so long as the total number of forms does not exceed ``max_num``.
+
+A ``max_num`` value of ``None`` (the default) puts no limit on the number of
+forms displayed. Please note that the default value of ``max_num`` was changed
+from ``0`` to ``None`` in version 1.2 to allow ``0`` as a valid value.
+
+Formset validation
+------------------
+
+Validation with a formset is almost identical to a regular ``Form``. There is
+an ``is_valid`` method on the formset to provide a convenient way to validate
+all forms in the formset::
+
+ >>> ArticleFormSet = formset_factory(ArticleForm)
+ >>> formset = ArticleFormSet({})
+ >>> formset.is_valid()
+ True
+
+We passed in no data to the formset which is resulting in a valid form. The
+formset is smart enough to ignore extra forms that were not changed. If we
+provide an invalid article::
+
+ >>> data = {
+ ... 'form-TOTAL_FORMS': u'2',
+ ... 'form-INITIAL_FORMS': u'0',
+ ... 'form-MAX_NUM_FORMS': u'',
+ ... 'form-0-title': u'Test',
+ ... 'form-0-pub_date': u'16 June 1904',
+ ... 'form-1-title': u'Test',
+ ... 'form-1-pub_date': u'', # <-- this date is missing but required
+ ... }
+ >>> formset = ArticleFormSet(data)
+ >>> formset.is_valid()
+ False
+ >>> formset.errors
+ [{}, {'pub_date': [u'This field is required.']}]
+
+As we can see, ``formset.errors`` is a list whose entries correspond to the
+forms in the formset. Validation was performed for each of the two forms, and
+the expected error message appears for the second item.
+
+.. _understanding-the-managementform:
+
+Understanding the ManagementForm
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You may have noticed the additional data (``form-TOTAL_FORMS``,
+``form-INITIAL_FORMS`` and ``form-MAX_NUM_FORMS``) that was required
+in the formset's data above. This data is required for the
+``ManagementForm``. This form is used by the formset to manage the
+collection of forms contained in the formset. If you don't provide
+this management data, an exception will be raised::
+
+ >>> data = {
+ ... 'form-0-title': u'Test',
+ ... 'form-0-pub_date': u'',
+ ... }
+ >>> formset = ArticleFormSet(data)
+ Traceback (most recent call last):
+ ...
+ django.forms.util.ValidationError: [u'ManagementForm data is missing or has been tampered with']
+
+It is used to keep track of how many form instances are being displayed. If
+you are adding new forms via JavaScript, you should increment the count fields
+in this form as well.
+
+The management form is available as an attribute of the formset
+itself. When rendering a formset in a template, you can include all
+the management data by rendering ``{{ my_formset.management_form }}``
+(substituting the name of your formset as appropriate).
+
+.. versionadded:: 1.1
+
+``total_form_count`` and ``initial_form_count``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+``BaseFormSet`` has a couple of methods that are closely related to the
+``ManagementForm``, ``total_form_count`` and ``initial_form_count``.
+
+``total_form_count`` returns the total number of forms in this formset.
+``initial_form_count`` returns the number of forms in the formset that were
+pre-filled, and is also used to determine how many forms are required. You
+will probably never need to override either of these methods, so please be
+sure you understand what they do before doing so.
+
+.. versionadded:: 1.2
+
+``empty_form``
+~~~~~~~~~~~~~~
+
+``BaseFormSet`` provides an additional attribute ``empty_form`` which returns
+a form instance with a prefix of ``__prefix__`` for easier use in dynamic
+forms with JavaScript.
+
+Custom formset validation
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A formset has a ``clean`` method similar to the one on a ``Form`` class. This
+is where you define your own validation that works at the formset level::
+
+ >>> from django.forms.formsets import BaseFormSet
+
+ >>> class BaseArticleFormSet(BaseFormSet):
+ ... def clean(self):
+ ... """Checks that no two articles have the same title."""
+ ... if any(self.errors):
+ ... # Don't bother validating the formset unless each form is valid on its own
+ ... return
+ ... titles = []
+ ... for i in range(0, self.total_form_count()):
+ ... form = self.forms[i]
+ ... title = form.cleaned_data['title']
+ ... if title in titles:
+ ... raise forms.ValidationError, "Articles in a set must have distinct titles."
+ ... titles.append(title)
+
+ >>> ArticleFormSet = formset_factory(ArticleForm, formset=BaseArticleFormSet)
+ >>> data = {
+ ... 'form-TOTAL_FORMS': u'2',
+ ... 'form-INITIAL_FORMS': u'0',
+ ... 'form-MAX_NUM_FORMS': u'',
+ ... 'form-0-title': u'Test',
+ ... 'form-0-pub_date': u'16 June 1904',
+ ... 'form-1-title': u'Test',
+ ... 'form-1-pub_date': u'23 June 1912',
+ ... }
+ >>> formset = ArticleFormSet(data)
+ >>> formset.is_valid()
+ False
+ >>> formset.errors
+ [{}, {}]
+ >>> formset.non_form_errors()
+ [u'Articles in a set must have distinct titles.']
+
+The formset ``clean`` method is called after all the ``Form.clean`` methods
+have been called. The errors will be found using the ``non_form_errors()``
+method on the formset.
+
+Dealing with ordering and deletion of forms
+-------------------------------------------
+
+Common use cases with a formset is dealing with ordering and deletion of the
+form instances. This has been dealt with for you. The ``formset_factory``
+provides two optional parameters ``can_order`` and ``can_delete`` that will do
+the extra work of adding the extra fields and providing simpler ways of
+getting to that data.
+
+``can_order``
+~~~~~~~~~~~~~
+
+Default: ``False``
+
+Lets create a formset with the ability to order::
+
+ >>> ArticleFormSet = formset_factory(ArticleForm, can_order=True)
+ >>> formset = ArticleFormSet(initial=[
+ ... {'title': u'Article #1', 'pub_date': datetime.date(2008, 5, 10)},
+ ... {'title': u'Article #2', 'pub_date': datetime.date(2008, 5, 11)},
+ ... ])
+ >>> for form in formset.forms:
+ ... print form.as_table()
+ <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" value="Article #1" id="id_form-0-title" /></td></tr>
+ <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" value="2008-05-10" id="id_form-0-pub_date" /></td></tr>
+ <tr><th><label for="id_form-0-ORDER">Order:</label></th><td><input type="text" name="form-0-ORDER" value="1" id="id_form-0-ORDER" /></td></tr>
+ <tr><th><label for="id_form-1-title">Title:</label></th><td><input type="text" name="form-1-title" value="Article #2" id="id_form-1-title" /></td></tr>
+ <tr><th><label for="id_form-1-pub_date">Pub date:</label></th><td><input type="text" name="form-1-pub_date" value="2008-05-11" id="id_form-1-pub_date" /></td></tr>
+ <tr><th><label for="id_form-1-ORDER">Order:</label></th><td><input type="text" name="form-1-ORDER" value="2" id="id_form-1-ORDER" /></td></tr>
+ <tr><th><label for="id_form-2-title">Title:</label></th><td><input type="text" name="form-2-title" id="id_form-2-title" /></td></tr>
+ <tr><th><label for="id_form-2-pub_date">Pub date:</label></th><td><input type="text" name="form-2-pub_date" id="id_form-2-pub_date" /></td></tr>
+ <tr><th><label for="id_form-2-ORDER">Order:</label></th><td><input type="text" name="form-2-ORDER" id="id_form-2-ORDER" /></td></tr>
+
+This adds an additional field to each form. This new field is named ``ORDER``
+and is an ``forms.IntegerField``. For the forms that came from the initial
+data it automatically assigned them a numeric value. Lets look at what will
+happen when the user changes these values::
+
+ >>> data = {
+ ... 'form-TOTAL_FORMS': u'3',
+ ... 'form-INITIAL_FORMS': u'2',
+ ... 'form-MAX_NUM_FORMS': u'',
+ ... 'form-0-title': u'Article #1',
+ ... 'form-0-pub_date': u'2008-05-10',
+ ... 'form-0-ORDER': u'2',
+ ... 'form-1-title': u'Article #2',
+ ... 'form-1-pub_date': u'2008-05-11',
+ ... 'form-1-ORDER': u'1',
+ ... 'form-2-title': u'Article #3',
+ ... 'form-2-pub_date': u'2008-05-01',
+ ... 'form-2-ORDER': u'0',
+ ... }
+
+ >>> formset = ArticleFormSet(data, initial=[
+ ... {'title': u'Article #1', 'pub_date': datetime.date(2008, 5, 10)},
+ ... {'title': u'Article #2', 'pub_date': datetime.date(2008, 5, 11)},
+ ... ])
+ >>> formset.is_valid()
+ True
+ >>> for form in formset.ordered_forms:
+ ... print form.cleaned_data
+ {'pub_date': datetime.date(2008, 5, 1), 'ORDER': 0, 'title': u'Article #3'}
+ {'pub_date': datetime.date(2008, 5, 11), 'ORDER': 1, 'title': u'Article #2'}
+ {'pub_date': datetime.date(2008, 5, 10), 'ORDER': 2, 'title': u'Article #1'}
+
+``can_delete``
+~~~~~~~~~~~~~~
+
+Default: ``False``
+
+Lets create a formset with the ability to delete::
+
+ >>> ArticleFormSet = formset_factory(ArticleForm, can_delete=True)
+ >>> formset = ArticleFormSet(initial=[
+ ... {'title': u'Article #1', 'pub_date': datetime.date(2008, 5, 10)},
+ ... {'title': u'Article #2', 'pub_date': datetime.date(2008, 5, 11)},
+ ... ])
+ >>> for form in formset.forms:
+ .... print form.as_table()
+ <input type="hidden" name="form-TOTAL_FORMS" value="3" id="id_form-TOTAL_FORMS" /><input type="hidden" name="form-INITIAL_FORMS" value="2" id="id_form-INITIAL_FORMS" /><input type="hidden" name="form-MAX_NUM_FORMS" id="id_form-MAX_NUM_FORMS" />
+ <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" value="Article #1" id="id_form-0-title" /></td></tr>
+ <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" value="2008-05-10" id="id_form-0-pub_date" /></td></tr>
+ <tr><th><label for="id_form-0-DELETE">Delete:</label></th><td><input type="checkbox" name="form-0-DELETE" id="id_form-0-DELETE" /></td></tr>
+ <tr><th><label for="id_form-1-title">Title:</label></th><td><input type="text" name="form-1-title" value="Article #2" id="id_form-1-title" /></td></tr>
+ <tr><th><label for="id_form-1-pub_date">Pub date:</label></th><td><input type="text" name="form-1-pub_date" value="2008-05-11" id="id_form-1-pub_date" /></td></tr>
+ <tr><th><label for="id_form-1-DELETE">Delete:</label></th><td><input type="checkbox" name="form-1-DELETE" id="id_form-1-DELETE" /></td></tr>
+ <tr><th><label for="id_form-2-title">Title:</label></th><td><input type="text" name="form-2-title" id="id_form-2-title" /></td></tr>
+ <tr><th><label for="id_form-2-pub_date">Pub date:</label></th><td><input type="text" name="form-2-pub_date" id="id_form-2-pub_date" /></td></tr>
+ <tr><th><label for="id_form-2-DELETE">Delete:</label></th><td><input type="checkbox" name="form-2-DELETE" id="id_form-2-DELETE" /></td></tr>
+
+Similar to ``can_order`` this adds a new field to each form named ``DELETE``
+and is a ``forms.BooleanField``. When data comes through marking any of the
+delete fields you can access them with ``deleted_forms``::
+
+ >>> data = {
+ ... 'form-TOTAL_FORMS': u'3',
+ ... 'form-INITIAL_FORMS': u'2',
+ ... 'form-MAX_NUM_FORMS': u'',
+ ... 'form-0-title': u'Article #1',
+ ... 'form-0-pub_date': u'2008-05-10',
+ ... 'form-0-DELETE': u'on',
+ ... 'form-1-title': u'Article #2',
+ ... 'form-1-pub_date': u'2008-05-11',
+ ... 'form-1-DELETE': u'',
+ ... 'form-2-title': u'',
+ ... 'form-2-pub_date': u'',
+ ... 'form-2-DELETE': u'',
+ ... }
+
+ >>> formset = ArticleFormSet(data, initial=[
+ ... {'title': u'Article #1', 'pub_date': datetime.date(2008, 5, 10)},
+ ... {'title': u'Article #2', 'pub_date': datetime.date(2008, 5, 11)},
+ ... ])
+ >>> [form.cleaned_data for form in formset.deleted_forms]
+ [{'DELETE': True, 'pub_date': datetime.date(2008, 5, 10), 'title': u'Article #1'}]
+
+Adding additional fields to a formset
+-------------------------------------
+
+If you need to add additional fields to the formset this can be easily
+accomplished. The formset base class provides an ``add_fields`` method. You
+can simply override this method to add your own fields or even redefine the
+default fields/attributes of the order and deletion fields::
+
+ >>> class BaseArticleFormSet(BaseFormSet):
+ ... def add_fields(self, form, index):
+ ... super(BaseArticleFormSet, self).add_fields(form, index)
+ ... form.fields["my_field"] = forms.CharField()
+
+ >>> ArticleFormSet = formset_factory(ArticleForm, formset=BaseArticleFormSet)
+ >>> formset = ArticleFormSet()
+ >>> for form in formset.forms:
+ ... print form.as_table()
+ <tr><th><label for="id_form-0-title">Title:</label></th><td><input type="text" name="form-0-title" id="id_form-0-title" /></td></tr>
+ <tr><th><label for="id_form-0-pub_date">Pub date:</label></th><td><input type="text" name="form-0-pub_date" id="id_form-0-pub_date" /></td></tr>
+ <tr><th><label for="id_form-0-my_field">My field:</label></th><td><input type="text" name="form-0-my_field" id="id_form-0-my_field" /></td></tr>
+
+Using a formset in views and templates
+--------------------------------------
+
+Using a formset inside a view is as easy as using a regular ``Form`` class.
+The only thing you will want to be aware of is making sure to use the
+management form inside the template. Let's look at a sample view:
+
+.. code-block:: python
+
+ def manage_articles(request):
+ ArticleFormSet = formset_factory(ArticleForm)
+ if request.method == 'POST':
+ formset = ArticleFormSet(request.POST, request.FILES)
+ if formset.is_valid():
+ # do something with the formset.cleaned_data
+ pass
+ else:
+ formset = ArticleFormSet()
+ return render_to_response('manage_articles.html', {'formset': formset})
+
+The ``manage_articles.html`` template might look like this:
+
+.. code-block:: html+django
+
+ <form method="post" action="">
+ {{ formset.management_form }}
+ <table>
+ {% for form in formset.forms %}
+ {{ form }}
+ {% endfor %}
+ </table>
+ </form>
+
+However the above can be slightly shortcutted and let the formset itself deal
+with the management form:
+
+.. code-block:: html+django
+
+ <form method="post" action="">
+ <table>
+ {{ formset }}
+ </table>
+ </form>
+
+The above ends up calling the ``as_table`` method on the formset class.
+
+Using more than one formset in a view
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You are able to use more than one formset in a view if you like. Formsets
+borrow much of its behavior from forms. With that said you are able to use
+``prefix`` to prefix formset form field names with a given value to allow
+more than one formset to be sent to a view without name clashing. Lets take
+a look at how this might be accomplished:
+
+.. code-block:: python
+
+ def manage_articles(request):
+ ArticleFormSet = formset_factory(ArticleForm)
+ BookFormSet = formset_factory(BookForm)
+ if request.method == 'POST':
+ article_formset = ArticleFormSet(request.POST, request.FILES, prefix='articles')
+ book_formset = BookFormSet(request.POST, request.FILES, prefix='books')
+ if article_formset.is_valid() and book_formset.is_valid():
+ # do something with the cleaned_data on the formsets.
+ pass
+ else:
+ article_formset = ArticleFormSet(prefix='articles')
+ book_formset = BookFormSet(prefix='books')
+ return render_to_response('manage_articles.html', {
+ 'article_formset': article_formset,
+ 'book_formset': book_formset,
+ })
+
+You would then render the formsets as normal. It is important to point out
+that you need to pass ``prefix`` on both the POST and non-POST cases so that
+it is rendered and processed correctly.
diff --git a/parts/django/docs/topics/forms/index.txt b/parts/django/docs/topics/forms/index.txt
new file mode 100644
index 0000000..30b09c0
--- /dev/null
+++ b/parts/django/docs/topics/forms/index.txt
@@ -0,0 +1,402 @@
+==================
+Working with forms
+==================
+
+.. admonition:: About this document
+
+ This document provides an introduction to Django's form handling features.
+ For a more detailed look at specific areas of the forms API, see
+ :doc:`/ref/forms/api`, :doc:`/ref/forms/fields`, and
+ :doc:`/ref/forms/validation`.
+
+.. highlightlang:: html+django
+
+``django.forms`` is Django's form-handling library.
+
+While it is possible to process form submissions just using Django's
+:class:`~django.http.HttpRequest` class, using the form library takes care of a
+number of common form-related tasks. Using it, you can:
+
+ 1. Display an HTML form with automatically generated form widgets.
+ 2. Check submitted data against a set of validation rules.
+ 3. Redisplay a form in the case of validation errors.
+ 4. Convert submitted form data to the relevant Python data types.
+
+Overview
+========
+
+The library deals with these concepts:
+
+.. glossary::
+
+ Widget
+ A class that corresponds to an HTML form widget, e.g.
+ ``<input type="text">`` or ``<textarea>``. This handles rendering of the
+ widget as HTML.
+
+ Field
+ A class that is responsible for doing validation, e.g.
+ an ``EmailField`` that makes sure its data is a valid e-mail address.
+
+ Form
+ A collection of fields that knows how to validate itself and
+ display itself as HTML.
+
+ Form Media
+ The CSS and JavaScript resources that are required to render a form.
+
+The library is decoupled from the other Django components, such as the database
+layer, views and templates. It relies only on Django settings, a couple of
+``django.utils`` helper functions and Django's internationalization hooks (but
+you're not required to be using internationalization features to use this
+library).
+
+Form objects
+============
+
+A Form object encapsulates a sequence of form fields and a collection of
+validation rules that must be fulfilled in order for the form to be accepted.
+Form classes are created as subclasses of ``django.forms.Form`` and
+make use of a declarative style that you'll be familiar with if you've used
+Django's database models.
+
+For example, consider a form used to implement "contact me" functionality on a
+personal Web site:
+
+.. code-block:: python
+
+ from django import forms
+
+ class ContactForm(forms.Form):
+ subject = forms.CharField(max_length=100)
+ message = forms.CharField()
+ sender = forms.EmailField()
+ cc_myself = forms.BooleanField(required=False)
+
+A form is composed of ``Field`` objects. In this case, our form has four
+fields: ``subject``, ``message``, ``sender`` and ``cc_myself``. ``CharField``,
+``EmailField`` and ``BooleanField`` are just three of the available field types;
+a full list can be found in :doc:`/ref/forms/fields`.
+
+If your form is going to be used to directly add or edit a Django model, you can
+use a :doc:`ModelForm </topics/forms/modelforms>` to avoid duplicating your model
+description.
+
+Using a form in a view
+----------------------
+
+The standard pattern for processing a form in a view looks like this:
+
+.. code-block:: python
+
+ def contact(request):
+ if request.method == 'POST': # If the form has been submitted...
+ form = ContactForm(request.POST) # A form bound to the POST data
+ if form.is_valid(): # All validation rules pass
+ # Process the data in form.cleaned_data
+ # ...
+ return HttpResponseRedirect('/thanks/') # Redirect after POST
+ else:
+ form = ContactForm() # An unbound form
+
+ return render_to_response('contact.html', {
+ 'form': form,
+ })
+
+
+There are three code paths here:
+
+ 1. If the form has not been submitted, an unbound instance of ContactForm is
+ created and passed to the template.
+ 2. If the form has been submitted, a bound instance of the form is created
+ using ``request.POST``. If the submitted data is valid, it is processed
+ and the user is re-directed to a "thanks" page.
+ 3. If the form has been submitted but is invalid, the bound form instance is
+ passed on to the template.
+
+.. versionchanged:: 1.0
+ The ``cleaned_data`` attribute was called ``clean_data`` in earlier releases.
+
+The distinction between **bound** and **unbound** forms is important. An unbound
+form does not have any data associated with it; when rendered to the user, it
+will be empty or will contain default values. A bound form does have submitted
+data, and hence can be used to tell if that data is valid. If an invalid bound
+form is rendered it can include inline error messages telling the user where
+they went wrong.
+
+See :ref:`ref-forms-api-bound-unbound` for further information on the
+differences between bound and unbound forms.
+
+Handling file uploads with a form
+---------------------------------
+
+To see how to handle file uploads with your form see
+:ref:`binding-uploaded-files` for more information.
+
+Processing the data from a form
+-------------------------------
+
+Once ``is_valid()`` returns ``True``, you can process the form submission safe
+in the knowledge that it conforms to the validation rules defined by your form.
+While you could access ``request.POST`` directly at this point, it is better to
+access ``form.cleaned_data``. This data has not only been validated but will
+also be converted in to the relevant Python types for you. In the above example,
+``cc_myself`` will be a boolean value. Likewise, fields such as ``IntegerField``
+and ``FloatField`` convert values to a Python int and float respectively.
+
+Extending the above example, here's how the form data could be processed:
+
+.. code-block:: python
+
+ if form.is_valid():
+ subject = form.cleaned_data['subject']
+ message = form.cleaned_data['message']
+ sender = form.cleaned_data['sender']
+ cc_myself = form.cleaned_data['cc_myself']
+
+ recipients = ['info@example.com']
+ if cc_myself:
+ recipients.append(sender)
+
+ from django.core.mail import send_mail
+ send_mail(subject, message, sender, recipients)
+ return HttpResponseRedirect('/thanks/') # Redirect after POST
+
+For more on sending e-mail from Django, see :doc:`/topics/email`.
+
+Displaying a form using a template
+----------------------------------
+
+Forms are designed to work with the Django template language. In the above
+example, we passed our ``ContactForm`` instance to the template using the
+context variable ``form``. Here's a simple example template::
+
+ <form action="/contact/" method="post">
+ {{ form.as_p }}
+ <input type="submit" value="Submit" />
+ </form>
+
+The form only outputs its own fields; it is up to you to provide the surrounding
+``<form>`` tags and the submit button.
+
+``form.as_p`` will output the form with each form field and accompanying label
+wrapped in a paragraph. Here's the output for our example template::
+
+ <form action="/contact/" method="post">
+ <p><label for="id_subject">Subject:</label>
+ <input id="id_subject" type="text" name="subject" maxlength="100" /></p>
+ <p><label for="id_message">Message:</label>
+ <input type="text" name="message" id="id_message" /></p>
+ <p><label for="id_sender">Sender:</label>
+ <input type="text" name="sender" id="id_sender" /></p>
+ <p><label for="id_cc_myself">Cc myself:</label>
+ <input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>
+ <input type="submit" value="Submit" />
+ </form>
+
+Note that each form field has an ID attribute set to ``id_<field-name>``, which
+is referenced by the accompanying label tag. This is important for ensuring
+forms are accessible to assistive technology such as screen reader software. You
+can also :ref:`customize the way in which labels and ids are generated
+<ref-forms-api-configuring-label>`.
+
+You can also use ``form.as_table`` to output table rows (you'll need to provide
+your own ``<table>`` tags) and ``form.as_ul`` to output list items.
+
+Customizing the form template
+-----------------------------
+
+If the default generated HTML is not to your taste, you can completely customize
+the way a form is presented using the Django template language. Extending the
+above example::
+
+ <form action="/contact/" method="post">
+ {{ form.non_field_errors }}
+ <div class="fieldWrapper">
+ {{ form.subject.errors }}
+ <label for="id_subject">E-mail subject:</label>
+ {{ form.subject }}
+ </div>
+ <div class="fieldWrapper">
+ {{ form.message.errors }}
+ <label for="id_message">Your message:</label>
+ {{ form.message }}
+ </div>
+ <div class="fieldWrapper">
+ {{ form.sender.errors }}
+ <label for="id_sender">Your email address:</label>
+ {{ form.sender }}
+ </div>
+ <div class="fieldWrapper">
+ {{ form.cc_myself.errors }}
+ <label for="id_cc_myself">CC yourself?</label>
+ {{ form.cc_myself }}
+ </div>
+ <p><input type="submit" value="Send message" /></p>
+ </form>
+
+Each named form-field can be output to the template using
+``{{ form.name_of_field }}``, which will produce the HTML needed to display the
+form widget. Using ``{{ form.name_of_field.errors }}`` displays a list of form
+errors, rendered as an unordered list. This might look like::
+
+ <ul class="errorlist">
+ <li>Sender is required.</li>
+ </ul>
+
+The list has a CSS class of ``errorlist`` to allow you to style its appearance.
+If you wish to further customize the display of errors you can do so by looping
+over them::
+
+ {% if form.subject.errors %}
+ <ol>
+ {% for error in form.subject.errors %}
+ <li><strong>{{ error|escape }}</strong></li>
+ {% endfor %}
+ </ol>
+ {% endif %}
+
+Looping over the form's fields
+------------------------------
+
+If you're using the same HTML for each of your form fields, you can reduce
+duplicate code by looping through each field in turn using a ``{% for %}``
+loop::
+
+ <form action="/contact/" method="post">
+ {% for field in form %}
+ <div class="fieldWrapper">
+ {{ field.errors }}
+ {{ field.label_tag }}: {{ field }}
+ </div>
+ {% endfor %}
+ <p><input type="submit" value="Send message" /></p>
+ </form>
+
+Within this loop, ``{{ field }}`` is an instance of :class:`BoundField`.
+``BoundField`` also has the following attributes, which can be useful in your
+templates:
+
+ ``{{ field.label }}``
+ The label of the field, e.g. ``E-mail address``.
+
+ ``{{ field.label_tag }}``
+ The field's label wrapped in the appropriate HTML ``<label>`` tag,
+ e.g. ``<label for="id_email">E-mail address</label>``
+
+ ``{{ field.html_name }}``
+ The name of the field that will be used in the input element's name
+ field. This takes the form prefix into account, if it has been set.
+
+ ``{{ field.help_text }}``
+ Any help text that has been associated with the field.
+
+ ``{{ field.errors }}``
+ Outputs a ``<ul class="errorlist">`` containing any validation errors
+ corresponding to this field. You can customize the presentation of
+ the errors with a ``{% for error in field.errors %}`` loop. In this
+ case, each object in the loop is a simple string containing the error
+ message.
+
+ ``field.is_hidden``
+ This attribute is ``True`` if the form field is a hidden field and
+ ``False`` otherwise. It's not particularly useful as a template
+ variable, but could be useful in conditional tests such as::
+
+ {% if field.is_hidden %}
+ {# Do something special #}
+ {% endif %}
+
+Looping over hidden and visible fields
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you're manually laying out a form in a template, as opposed to relying on
+Django's default form layout, you might want to treat ``<input type="hidden">``
+fields differently than non-hidden fields. For example, because hidden fields
+don't display anything, putting error messages "next to" the field could cause
+confusion for your users -- so errors for those fields should be handled
+differently.
+
+Django provides two methods on a form that allow you to loop over the hidden
+and visible fields independently: ``hidden_fields()`` and
+``visible_fields()``. Here's a modification of an earlier example that uses
+these two methods::
+
+ <form action="/contact/" method="post">
+ {% for field in form.visible_fields %}
+ <div class="fieldWrapper">
+
+ {# Include the hidden fields in the form #}
+ {% if forloop.first %}
+ {% for hidden in form.hidden_fields %}
+ {{ hidden }}
+ {% endfor %}
+ {% endif %}
+
+ {{ field.errors }}
+ {{ field.label_tag }}: {{ field }}
+ </div>
+ {% endfor %}
+ <p><input type="submit" value="Send message" /></p>
+ </form>
+
+This example does not handle any errors in the hidden fields. Usually, an
+error in a hidden field is a sign of form tampering, since normal form
+interaction won't alter them. However, you could easily insert some error
+displays for those form errors, as well.
+
+.. versionadded:: 1.1
+ The ``hidden_fields`` and ``visible_fields`` methods are new in Django
+ 1.1.
+
+Reusable form templates
+-----------------------
+
+If your site uses the same rendering logic for forms in multiple places, you
+can reduce duplication by saving the form's loop in a standalone template and
+using the :ttag:`include` tag to reuse it in other templates::
+
+ <form action="/contact/" method="post">
+ {% include "form_snippet.html" %}
+ <p><input type="submit" value="Send message" /></p>
+ </form>
+
+ # In form_snippet.html:
+
+ {% for field in form %}
+ <div class="fieldWrapper">
+ {{ field.errors }}
+ {{ field.label_tag }}: {{ field }}
+ </div>
+ {% endfor %}
+
+If the form object passed to a template has a different name within the
+context, you can alias it using the :ttag:`with` tag::
+
+ <form action="/comments/add/" method="post">
+ {% with comment_form as form %}
+ {% include "form_snippet.html" %}
+ {% endwith %}
+ <p><input type="submit" value="Submit comment" /></p>
+ </form>
+
+If you find yourself doing this often, you might consider creating a custom
+:ref:`inclusion tag<howto-custom-template-tags-inclusion-tags>`.
+
+Further topics
+==============
+
+This covers the basics, but forms can do a whole lot more:
+
+.. toctree::
+ :maxdepth: 2
+
+ modelforms
+ formsets
+ media
+
+.. seealso::
+
+ :doc:`The Forms Reference </ref/forms/index>`
+ Covers the full API reference, including form fields, form widgets,
+ and form and field validation.
diff --git a/parts/django/docs/topics/forms/media.txt b/parts/django/docs/topics/forms/media.txt
new file mode 100644
index 0000000..fe70894
--- /dev/null
+++ b/parts/django/docs/topics/forms/media.txt
@@ -0,0 +1,309 @@
+Form Media
+==========
+
+Rendering an attractive and easy-to-use Web form requires more than just
+HTML - it also requires CSS stylesheets, and if you want to use fancy
+"Web2.0" widgets, you may also need to include some JavaScript on each
+page. The exact combination of CSS and JavaScript that is required for
+any given page will depend upon the widgets that are in use on that page.
+
+This is where Django media definitions come in. Django allows you to
+associate different media files with the forms and widgets that require
+that media. For example, if you want to use a calendar to render DateFields,
+you can define a custom Calendar widget. This widget can then be associated
+with the CSS and JavaScript that is required to render the calendar. When
+the Calendar widget is used on a form, Django is able to identify the CSS and
+JavaScript files that are required, and provide the list of file names
+in a form suitable for easy inclusion on your Web page.
+
+.. admonition:: Media and Django Admin
+
+ The Django Admin application defines a number of customized widgets
+ for calendars, filtered selections, and so on. These widgets define
+ media requirements, and the Django Admin uses the custom widgets
+ in place of the Django defaults. The Admin templates will only include
+ those media files that are required to render the widgets on any
+ given page.
+
+ If you like the widgets that the Django Admin application uses,
+ feel free to use them in your own application! They're all stored
+ in ``django.contrib.admin.widgets``.
+
+.. admonition:: Which JavaScript toolkit?
+
+ Many JavaScript toolkits exist, and many of them include widgets (such
+ as calendar widgets) that can be used to enhance your application.
+ Django has deliberately avoided blessing any one JavaScript toolkit.
+ Each toolkit has its own relative strengths and weaknesses - use
+ whichever toolkit suits your requirements. Django is able to integrate
+ with any JavaScript toolkit.
+
+Media as a static definition
+----------------------------
+
+The easiest way to define media is as a static definition. Using this method,
+the media declaration is an inner class. The properties of the inner class
+define the media requirements.
+
+Here's a simple example::
+
+ class CalendarWidget(forms.TextInput):
+ class Media:
+ css = {
+ 'all': ('pretty.css',)
+ }
+ js = ('animations.js', 'actions.js')
+
+This code defines a ``CalendarWidget``, which will be based on ``TextInput``.
+Every time the CalendarWidget is used on a form, that form will be directed
+to include the CSS file ``pretty.css``, and the JavaScript files
+``animations.js`` and ``actions.js``.
+
+This static media definition is converted at runtime into a widget property
+named ``media``. The media for a CalendarWidget instance can be retrieved
+through this property::
+
+ >>> w = CalendarWidget()
+ >>> print w.media
+ <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
+ <script type="text/javascript" src="http://media.example.com/animations.js"></script>
+ <script type="text/javascript" src="http://media.example.com/actions.js"></script>
+
+Here's a list of all possible ``Media`` options. There are no required options.
+
+``css``
+~~~~~~~
+
+A dictionary describing the CSS files required for various forms of output
+media.
+
+The values in the dictionary should be a tuple/list of file names. See
+`the section on media paths`_ for details of how to specify paths to media
+files.
+
+.. _the section on media paths: `Paths in media definitions`_
+
+The keys in the dictionary are the output media types. These are the same
+types accepted by CSS files in media declarations: 'all', 'aural', 'braille',
+'embossed', 'handheld', 'print', 'projection', 'screen', 'tty' and 'tv'. If
+you need to have different stylesheets for different media types, provide
+a list of CSS files for each output medium. The following example would
+provide two CSS options -- one for the screen, and one for print::
+
+ class Media:
+ css = {
+ 'screen': ('pretty.css',),
+ 'print': ('newspaper.css',)
+ }
+
+If a group of CSS files are appropriate for multiple output media types,
+the dictionary key can be a comma separated list of output media types.
+In the following example, TV's and projectors will have the same media
+requirements::
+
+ class Media:
+ css = {
+ 'screen': ('pretty.css',),
+ 'tv,projector': ('lo_res.css',),
+ 'print': ('newspaper.css',)
+ }
+
+If this last CSS definition were to be rendered, it would become the following HTML::
+
+ <link href="http://media.example.com/pretty.css" type="text/css" media="screen" rel="stylesheet" />
+ <link href="http://media.example.com/lo_res.css" type="text/css" media="tv,projector" rel="stylesheet" />
+ <link href="http://media.example.com/newspaper.css" type="text/css" media="print" rel="stylesheet" />
+
+``js``
+~~~~~~
+
+A tuple describing the required JavaScript files. See
+`the section on media paths`_ for details of how to specify paths to media
+files.
+
+``extend``
+~~~~~~~~~~
+
+A boolean defining inheritance behavior for media declarations.
+
+By default, any object using a static media definition will inherit all the
+media associated with the parent widget. This occurs regardless of how the
+parent defines its media requirements. For example, if we were to extend our
+basic Calendar widget from the example above::
+
+ >>> class FancyCalendarWidget(CalendarWidget):
+ ... class Media:
+ ... css = {
+ ... 'all': ('fancy.css',)
+ ... }
+ ... js = ('whizbang.js',)
+
+ >>> w = FancyCalendarWidget()
+ >>> print w.media
+ <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
+ <link href="http://media.example.com/fancy.css" type="text/css" media="all" rel="stylesheet" />
+ <script type="text/javascript" src="http://media.example.com/animations.js"></script>
+ <script type="text/javascript" src="http://media.example.com/actions.js"></script>
+ <script type="text/javascript" src="http://media.example.com/whizbang.js"></script>
+
+The FancyCalendar widget inherits all the media from it's parent widget. If
+you don't want media to be inherited in this way, add an ``extend=False``
+declaration to the media declaration::
+
+ >>> class FancyCalendarWidget(CalendarWidget):
+ ... class Media:
+ ... extend = False
+ ... css = {
+ ... 'all': ('fancy.css',)
+ ... }
+ ... js = ('whizbang.js',)
+
+ >>> w = FancyCalendarWidget()
+ >>> print w.media
+ <link href="http://media.example.com/fancy.css" type="text/css" media="all" rel="stylesheet" />
+ <script type="text/javascript" src="http://media.example.com/whizbang.js"></script>
+
+If you require even more control over media inheritance, define your media
+using a `dynamic property`_. Dynamic properties give you complete control over
+which media files are inherited, and which are not.
+
+.. _dynamic property: `Media as a dynamic property`_
+
+Media as a dynamic property
+---------------------------
+
+If you need to perform some more sophisticated manipulation of media
+requirements, you can define the media property directly. This is done
+by defining a widget property that returns an instance of ``forms.Media``.
+The constructor for ``forms.Media`` accepts ``css`` and ``js`` keyword
+arguments in the same format as that used in a static media definition.
+
+For example, the static media definition for our Calendar Widget could
+also be defined in a dynamic fashion::
+
+ class CalendarWidget(forms.TextInput):
+ def _media(self):
+ return forms.Media(css={'all': ('pretty.css',)},
+ js=('animations.js', 'actions.js'))
+ media = property(_media)
+
+See the section on `Media objects`_ for more details on how to construct
+return values for dynamic media properties.
+
+Paths in media definitions
+--------------------------
+
+Paths used to specify media can be either relative or absolute. If a path
+starts with '/', 'http://' or 'https://', it will be interpreted as an absolute
+path, and left as-is. All other paths will be prepended with the value of
+``settings.MEDIA_URL``. For example, if the MEDIA_URL for your site was
+``http://media.example.com/``::
+
+ class CalendarWidget(forms.TextInput):
+ class Media:
+ css = {
+ 'all': ('/css/pretty.css',),
+ }
+ js = ('animations.js', 'http://othersite.com/actions.js')
+
+ >>> w = CalendarWidget()
+ >>> print w.media
+ <link href="/css/pretty.css" type="text/css" media="all" rel="stylesheet" />
+ <script type="text/javascript" src="http://media.example.com/animations.js"></script>
+ <script type="text/javascript" src="http://othersite.com/actions.js"></script>
+
+Media objects
+-------------
+
+When you interrogate the media attribute of a widget or form, the value that
+is returned is a ``forms.Media`` object. As we have already seen, the string
+representation of a Media object is the HTML required to include media
+in the ``<head>`` block of your HTML page.
+
+However, Media objects have some other interesting properties.
+
+Media subsets
+~~~~~~~~~~~~~
+
+If you only want media of a particular type, you can use the subscript operator
+to filter out a medium of interest. For example::
+
+ >>> w = CalendarWidget()
+ >>> print w.media
+ <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
+ <script type="text/javascript" src="http://media.example.com/animations.js"></script>
+ <script type="text/javascript" src="http://media.example.com/actions.js"></script>
+
+ >>> print w.media['css']
+ <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
+
+When you use the subscript operator, the value that is returned is a new
+Media object -- but one that only contains the media of interest.
+
+Combining media objects
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Media objects can also be added together. When two media objects are added,
+the resulting Media object contains the union of the media from both files::
+
+ >>> class CalendarWidget(forms.TextInput):
+ ... class Media:
+ ... css = {
+ ... 'all': ('pretty.css',)
+ ... }
+ ... js = ('animations.js', 'actions.js')
+
+ >>> class OtherWidget(forms.TextInput):
+ ... class Media:
+ ... js = ('whizbang.js',)
+
+ >>> w1 = CalendarWidget()
+ >>> w2 = OtherWidget()
+ >>> print w1.media + w2.media
+ <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
+ <script type="text/javascript" src="http://media.example.com/animations.js"></script>
+ <script type="text/javascript" src="http://media.example.com/actions.js"></script>
+ <script type="text/javascript" src="http://media.example.com/whizbang.js"></script>
+
+Media on Forms
+--------------
+
+Widgets aren't the only objects that can have media definitions -- forms
+can also define media. The rules for media definitions on forms are the
+same as the rules for widgets: declarations can be static or dynamic;
+path and inheritance rules for those declarations are exactly the same.
+
+Regardless of whether you define a media declaration, *all* Form objects
+have a media property. The default value for this property is the result
+of adding the media definitions for all widgets that are part of the form::
+
+ >>> class ContactForm(forms.Form):
+ ... date = DateField(widget=CalendarWidget)
+ ... name = CharField(max_length=40, widget=OtherWidget)
+
+ >>> f = ContactForm()
+ >>> f.media
+ <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
+ <script type="text/javascript" src="http://media.example.com/animations.js"></script>
+ <script type="text/javascript" src="http://media.example.com/actions.js"></script>
+ <script type="text/javascript" src="http://media.example.com/whizbang.js"></script>
+
+If you want to associate additional media with a form -- for example, CSS for form
+layout -- simply add a media declaration to the form::
+
+ >>> class ContactForm(forms.Form):
+ ... date = DateField(widget=CalendarWidget)
+ ... name = CharField(max_length=40, widget=OtherWidget)
+ ...
+ ... class Media:
+ ... css = {
+ ... 'all': ('layout.css',)
+ ... }
+
+ >>> f = ContactForm()
+ >>> f.media
+ <link href="http://media.example.com/pretty.css" type="text/css" media="all" rel="stylesheet" />
+ <link href="http://media.example.com/layout.css" type="text/css" media="all" rel="stylesheet" />
+ <script type="text/javascript" src="http://media.example.com/animations.js"></script>
+ <script type="text/javascript" src="http://media.example.com/actions.js"></script>
+ <script type="text/javascript" src="http://media.example.com/whizbang.js"></script>
diff --git a/parts/django/docs/topics/forms/modelforms.txt b/parts/django/docs/topics/forms/modelforms.txt
new file mode 100644
index 0000000..23ed9a7
--- /dev/null
+++ b/parts/django/docs/topics/forms/modelforms.txt
@@ -0,0 +1,885 @@
+==========================
+Creating forms from models
+==========================
+
+.. module:: django.forms.models
+ :synopsis: ModelForm and ModelFormset.
+
+.. currentmodule:: django.forms
+
+``ModelForm``
+=============
+.. class:: ModelForm
+
+If you're building a database-driven app, chances are you'll have forms that
+map closely to Django models. For instance, you might have a ``BlogComment``
+model, and you want to create a form that lets people submit comments. In this
+case, it would be redundant to define the field types in your form, because
+you've already defined the fields in your model.
+
+For this reason, Django provides a helper class that let you create a ``Form``
+class from a Django model.
+
+For example::
+
+ >>> from django.forms import ModelForm
+
+ # Create the form class.
+ >>> class ArticleForm(ModelForm):
+ ... class Meta:
+ ... model = Article
+
+ # Creating a form to add an article.
+ >>> form = ArticleForm()
+
+ # Creating a form to change an existing article.
+ >>> article = Article.objects.get(pk=1)
+ >>> form = ArticleForm(instance=article)
+
+Field types
+-----------
+
+The generated ``Form`` class will have a form field for every model field. Each
+model field has a corresponding default form field. For example, a
+``CharField`` on a model is represented as a ``CharField`` on a form. A
+model ``ManyToManyField`` is represented as a ``MultipleChoiceField``. Here is
+the full list of conversions:
+
+ =============================== ========================================
+ Model field Form field
+ =============================== ========================================
+ ``AutoField`` Not represented in the form
+
+ ``BigIntegerField`` ``IntegerField`` with ``min_value`` set
+ to -9223372036854775808 and ``max_value``
+ set to 9223372036854775807.
+
+ ``BooleanField`` ``BooleanField``
+
+ ``CharField`` ``CharField`` with ``max_length`` set to
+ the model field's ``max_length``
+
+ ``CommaSeparatedIntegerField`` ``CharField``
+
+ ``DateField`` ``DateField``
+
+ ``DateTimeField`` ``DateTimeField``
+
+ ``DecimalField`` ``DecimalField``
+
+ ``EmailField`` ``EmailField``
+
+ ``FileField`` ``FileField``
+
+ ``FilePathField`` ``CharField``
+
+ ``FloatField`` ``FloatField``
+
+ ``ForeignKey`` ``ModelChoiceField`` (see below)
+
+ ``ImageField`` ``ImageField``
+
+ ``IntegerField`` ``IntegerField``
+
+ ``IPAddressField`` ``IPAddressField``
+
+ ``ManyToManyField`` ``ModelMultipleChoiceField`` (see
+ below)
+
+ ``NullBooleanField`` ``CharField``
+
+ ``PhoneNumberField`` ``USPhoneNumberField``
+ (from ``django.contrib.localflavor.us``)
+
+ ``PositiveIntegerField`` ``IntegerField``
+
+ ``PositiveSmallIntegerField`` ``IntegerField``
+
+ ``SlugField`` ``SlugField``
+
+ ``SmallIntegerField`` ``IntegerField``
+
+ ``TextField`` ``CharField`` with
+ ``widget=forms.Textarea``
+
+ ``TimeField`` ``TimeField``
+
+ ``URLField`` ``URLField`` with ``verify_exists`` set
+ to the model field's ``verify_exists``
+
+ ``XMLField`` ``CharField`` with
+ ``widget=forms.Textarea``
+ =============================== ========================================
+
+
+.. versionadded:: 1.0
+ The ``FloatField`` form field and ``DecimalField`` model and form fields
+ are new in Django 1.0.
+
+.. versionadded:: 1.2
+ The ``BigIntegerField`` is new in Django 1.2.
+
+
+As you might expect, the ``ForeignKey`` and ``ManyToManyField`` model field
+types are special cases:
+
+ * ``ForeignKey`` is represented by ``django.forms.ModelChoiceField``,
+ which is a ``ChoiceField`` whose choices are a model ``QuerySet``.
+
+ * ``ManyToManyField`` is represented by
+ ``django.forms.ModelMultipleChoiceField``, which is a
+ ``MultipleChoiceField`` whose choices are a model ``QuerySet``.
+
+In addition, each generated form field has attributes set as follows:
+
+ * If the model field has ``blank=True``, then ``required`` is set to
+ ``False`` on the form field. Otherwise, ``required=True``.
+
+ * The form field's ``label`` is set to the ``verbose_name`` of the model
+ field, with the first character capitalized.
+
+ * The form field's ``help_text`` is set to the ``help_text`` of the model
+ field.
+
+ * If the model field has ``choices`` set, then the form field's ``widget``
+ will be set to ``Select``, with choices coming from the model field's
+ ``choices``. The choices will normally include the blank choice which is
+ selected by default. If the field is required, this forces the user to
+ make a selection. The blank choice will not be included if the model
+ field has ``blank=False`` and an explicit ``default`` value (the
+ ``default`` value will be initially selected instead).
+
+Finally, note that you can override the form field used for a given model
+field. See `Overriding the default field types or widgets`_ below.
+
+A full example
+--------------
+
+Consider this set of models::
+
+ from django.db import models
+ from django.forms import ModelForm
+
+ TITLE_CHOICES = (
+ ('MR', 'Mr.'),
+ ('MRS', 'Mrs.'),
+ ('MS', 'Ms.'),
+ )
+
+ class Author(models.Model):
+ name = models.CharField(max_length=100)
+ title = models.CharField(max_length=3, choices=TITLE_CHOICES)
+ birth_date = models.DateField(blank=True, null=True)
+
+ def __unicode__(self):
+ return self.name
+
+ class Book(models.Model):
+ name = models.CharField(max_length=100)
+ authors = models.ManyToManyField(Author)
+
+ class AuthorForm(ModelForm):
+ class Meta:
+ model = Author
+
+ class BookForm(ModelForm):
+ class Meta:
+ model = Book
+
+With these models, the ``ModelForm`` subclasses above would be roughly
+equivalent to this (the only difference being the ``save()`` method, which
+we'll discuss in a moment.)::
+
+ class AuthorForm(forms.Form):
+ name = forms.CharField(max_length=100)
+ title = forms.CharField(max_length=3,
+ widget=forms.Select(choices=TITLE_CHOICES))
+ birth_date = forms.DateField(required=False)
+
+ class BookForm(forms.Form):
+ name = forms.CharField(max_length=100)
+ authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all())
+
+The ``is_valid()`` method and ``errors``
+----------------------------------------
+
+.. versionchanged:: 1.2
+
+The first time you call ``is_valid()`` or access the ``errors`` attribute of a
+``ModelForm`` has always triggered form validation, but as of Django 1.2, it
+will also trigger :ref:`model validation <validating-objects>`. This has the
+side-effect of cleaning the model you pass to the ``ModelForm`` constructor.
+For instance, calling ``is_valid()`` on your form will convert any date fields
+on your model to actual date objects.
+
+
+The ``save()`` method
+---------------------
+
+Every form produced by ``ModelForm`` also has a ``save()``
+method. This method creates and saves a database object from the data
+bound to the form. A subclass of ``ModelForm`` can accept an existing
+model instance as the keyword argument ``instance``; if this is
+supplied, ``save()`` will update that instance. If it's not supplied,
+``save()`` will create a new instance of the specified model::
+
+ # Create a form instance from POST data.
+ >>> f = ArticleForm(request.POST)
+
+ # Save a new Article object from the form's data.
+ >>> new_article = f.save()
+
+ # Create a form to edit an existing Article.
+ >>> a = Article.objects.get(pk=1)
+ >>> f = ArticleForm(instance=a)
+ >>> f.save()
+
+ # Create a form to edit an existing Article, but use
+ # POST data to populate the form.
+ >>> a = Article.objects.get(pk=1)
+ >>> f = ArticleForm(request.POST, instance=a)
+ >>> f.save()
+
+Note that ``save()`` will raise a ``ValueError`` if the data in the form
+doesn't validate -- i.e., if form.errors evaluates to True.
+
+This ``save()`` method accepts an optional ``commit`` keyword argument, which
+accepts either ``True`` or ``False``. If you call ``save()`` with
+``commit=False``, then it will return an object that hasn't yet been saved to
+the database. In this case, it's up to you to call ``save()`` on the resulting
+model instance. This is useful if you want to do custom processing on the
+object before saving it, or if you want to use one of the specialized
+:ref:`model saving options <ref-models-force-insert>`. ``commit`` is ``True``
+by default.
+
+Another side effect of using ``commit=False`` is seen when your model has
+a many-to-many relation with another model. If your model has a many-to-many
+relation and you specify ``commit=False`` when you save a form, Django cannot
+immediately save the form data for the many-to-many relation. This is because
+it isn't possible to save many-to-many data for an instance until the instance
+exists in the database.
+
+To work around this problem, every time you save a form using ``commit=False``,
+Django adds a ``save_m2m()`` method to your ``ModelForm`` subclass. After
+you've manually saved the instance produced by the form, you can invoke
+``save_m2m()`` to save the many-to-many form data. For example::
+
+ # Create a form instance with POST data.
+ >>> f = AuthorForm(request.POST)
+
+ # Create, but don't save the new author instance.
+ >>> new_author = f.save(commit=False)
+
+ # Modify the author in some way.
+ >>> new_author.some_field = 'some_value'
+
+ # Save the new instance.
+ >>> new_author.save()
+
+ # Now, save the many-to-many data for the form.
+ >>> f.save_m2m()
+
+Calling ``save_m2m()`` is only required if you use ``save(commit=False)``.
+When you use a simple ``save()`` on a form, all data -- including
+many-to-many data -- is saved without the need for any additional method calls.
+For example::
+
+ # Create a form instance with POST data.
+ >>> a = Author()
+ >>> f = AuthorForm(request.POST, instance=a)
+
+ # Create and save the new author instance. There's no need to do anything else.
+ >>> new_author = f.save()
+
+Other than the ``save()`` and ``save_m2m()`` methods, a ``ModelForm`` works
+exactly the same way as any other ``forms`` form. For example, the
+``is_valid()`` method is used to check for validity, the ``is_multipart()``
+method is used to determine whether a form requires multipart file upload (and
+hence whether ``request.FILES`` must be passed to the form), etc. See
+:ref:`binding-uploaded-files` for more information.
+
+Using a subset of fields on the form
+------------------------------------
+
+In some cases, you may not want all the model fields to appear on the generated
+form. There are three ways of telling ``ModelForm`` to use only a subset of the
+model fields:
+
+1. Set ``editable=False`` on the model field. As a result, *any* form
+ created from the model via ``ModelForm`` will not include that
+ field.
+
+2. Use the ``fields`` attribute of the ``ModelForm``'s inner ``Meta``
+ class. This attribute, if given, should be a list of field names
+ to include in the form.
+
+ .. versionchanged:: 1.1
+
+ The form will render the fields in the same order they are specified in the
+ ``fields`` attribute.
+
+3. Use the ``exclude`` attribute of the ``ModelForm``'s inner ``Meta``
+ class. This attribute, if given, should be a list of field names
+ to exclude from the form.
+
+For example, if you want a form for the ``Author`` model (defined
+above) that includes only the ``name`` and ``title`` fields, you would
+specify ``fields`` or ``exclude`` like this::
+
+ class PartialAuthorForm(ModelForm):
+ class Meta:
+ model = Author
+ fields = ('name', 'title')
+
+ class PartialAuthorForm(ModelForm):
+ class Meta:
+ model = Author
+ exclude = ('birth_date',)
+
+Since the Author model has only 3 fields, 'name', 'title', and
+'birth_date', the forms above will contain exactly the same fields.
+
+.. note::
+
+ If you specify ``fields`` or ``exclude`` when creating a form with
+ ``ModelForm``, then the fields that are not in the resulting form will not
+ be set by the form's ``save()`` method. Django will prevent any attempt to
+ save an incomplete model, so if the model does not allow the missing fields
+ to be empty, and does not provide a default value for the missing fields,
+ any attempt to ``save()`` a ``ModelForm`` with missing fields will fail.
+ To avoid this failure, you must instantiate your model with initial values
+ for the missing, but required fields::
+
+ author = Author(title='Mr')
+ form = PartialAuthorForm(request.POST, instance=author)
+ form.save()
+
+ Alternatively, you can use ``save(commit=False)`` and manually set
+ any extra required fields::
+
+ form = PartialAuthorForm(request.POST)
+ author = form.save(commit=False)
+ author.title = 'Mr'
+ author.save()
+
+ See the `section on saving forms`_ for more details on using
+ ``save(commit=False)``.
+
+.. _section on saving forms: `The save() method`_
+
+Overriding the default field types or widgets
+---------------------------------------------
+
+.. versionadded:: 1.2
+ The ``widgets`` attribute is new in Django 1.2.
+
+The default field types, as described in the `Field types`_ table above, are
+sensible defaults. If you have a ``DateField`` in your model, chances are you'd
+want that to be represented as a ``DateField`` in your form. But
+``ModelForm`` gives you the flexibility of changing the form field type and
+widget for a given model field.
+
+To specify a custom widget for a field, use the ``widgets`` attribute of the
+inner ``Meta`` class. This should be a dictionary mapping field names to widget
+classes or instances.
+
+For example, if you want the a ``CharField`` for the ``name``
+attribute of ``Author`` to be represented by a ``<textarea>`` instead
+of its default ``<input type="text">``, you can override the field's
+widget::
+
+ from django.forms import ModelForm, Textarea
+
+ class AuthorForm(ModelForm):
+ class Meta:
+ model = Author
+ fields = ('name', 'title', 'birth_date')
+ widgets = {
+ 'name': Textarea(attrs={'cols': 80, 'rows': 20}),
+ }
+
+The ``widgets`` dictionary accepts either widget instances (e.g.,
+``Textarea(...)``) or classes (e.g., ``Textarea``).
+
+If you want to further customize a field -- including its type, label, etc. --
+you can do this by declaratively specifying fields like you would in a regular
+``Form``. Declared fields will override the default ones generated by using the
+``model`` attribute.
+
+For example, if you wanted to use ``MyDateFormField`` for the ``pub_date``
+field, you could do the following::
+
+ class ArticleForm(ModelForm):
+ pub_date = MyDateFormField()
+
+ class Meta:
+ model = Article
+
+If you want to override a field's default label, then specify the ``label``
+parameter when declaring the form field::
+
+ >>> class ArticleForm(ModelForm):
+ ... pub_date = DateField(label='Publication date')
+ ...
+ ... class Meta:
+ ... model = Article
+
+.. note::
+
+ If you explicitly instantiate a form field like this, Django assumes that you
+ want to completely define its behavior; therefore, default attributes (such as
+ ``max_length`` or ``required``) are not drawn from the corresponding model. If
+ you want to maintain the behavior specified in the model, you must set the
+ relevant arguments explicitly when declaring the form field.
+
+ For example, if the ``Article`` model looks like this::
+
+ class Article(models.Model):
+ headline = models.CharField(max_length=200, null=True, blank=True,
+ help_text="Use puns liberally")
+ content = models.TextField()
+
+ and you want to do some custom validation for ``headline``, while keeping
+ the ``blank`` and ``help_text`` values as specified, you might define
+ ``ArticleForm`` like this::
+
+ class ArticleForm(ModelForm):
+ headline = MyFormField(max_length=200, required=False,
+ help_text="Use puns liberally")
+
+ class Meta:
+ model = Article
+
+ See the :doc:`form field documentation </ref/forms/fields>` for more information
+ on fields and their arguments.
+
+Changing the order of fields
+----------------------------
+
+.. versionadded:: 1.1
+
+By default, a ``ModelForm`` will render fields in the same order that they are
+defined on the model, with ``ManyToManyField`` instances appearing last. If
+you want to change the order in which fields are rendered, you can use the
+``fields`` attribute on the ``Meta`` class.
+
+The ``fields`` attribute defines the subset of model fields that will be
+rendered, and the order in which they will be rendered. For example given this
+model::
+
+ class Book(models.Model):
+ author = models.ForeignKey(Author)
+ title = models.CharField(max_length=100)
+
+the ``author`` field would be rendered first. If we wanted the title field
+to be rendered first, we could specify the following ``ModelForm``::
+
+ >>> class BookForm(ModelForm):
+ ... class Meta:
+ ... model = Book
+ ... fields = ('title', 'author')
+
+.. _overriding-modelform-clean-method:
+
+Overriding the clean() method
+-----------------------------
+
+You can override the ``clean()`` method on a model form to provide additional
+validation in the same way you can on a normal form.
+
+In this regard, model forms have two specific characteristics when compared to
+forms:
+
+By default the ``clean()`` method validates the uniqueness of fields that are
+marked as ``unique``, ``unique_together`` or ``unique_for_date|month|year`` on
+the model. Therefore, if you would like to override the ``clean()`` method and
+maintain the default validation, you must call the parent class's ``clean()``
+method.
+
+Also, a model form instance bound to a model object will contain a
+``self.instance`` attribute that gives model form methods access to that
+specific model instance.
+
+Form inheritance
+----------------
+
+As with basic forms, you can extend and reuse ``ModelForms`` by inheriting
+them. This is useful if you need to declare extra fields or extra methods on a
+parent class for use in a number of forms derived from models. For example,
+using the previous ``ArticleForm`` class::
+
+ >>> class EnhancedArticleForm(ArticleForm):
+ ... def clean_pub_date(self):
+ ... ...
+
+This creates a form that behaves identically to ``ArticleForm``, except there's
+some extra validation and cleaning for the ``pub_date`` field.
+
+You can also subclass the parent's ``Meta`` inner class if you want to change
+the ``Meta.fields`` or ``Meta.excludes`` lists::
+
+ >>> class RestrictedArticleForm(EnhancedArticleForm):
+ ... class Meta(ArticleForm.Meta):
+ ... exclude = ('body',)
+
+This adds the extra method from the ``EnhancedArticleForm`` and modifies
+the original ``ArticleForm.Meta`` to remove one field.
+
+There are a couple of things to note, however.
+
+ * Normal Python name resolution rules apply. If you have multiple base
+ classes that declare a ``Meta`` inner class, only the first one will be
+ used. This means the child's ``Meta``, if it exists, otherwise the
+ ``Meta`` of the first parent, etc.
+
+ * For technical reasons, a subclass cannot inherit from both a ``ModelForm``
+ and a ``Form`` simultaneously.
+
+Chances are these notes won't affect you unless you're trying to do something
+tricky with subclassing.
+
+Interaction with model validation
+---------------------------------
+
+As part of its validation process, ``ModelForm`` will call the ``clean()``
+method of each field on your model that has a corresponding field on your form.
+If you have excluded any model fields, validation will not be run on those
+fields. See the :doc:`form validation </ref/forms/validation>` documentation
+for more on how field cleaning and validation work. Also, your model's
+``clean()`` method will be called before any uniqueness checks are made. See
+:ref:`Validating objects <validating-objects>` for more information on the
+model's ``clean()`` hook.
+
+.. _model-formsets:
+
+Model formsets
+==============
+
+Like :doc:`regular formsets </topics/forms/formsets>`, Django provides a couple
+of enhanced formset classes that make it easy to work with Django models. Let's
+reuse the ``Author`` model from above::
+
+ >>> from django.forms.models import modelformset_factory
+ >>> AuthorFormSet = modelformset_factory(Author)
+
+This will create a formset that is capable of working with the data associated
+with the ``Author`` model. It works just like a regular formset::
+
+ >>> formset = AuthorFormSet()
+ >>> print formset
+ <input type="hidden" name="form-TOTAL_FORMS" value="1" id="id_form-TOTAL_FORMS" /><input type="hidden" name="form-INITIAL_FORMS" value="0" id="id_form-INITIAL_FORMS" /><input type="hidden" name="form-MAX_NUM_FORMS" id="id_form-MAX_NUM_FORMS" />
+ <tr><th><label for="id_form-0-name">Name:</label></th><td><input id="id_form-0-name" type="text" name="form-0-name" maxlength="100" /></td></tr>
+ <tr><th><label for="id_form-0-title">Title:</label></th><td><select name="form-0-title" id="id_form-0-title">
+ <option value="" selected="selected">---------</option>
+ <option value="MR">Mr.</option>
+ <option value="MRS">Mrs.</option>
+ <option value="MS">Ms.</option>
+ </select></td></tr>
+ <tr><th><label for="id_form-0-birth_date">Birth date:</label></th><td><input type="text" name="form-0-birth_date" id="id_form-0-birth_date" /><input type="hidden" name="form-0-id" id="id_form-0-id" /></td></tr>
+
+.. note::
+ ``modelformset_factory`` uses ``formset_factory`` to generate formsets.
+ This means that a model formset is just an extension of a basic formset
+ that knows how to interact with a particular model.
+
+Changing the queryset
+---------------------
+
+By default, when you create a formset from a model, the formset will use a
+queryset that includes all objects in the model (e.g.,
+``Author.objects.all()``). You can override this behavior by using the
+``queryset`` argument::
+
+ >>> formset = AuthorFormSet(queryset=Author.objects.filter(name__startswith='O'))
+
+Alternatively, you can create a subclass that sets ``self.queryset`` in
+``__init__``::
+
+ from django.forms.models import BaseModelFormSet
+
+ class BaseAuthorFormSet(BaseModelFormSet):
+ def __init__(self, *args, **kwargs):
+ super(BaseAuthorFormSet, self).__init__(*args, **kwargs)
+ self.queryset = Author.objects.filter(name__startswith='O')
+
+Then, pass your ``BaseAuthorFormSet`` class to the factory function::
+
+ >>> AuthorFormSet = modelformset_factory(Author, formset=BaseAuthorFormSet)
+
+If you want to return a formset that doesn't include *any* pre-existing
+instances of the model, you can specify an empty QuerySet::
+
+ >>> AuthorFormSet(queryset=Author.objects.none())
+
+
+Controlling which fields are used with ``fields`` and ``exclude``
+-----------------------------------------------------------------
+
+By default, a model formset uses all fields in the model that are not marked
+with ``editable=False``. However, this can be overridden at the formset level::
+
+ >>> AuthorFormSet = modelformset_factory(Author, fields=('name', 'title'))
+
+Using ``fields`` restricts the formset to use only the given fields.
+Alternatively, you can take an "opt-out" approach, specifying which fields to
+exclude::
+
+ >>> AuthorFormSet = modelformset_factory(Author, exclude=('birth_date',))
+
+.. _saving-objects-in-the-formset:
+
+Saving objects in the formset
+-----------------------------
+
+As with a ``ModelForm``, you can save the data as a model object. This is done
+with the formset's ``save()`` method::
+
+ # Create a formset instance with POST data.
+ >>> formset = AuthorFormSet(request.POST)
+
+ # Assuming all is valid, save the data.
+ >>> instances = formset.save()
+
+The ``save()`` method returns the instances that have been saved to the
+database. If a given instance's data didn't change in the bound data, the
+instance won't be saved to the database and won't be included in the return
+value (``instances``, in the above example).
+
+Pass ``commit=False`` to return the unsaved model instances::
+
+ # don't save to the database
+ >>> instances = formset.save(commit=False)
+ >>> for instance in instances:
+ ... # do something with instance
+ ... instance.save()
+
+This gives you the ability to attach data to the instances before saving them
+to the database. If your formset contains a ``ManyToManyField``, you'll also
+need to call ``formset.save_m2m()`` to ensure the many-to-many relationships
+are saved properly.
+
+.. _model-formsets-max-num:
+
+Limiting the number of editable objects
+---------------------------------------
+
+.. versionchanged:: 1.2
+
+As with regular formsets, you can use the ``max_num`` and ``extra`` parameters
+to ``modelformset_factory`` to limit the number of extra forms displayed.
+
+``max_num`` does not prevent existing objects from being displayed::
+
+ >>> Author.objects.order_by('name')
+ [<Author: Charles Baudelaire>, <Author: Paul Verlaine>, <Author: Walt Whitman>]
+
+ >>> AuthorFormSet = modelformset_factory(Author, max_num=1)
+ >>> formset = AuthorFormSet(queryset=Author.objects.order_by('name'))
+ >>> [x.name for x in formset.get_queryset()]
+ [u'Charles Baudelaire', u'Paul Verlaine', u'Walt Whitman']
+
+If the value of ``max_num`` is greater than the number of existing related
+objects, up to ``extra`` additional blank forms will be added to the formset,
+so long as the total number of forms does not exceed ``max_num``::
+
+ >>> AuthorFormSet = modelformset_factory(Author, max_num=4, extra=2)
+ >>> formset = AuthorFormSet(queryset=Author.objects.order_by('name'))
+ >>> for form in formset.forms:
+ ... print form.as_table()
+ <tr><th><label for="id_form-0-name">Name:</label></th><td><input id="id_form-0-name" type="text" name="form-0-name" value="Charles Baudelaire" maxlength="100" /><input type="hidden" name="form-0-id" value="1" id="id_form-0-id" /></td></tr>
+ <tr><th><label for="id_form-1-name">Name:</label></th><td><input id="id_form-1-name" type="text" name="form-1-name" value="Paul Verlaine" maxlength="100" /><input type="hidden" name="form-1-id" value="3" id="id_form-1-id" /></td></tr>
+ <tr><th><label for="id_form-2-name">Name:</label></th><td><input id="id_form-2-name" type="text" name="form-2-name" value="Walt Whitman" maxlength="100" /><input type="hidden" name="form-2-id" value="2" id="id_form-2-id" /></td></tr>
+ <tr><th><label for="id_form-3-name">Name:</label></th><td><input id="id_form-3-name" type="text" name="form-3-name" maxlength="100" /><input type="hidden" name="form-3-id" id="id_form-3-id" /></td></tr>
+
+.. versionchanged:: 1.2
+
+A ``max_num`` value of ``None`` (the default) puts no limit on the number of
+forms displayed.
+
+Using a model formset in a view
+-------------------------------
+
+Model formsets are very similar to formsets. Let's say we want to present a
+formset to edit ``Author`` model instances::
+
+ def manage_authors(request):
+ AuthorFormSet = modelformset_factory(Author)
+ if request.method == 'POST':
+ formset = AuthorFormSet(request.POST, request.FILES)
+ if formset.is_valid():
+ formset.save()
+ # do something.
+ else:
+ formset = AuthorFormSet()
+ return render_to_response("manage_authors.html", {
+ "formset": formset,
+ })
+
+As you can see, the view logic of a model formset isn't drastically different
+than that of a "normal" formset. The only difference is that we call
+``formset.save()`` to save the data into the database. (This was described
+above, in :ref:`saving-objects-in-the-formset`.)
+
+Overiding ``clean()`` on a ``model_formset``
+--------------------------------------------
+
+Just like with ``ModelForms``, by default the ``clean()`` method of a
+``model_formset`` will validate that none of the items in the formset violate
+the unique constraints on your model (either ``unique``, ``unique_together`` or
+``unique_for_date|month|year``). If you want to overide the ``clean()`` method
+on a ``model_formset`` and maintain this validation, you must call the parent
+class's ``clean`` method::
+
+ class MyModelFormSet(BaseModelFormSet):
+ def clean(self):
+ super(MyModelFormSet, self).clean()
+ # example custom validation across forms in the formset:
+ for form in self.forms:
+ # your custom formset validation
+
+Using a custom queryset
+-----------------------
+
+As stated earlier, you can override the default queryset used by the model
+formset::
+
+ def manage_authors(request):
+ AuthorFormSet = modelformset_factory(Author)
+ if request.method == "POST":
+ formset = AuthorFormSet(request.POST, request.FILES,
+ queryset=Author.objects.filter(name__startswith='O'))
+ if formset.is_valid():
+ formset.save()
+ # Do something.
+ else:
+ formset = AuthorFormSet(queryset=Author.objects.filter(name__startswith='O'))
+ return render_to_response("manage_authors.html", {
+ "formset": formset,
+ })
+
+Note that we pass the ``queryset`` argument in both the ``POST`` and ``GET``
+cases in this example.
+
+Using the formset in the template
+---------------------------------
+
+.. highlight:: html+django
+
+There are three ways to render a formset in a Django template.
+
+First, you can let the formset do most of the work::
+
+ <form method="post" action="">
+ {{ formset }}
+ </form>
+
+Second, you can manually render the formset, but let the form deal with
+itself::
+
+ <form method="post" action="">
+ {{ formset.management_form }}
+ {% for form in formset.forms %}
+ {{ form }}
+ {% endfor %}
+ </form>
+
+When you manually render the forms yourself, be sure to render the management
+form as shown above. See the :ref:`management form documentation
+<understanding-the-managementform>`.
+
+Third, you can manually render each field::
+
+ <form method="post" action="">
+ {{ formset.management_form }}
+ {% for form in formset.forms %}
+ {% for field in form %}
+ {{ field.label_tag }}: {{ field }}
+ {% endfor %}
+ {% endfor %}
+ </form>
+
+If you opt to use this third method and you don't iterate over the fields with
+a ``{% for %}`` loop, you'll need to render the primary key field. For example,
+if you were rendering the ``name`` and ``age`` fields of a model::
+
+ <form method="post" action="">
+ {{ formset.management_form }}
+ {% for form in formset.forms %}
+ {{ form.id }}
+ <ul>
+ <li>{{ form.name }}</li>
+ <li>{{ form.age }}</li>
+ </ul>
+ {% endfor %}
+ </form>
+
+Notice how we need to explicitly render ``{{ form.id }}``. This ensures that
+the model formset, in the ``POST`` case, will work correctly. (This example
+assumes a primary key named ``id``. If you've explicitly defined your own
+primary key that isn't called ``id``, make sure it gets rendered.)
+
+.. highlight:: python
+
+Inline formsets
+===============
+
+Inline formsets is a small abstraction layer on top of model formsets. These
+simplify the case of working with related objects via a foreign key. Suppose
+you have these two models::
+
+ class Author(models.Model):
+ name = models.CharField(max_length=100)
+
+ class Book(models.Model):
+ author = models.ForeignKey(Author)
+ title = models.CharField(max_length=100)
+
+If you want to create a formset that allows you to edit books belonging to
+a particular author, you could do this::
+
+ >>> from django.forms.models import inlineformset_factory
+ >>> BookFormSet = inlineformset_factory(Author, Book)
+ >>> author = Author.objects.get(name=u'Mike Royko')
+ >>> formset = BookFormSet(instance=author)
+
+.. note::
+ ``inlineformset_factory`` uses ``modelformset_factory`` and marks
+ ``can_delete=True``.
+
+More than one foreign key to the same model
+-------------------------------------------
+
+If your model contains more than one foreign key to the same model, you'll
+need to resolve the ambiguity manually using ``fk_name``. For example, consider
+the following model::
+
+ class Friendship(models.Model):
+ from_friend = models.ForeignKey(Friend)
+ to_friend = models.ForeignKey(Friend)
+ length_in_months = models.IntegerField()
+
+To resolve this, you can use ``fk_name`` to ``inlineformset_factory``::
+
+ >>> FriendshipFormSet = inlineformset_factory(Friend, Friendship, fk_name="from_friend")
+
+Using an inline formset in a view
+---------------------------------
+
+You may want to provide a view that allows a user to edit the related objects
+of a model. Here's how you can do that::
+
+ def manage_books(request, author_id):
+ author = Author.objects.get(pk=author_id)
+ BookInlineFormSet = inlineformset_factory(Author, Book)
+ if request.method == "POST":
+ formset = BookInlineFormSet(request.POST, request.FILES, instance=author)
+ if formset.is_valid():
+ formset.save()
+ # Do something.
+ else:
+ formset = BookInlineFormSet(instance=author)
+ return render_to_response("manage_books.html", {
+ "formset": formset,
+ })
+
+Notice how we pass ``instance`` in both the ``POST`` and ``GET`` cases.
diff --git a/parts/django/docs/topics/generic-views.txt b/parts/django/docs/topics/generic-views.txt
new file mode 100644
index 0000000..41e32c8
--- /dev/null
+++ b/parts/django/docs/topics/generic-views.txt
@@ -0,0 +1,501 @@
+=============
+Generic views
+=============
+
+Writing Web applications can be monotonous, because we repeat certain patterns
+again and again. Django tries to take away some of that monotony at the model
+and template layers, but Web developers also experience this boredom at the view
+level.
+
+Django's *generic views* were developed to ease that pain. They take certain
+common idioms and patterns found in view development and abstract them so that
+you can quickly write common views of data without having to write too much
+code.
+
+We can recognize certain common tasks, like displaying a list of objects, and
+write code that displays a list of *any* object. Then the model in question can
+be passed as an extra argument to the URLconf.
+
+Django ships with generic views to do the following:
+
+ * Perform common "simple" tasks: redirect to a different page and
+ render a given template.
+
+ * Display list and detail pages for a single object. If we were creating an
+ application to manage conferences then a ``talk_list`` view and a
+ ``registered_user_list`` view would be examples of list views. A single
+ talk page is an example of what we call a "detail" view.
+
+ * Present date-based objects in year/month/day archive pages,
+ associated detail, and "latest" pages. The Django Weblog's
+ (http://www.djangoproject.com/weblog/) year, month, and
+ day archives are built with these, as would be a typical
+ newspaper's archives.
+
+ * Allow users to create, update, and delete objects -- with or
+ without authorization.
+
+Taken together, these views provide easy interfaces to perform the most common
+tasks developers encounter.
+
+Using generic views
+===================
+
+All of these views are used by creating configuration dictionaries in
+your URLconf files and passing those dictionaries as the third member of the
+URLconf tuple for a given pattern.
+
+For example, here's a simple URLconf you could use to present a static "about"
+page::
+
+ from django.conf.urls.defaults import *
+ from django.views.generic.simple import direct_to_template
+
+ urlpatterns = patterns('',
+ ('^about/$', direct_to_template, {
+ 'template': 'about.html'
+ })
+ )
+
+Though this might seem a bit "magical" at first glance -- look, a view with no
+code! --, actually the ``direct_to_template`` view simply grabs information from
+the extra-parameters dictionary and uses that information when rendering the
+view.
+
+Because this generic view -- and all the others -- is a regular view function
+like any other, we can reuse it inside our own views. As an example, let's
+extend our "about" example to map URLs of the form ``/about/<whatever>/`` to
+statically rendered ``about/<whatever>.html``. We'll do this by first modifying
+the URLconf to point to a view function:
+
+.. parsed-literal::
+
+ from django.conf.urls.defaults import *
+ from django.views.generic.simple import direct_to_template
+ **from books.views import about_pages**
+
+ urlpatterns = patterns('',
+ ('^about/$', direct_to_template, {
+ 'template': 'about.html'
+ }),
+ **('^about/(\\w+)/$', about_pages),**
+ )
+
+Next, we'll write the ``about_pages`` view::
+
+ from django.http import Http404
+ from django.template import TemplateDoesNotExist
+ from django.views.generic.simple import direct_to_template
+
+ def about_pages(request, page):
+ try:
+ return direct_to_template(request, template="about/%s.html" % page)
+ except TemplateDoesNotExist:
+ raise Http404()
+
+Here we're treating ``direct_to_template`` like any other function. Since it
+returns an ``HttpResponse``, we can simply return it as-is. The only slightly
+tricky business here is dealing with missing templates. We don't want a
+nonexistent template to cause a server error, so we catch
+``TemplateDoesNotExist`` exceptions and return 404 errors instead.
+
+.. admonition:: Is there a security vulnerability here?
+
+ Sharp-eyed readers may have noticed a possible security hole: we're
+ constructing the template name using interpolated content from the browser
+ (``template="about/%s.html" % page``). At first glance, this looks like a
+ classic *directory traversal* vulnerability. But is it really?
+
+ Not exactly. Yes, a maliciously crafted value of ``page`` could cause
+ directory traversal, but although ``page`` *is* taken from the request URL,
+ not every value will be accepted. The key is in the URLconf: we're using
+ the regular expression ``\w+`` to match the ``page`` part of the URL, and
+ ``\w`` only accepts letters and numbers. Thus, any malicious characters
+ (dots and slashes, here) will be rejected by the URL resolver before they
+ reach the view itself.
+
+Generic views of objects
+========================
+
+The ``direct_to_template`` certainly is useful, but Django's generic views
+really shine when it comes to presenting views on your database content. Because
+it's such a common task, Django comes with a handful of built-in generic views
+that make generating list and detail views of objects incredibly easy.
+
+Let's take a look at one of these generic views: the "object list" view. We'll
+be using these models::
+
+ # models.py
+ from django.db import models
+
+ class Publisher(models.Model):
+ name = models.CharField(max_length=30)
+ address = models.CharField(max_length=50)
+ city = models.CharField(max_length=60)
+ state_province = models.CharField(max_length=30)
+ country = models.CharField(max_length=50)
+ website = models.URLField()
+
+ def __unicode__(self):
+ return self.name
+
+ class Meta:
+ ordering = ["-name"]
+
+ class Book(models.Model):
+ title = models.CharField(max_length=100)
+ authors = models.ManyToManyField('Author')
+ publisher = models.ForeignKey(Publisher)
+ publication_date = models.DateField()
+
+To build a list page of all publishers, we'd use a URLconf along these lines::
+
+ from django.conf.urls.defaults import *
+ from django.views.generic import list_detail
+ from books.models import Publisher
+
+ publisher_info = {
+ "queryset" : Publisher.objects.all(),
+ }
+
+ urlpatterns = patterns('',
+ (r'^publishers/$', list_detail.object_list, publisher_info)
+ )
+
+That's all the Python code we need to write. We still need to write a template,
+however. We could explicitly tell the ``object_list`` view which template to use
+by including a ``template_name`` key in the extra arguments dictionary, but in
+the absence of an explicit template Django will infer one from the object's
+name. In this case, the inferred template will be
+``"books/publisher_list.html"`` -- the "books" part comes from the name of the
+app that defines the model, while the "publisher" bit is just the lowercased
+version of the model's name.
+
+.. highlightlang:: html+django
+
+This template will be rendered against a context containing a variable called
+``object_list`` that contains all the publisher objects. A very simple template
+might look like the following::
+
+ {% extends "base.html" %}
+
+ {% block content %}
+ <h2>Publishers</h2>
+ <ul>
+ {% for publisher in object_list %}
+ <li>{{ publisher.name }}</li>
+ {% endfor %}
+ </ul>
+ {% endblock %}
+
+That's really all there is to it. All the cool features of generic views come
+from changing the "info" dictionary passed to the generic view. The
+:doc:`generic views reference</ref/generic-views>` documents all the generic
+views and all their options in detail; the rest of this document will consider
+some of the common ways you might customize and extend generic views.
+
+Extending generic views
+=======================
+
+.. highlightlang:: python
+
+There's no question that using generic views can speed up development
+substantially. In most projects, however, there comes a moment when the
+generic views no longer suffice. Indeed, the most common question asked by new
+Django developers is how to make generic views handle a wider array of
+situations.
+
+Luckily, in nearly every one of these cases, there are ways to simply extend
+generic views to handle a larger array of use cases. These situations usually
+fall into a handful of patterns dealt with in the sections that follow.
+
+Making "friendly" template contexts
+-----------------------------------
+
+You might have noticed that our sample publisher list template stores all the
+books in a variable named ``object_list``. While this works just fine, it isn't
+all that "friendly" to template authors: they have to "just know" that they're
+dealing with publishers here. A better name for that variable would be
+``publisher_list``; that variable's content is pretty obvious.
+
+We can change the name of that variable easily with the ``template_object_name``
+argument:
+
+.. parsed-literal::
+
+ publisher_info = {
+ "queryset" : Publisher.objects.all(),
+ **"template_object_name" : "publisher",**
+ }
+
+ urlpatterns = patterns('',
+ (r'^publishers/$', list_detail.object_list, publisher_info)
+ )
+
+Providing a useful ``template_object_name`` is always a good idea. Your
+coworkers who design templates will thank you.
+
+Adding extra context
+--------------------
+
+Often you simply need to present some extra information beyond that provided by
+the generic view. For example, think of showing a list of all the books on each
+publisher detail page. The ``object_detail`` generic view provides the
+publisher to the context, but it seems there's no way to get additional
+information in that template.
+
+But there is: all generic views take an extra optional parameter,
+``extra_context``. This is a dictionary of extra objects that will be added to
+the template's context. So, to provide the list of all books on the detail
+detail view, we'd use an info dict like this:
+
+.. parsed-literal::
+
+ from books.models import Publisher, **Book**
+
+ publisher_info = {
+ "queryset" : Publisher.objects.all(),
+ "template_object_name" : "publisher",
+ **"extra_context" : {"book_list" : Book.objects.all()}**
+ }
+
+This would populate a ``{{ book_list }}`` variable in the template context.
+This pattern can be used to pass any information down into the template for the
+generic view. It's very handy.
+
+However, there's actually a subtle bug here -- can you spot it?
+
+The problem has to do with when the queries in ``extra_context`` are evaluated.
+Because this example puts ``Book.objects.all()`` in the URLconf, it will
+be evaluated only once (when the URLconf is first loaded). Once you add or
+remove books, you'll notice that the generic view doesn't reflect those
+changes until you reload the Web server (see :ref:`caching-and-querysets`
+for more information about when QuerySets are cached and evaluated).
+
+.. note::
+
+ This problem doesn't apply to the ``queryset`` generic view argument. Since
+ Django knows that particular QuerySet should *never* be cached, the generic
+ view takes care of clearing the cache when each view is rendered.
+
+The solution is to use a callback in ``extra_context`` instead of a value. Any
+callable (i.e., a function) that's passed to ``extra_context`` will be evaluated
+when the view is rendered (instead of only once). You could do this with an
+explicitly defined function:
+
+.. parsed-literal::
+
+ def get_books():
+ return Book.objects.all()
+
+ publisher_info = {
+ "queryset" : Publisher.objects.all(),
+ "template_object_name" : "publisher",
+ "extra_context" : **{"book_list" : get_books}**
+ }
+
+or you could use a less obvious but shorter version that relies on the fact that
+``Book.objects.all`` is itself a callable:
+
+.. parsed-literal::
+
+ publisher_info = {
+ "queryset" : Publisher.objects.all(),
+ "template_object_name" : "publisher",
+ "extra_context" : **{"book_list" : Book.objects.all}**
+ }
+
+Notice the lack of parentheses after ``Book.objects.all``; this references
+the function without actually calling it (which the generic view will do later).
+
+Viewing subsets of objects
+--------------------------
+
+Now let's take a closer look at this ``queryset`` key we've been using all
+along. Most generic views take one of these ``queryset`` arguments -- it's how
+the view knows which set of objects to display (see :doc:`/topics/db/queries` for
+more information about ``QuerySet`` objects, and see the
+:doc:`generic views reference</ref/generic-views>` for the complete details).
+
+To pick a simple example, we might want to order a list of books by
+publication date, with the most recent first:
+
+.. parsed-literal::
+
+ book_info = {
+ "queryset" : Book.objects.all().order_by("-publication_date"),
+ }
+
+ urlpatterns = patterns('',
+ (r'^publishers/$', list_detail.object_list, publisher_info),
+ **(r'^books/$', list_detail.object_list, book_info),**
+ )
+
+
+That's a pretty simple example, but it illustrates the idea nicely. Of course,
+you'll usually want to do more than just reorder objects. If you want to
+present a list of books by a particular publisher, you can use the same
+technique:
+
+.. parsed-literal::
+
+ **acme_books = {**
+ **"queryset": Book.objects.filter(publisher__name="Acme Publishing"),**
+ **"template_name" : "books/acme_list.html"**
+ **}**
+
+ urlpatterns = patterns('',
+ (r'^publishers/$', list_detail.object_list, publisher_info),
+ **(r'^books/acme/$', list_detail.object_list, acme_books),**
+ )
+
+Notice that along with a filtered ``queryset``, we're also using a custom
+template name. If we didn't, the generic view would use the same template as the
+"vanilla" object list, which might not be what we want.
+
+Also notice that this isn't a very elegant way of doing publisher-specific
+books. If we want to add another publisher page, we'd need another handful of
+lines in the URLconf, and more than a few publishers would get unreasonable.
+We'll deal with this problem in the next section.
+
+.. note::
+
+ If you get a 404 when requesting ``/books/acme/``, check to ensure you
+ actually have a Publisher with the name 'ACME Publishing'. Generic
+ views have an ``allow_empty`` parameter for this case. See the
+ :doc:`generic views reference</ref/generic-views>` for more details.
+
+Complex filtering with wrapper functions
+----------------------------------------
+
+Another common need is to filter down the objects given in a list page by some
+key in the URL. Earlier we hard-coded the publisher's name in the URLconf, but
+what if we wanted to write a view that displayed all the books by some arbitrary
+publisher? We can "wrap" the ``object_list`` generic view to avoid writing a lot
+of code by hand. As usual, we'll start by writing a URLconf:
+
+.. parsed-literal::
+
+ from books.views import books_by_publisher
+
+ urlpatterns = patterns('',
+ (r'^publishers/$', list_detail.object_list, publisher_info),
+ **(r'^books/(\\w+)/$', books_by_publisher),**
+ )
+
+Next, we'll write the ``books_by_publisher`` view itself::
+
+ from django.http import Http404
+ from django.views.generic import list_detail
+ from books.models import Book, Publisher
+
+ def books_by_publisher(request, name):
+
+ # Look up the publisher (and raise a 404 if it can't be found).
+ try:
+ publisher = Publisher.objects.get(name__iexact=name)
+ except Publisher.DoesNotExist:
+ raise Http404
+
+ # Use the object_list view for the heavy lifting.
+ return list_detail.object_list(
+ request,
+ queryset = Book.objects.filter(publisher=publisher),
+ template_name = "books/books_by_publisher.html",
+ template_object_name = "books",
+ extra_context = {"publisher" : publisher}
+ )
+
+This works because there's really nothing special about generic views -- they're
+just Python functions. Like any view function, generic views expect a certain
+set of arguments and return ``HttpResponse`` objects. Thus, it's incredibly easy
+to wrap a small function around a generic view that does additional work before
+(or after; see the next section) handing things off to the generic view.
+
+.. note::
+
+ Notice that in the preceding example we passed the current publisher being
+ displayed in the ``extra_context``. This is usually a good idea in wrappers
+ of this nature; it lets the template know which "parent" object is currently
+ being browsed.
+
+Performing extra work
+---------------------
+
+The last common pattern we'll look at involves doing some extra work before
+or after calling the generic view.
+
+Imagine we had a ``last_accessed`` field on our ``Author`` object that we were
+using to keep track of the last time anybody looked at that author::
+
+ # models.py
+
+ class Author(models.Model):
+ salutation = models.CharField(max_length=10)
+ first_name = models.CharField(max_length=30)
+ last_name = models.CharField(max_length=40)
+ email = models.EmailField()
+ headshot = models.ImageField(upload_to='/tmp')
+ last_accessed = models.DateTimeField()
+
+The generic ``object_detail`` view, of course, wouldn't know anything about this
+field, but once again we could easily write a custom view to keep that field
+updated.
+
+First, we'd need to add an author detail bit in the URLconf to point to a
+custom view:
+
+.. parsed-literal::
+
+ from books.views import author_detail
+
+ urlpatterns = patterns('',
+ #...
+ **(r'^authors/(?P<author_id>\\d+)/$', author_detail),**
+ )
+
+Then we'd write our wrapper function::
+
+ import datetime
+ from books.models import Author
+ from django.views.generic import list_detail
+ from django.shortcuts import get_object_or_404
+
+ def author_detail(request, author_id):
+ # Look up the Author (and raise a 404 if she's not found)
+ author = get_object_or_404(Author, pk=author_id)
+
+ # Record the last accessed date
+ author.last_accessed = datetime.datetime.now()
+ author.save()
+
+ # Show the detail page
+ return list_detail.object_detail(
+ request,
+ queryset = Author.objects.all(),
+ object_id = author_id,
+ )
+
+.. note::
+
+ This code won't actually work unless you create a
+ ``books/author_detail.html`` template.
+
+We can use a similar idiom to alter the response returned by the generic view.
+If we wanted to provide a downloadable plain-text version of the list of
+authors, we could use a view like this::
+
+ def author_list_plaintext(request):
+ response = list_detail.object_list(
+ request,
+ queryset = Author.objects.all(),
+ mimetype = "text/plain",
+ template_name = "books/author_list.txt"
+ )
+ response["Content-Disposition"] = "attachment; filename=authors.txt"
+ return response
+
+This works because the generic views return simple ``HttpResponse`` objects
+that can be treated like dictionaries to set HTTP headers. This
+``Content-Disposition`` business, by the way, instructs the browser to
+download and save the page instead of displaying it in the browser.
diff --git a/parts/django/docs/topics/http/_images/middleware.png b/parts/django/docs/topics/http/_images/middleware.png
new file mode 100644
index 0000000..505c70a
--- /dev/null
+++ b/parts/django/docs/topics/http/_images/middleware.png
Binary files differ
diff --git a/parts/django/docs/topics/http/file-uploads.txt b/parts/django/docs/topics/http/file-uploads.txt
new file mode 100644
index 0000000..a06a1ca
--- /dev/null
+++ b/parts/django/docs/topics/http/file-uploads.txt
@@ -0,0 +1,394 @@
+============
+File Uploads
+============
+
+.. currentmodule:: django.core.files
+
+.. versionadded:: 1.0
+
+When Django handles a file upload, the file data ends up placed in
+:attr:`request.FILES <django.http.HttpRequest.FILES>` (for more on the
+``request`` object see the documentation for :doc:`request and response objects
+</ref/request-response>`). This document explains how files are stored on disk
+and in memory, and how to customize the default behavior.
+
+Basic file uploads
+==================
+
+Consider a simple form containing a :class:`~django.forms.FileField`::
+
+ from django import forms
+
+ class UploadFileForm(forms.Form):
+ title = forms.CharField(max_length=50)
+ file = forms.FileField()
+
+A view handling this form will receive the file data in
+:attr:`request.FILES <django.http.HttpRequest.FILES>`, which is a dictionary
+containing a key for each :class:`~django.forms.FileField` (or
+:class:`~django.forms.ImageField`, or other :class:`~django.forms.FileField`
+subclass) in the form. So the data from the above form would
+be accessible as ``request.FILES['file']``.
+
+Note that :attr:`request.FILES <django.http.HttpRequest.FILES>` will only
+contain data if the request method was ``POST`` and the ``<form>`` that posted
+the request has the attribute ``enctype="multipart/form-data"``. Otherwise,
+``request.FILES`` will be empty.
+
+Most of the time, you'll simply pass the file data from ``request`` into the
+form as described in :ref:`binding-uploaded-files`. This would look
+something like::
+
+ from django.http import HttpResponseRedirect
+ from django.shortcuts import render_to_response
+
+ # Imaginary function to handle an uploaded file.
+ from somewhere import handle_uploaded_file
+
+ def upload_file(request):
+ if request.method == 'POST':
+ form = UploadFileForm(request.POST, request.FILES)
+ if form.is_valid():
+ handle_uploaded_file(request.FILES['file'])
+ return HttpResponseRedirect('/success/url/')
+ else:
+ form = UploadFileForm()
+ return render_to_response('upload.html', {'form': form})
+
+Notice that we have to pass :attr:`request.FILES <django.http.HttpRequest.FILES>`
+into the form's constructor; this is how file data gets bound into a form.
+
+Handling uploaded files
+-----------------------
+
+The final piece of the puzzle is handling the actual file data from
+:attr:`request.FILES <django.http.HttpRequest.FILES>`. Each entry in this
+dictionary is an ``UploadedFile`` object -- a simple wrapper around an uploaded
+file. You'll usually use one of these methods to access the uploaded content:
+
+ ``UploadedFile.read()``
+ Read the entire uploaded data from the file. Be careful with this
+ method: if the uploaded file is huge it can overwhelm your system if you
+ try to read it into memory. You'll probably want to use ``chunks()``
+ instead; see below.
+
+ ``UploadedFile.multiple_chunks()``
+ Returns ``True`` if the uploaded file is big enough to require
+ reading in multiple chunks. By default this will be any file
+ larger than 2.5 megabytes, but that's configurable; see below.
+
+ ``UploadedFile.chunks()``
+ A generator returning chunks of the file. If ``multiple_chunks()`` is
+ ``True``, you should use this method in a loop instead of ``read()``.
+
+ In practice, it's often easiest simply to use ``chunks()`` all the time;
+ see the example below.
+
+ ``UploadedFile.name``
+ The name of the uploaded file (e.g. ``my_file.txt``).
+
+ ``UploadedFile.size``
+ The size, in bytes, of the uploaded file.
+
+There are a few other methods and attributes available on ``UploadedFile``
+objects; see `UploadedFile objects`_ for a complete reference.
+
+Putting it all together, here's a common way you might handle an uploaded file::
+
+ def handle_uploaded_file(f):
+ destination = open('some/file/name.txt', 'wb+')
+ for chunk in f.chunks():
+ destination.write(chunk)
+ destination.close()
+
+Looping over ``UploadedFile.chunks()`` instead of using ``read()`` ensures that
+large files don't overwhelm your system's memory.
+
+Where uploaded data is stored
+-----------------------------
+
+Before you save uploaded files, the data needs to be stored somewhere.
+
+By default, if an uploaded file is smaller than 2.5 megabytes, Django will hold
+the entire contents of the upload in memory. This means that saving the file
+involves only a read from memory and a write to disk and thus is very fast.
+
+However, if an uploaded file is too large, Django will write the uploaded file
+to a temporary file stored in your system's temporary directory. On a Unix-like
+platform this means you can expect Django to generate a file called something
+like ``/tmp/tmpzfp6I6.upload``. If an upload is large enough, you can watch this
+file grow in size as Django streams the data onto disk.
+
+These specifics -- 2.5 megabytes; ``/tmp``; etc. -- are simply "reasonable
+defaults". Read on for details on how you can customize or completely replace
+upload behavior.
+
+Changing upload handler behavior
+--------------------------------
+
+Three settings control Django's file upload behavior:
+
+ :setting:`FILE_UPLOAD_MAX_MEMORY_SIZE`
+ The maximum size, in bytes, for files that will be uploaded into memory.
+ Files larger than :setting:`FILE_UPLOAD_MAX_MEMORY_SIZE` will be
+ streamed to disk.
+
+ Defaults to 2.5 megabytes.
+
+ :setting:`FILE_UPLOAD_TEMP_DIR`
+ The directory where uploaded files larger than
+ :setting:`FILE_UPLOAD_MAX_MEMORY_SIZE` will be stored.
+
+ Defaults to your system's standard temporary directory (i.e. ``/tmp`` on
+ most Unix-like systems).
+
+ :setting:`FILE_UPLOAD_PERMISSIONS`
+ The numeric mode (i.e. ``0644``) to set newly uploaded files to. For
+ more information about what these modes mean, see the `documentation for
+ os.chmod`_
+
+ If this isn't given or is ``None``, you'll get operating-system
+ dependent behavior. On most platforms, temporary files will have a mode
+ of ``0600``, and files saved from memory will be saved using the
+ system's standard umask.
+
+ .. warning::
+
+ If you're not familiar with file modes, please note that the leading
+ ``0`` is very important: it indicates an octal number, which is the
+ way that modes must be specified. If you try to use ``644``, you'll
+ get totally incorrect behavior.
+
+ **Always prefix the mode with a 0.**
+
+ :setting:`FILE_UPLOAD_HANDLERS`
+ The actual handlers for uploaded files. Changing this setting allows
+ complete customization -- even replacement -- of Django's upload
+ process. See `upload handlers`_, below, for details.
+
+ Defaults to::
+
+ ("django.core.files.uploadhandler.MemoryFileUploadHandler",
+ "django.core.files.uploadhandler.TemporaryFileUploadHandler",)
+
+ Which means "try to upload to memory first, then fall back to temporary
+ files."
+
+.. _documentation for os.chmod: http://docs.python.org/library/os.html#os.chmod
+
+``UploadedFile`` objects
+========================
+
+.. class:: UploadedFile
+
+In addition to those inherited from :class:`File`, all ``UploadedFile`` objects
+define the following methods/attributes:
+
+ ``UploadedFile.content_type``
+ The content-type header uploaded with the file (e.g. ``text/plain`` or
+ ``application/pdf``). Like any data supplied by the user, you shouldn't
+ trust that the uploaded file is actually this type. You'll still need to
+ validate that the file contains the content that the content-type header
+ claims -- "trust but verify."
+
+ ``UploadedFile.charset``
+ For ``text/*`` content-types, the character set (i.e. ``utf8``) supplied
+ by the browser. Again, "trust but verify" is the best policy here.
+
+ ``UploadedFile.temporary_file_path()``
+ Only files uploaded onto disk will have this method; it returns the full
+ path to the temporary uploaded file.
+
+.. note::
+
+ Like regular Python files, you can read the file line-by-line simply by
+ iterating over the uploaded file:
+
+ .. code-block:: python
+
+ for line in uploadedfile:
+ do_something_with(line)
+
+ However, *unlike* standard Python files, :class:`UploadedFile` only
+ understands ``\n`` (also known as "Unix-style") line endings. If you know
+ that you need to handle uploaded files with different line endings, you'll
+ need to do so in your view.
+
+Upload Handlers
+===============
+
+When a user uploads a file, Django passes off the file data to an *upload
+handler* -- a small class that handles file data as it gets uploaded. Upload
+handlers are initially defined in the ``FILE_UPLOAD_HANDLERS`` setting, which
+defaults to::
+
+ ("django.core.files.uploadhandler.MemoryFileUploadHandler",
+ "django.core.files.uploadhandler.TemporaryFileUploadHandler",)
+
+Together the ``MemoryFileUploadHandler`` and ``TemporaryFileUploadHandler``
+provide Django's default file upload behavior of reading small files into memory
+and large ones onto disk.
+
+You can write custom handlers that customize how Django handles files. You
+could, for example, use custom handlers to enforce user-level quotas, compress
+data on the fly, render progress bars, and even send data to another storage
+location directly without storing it locally.
+
+Modifying upload handlers on the fly
+------------------------------------
+
+Sometimes particular views require different upload behavior. In these cases,
+you can override upload handlers on a per-request basis by modifying
+``request.upload_handlers``. By default, this list will contain the upload
+handlers given by ``FILE_UPLOAD_HANDLERS``, but you can modify the list as you
+would any other list.
+
+For instance, suppose you've written a ``ProgressBarUploadHandler`` that
+provides feedback on upload progress to some sort of AJAX widget. You'd add this
+handler to your upload handlers like this::
+
+ request.upload_handlers.insert(0, ProgressBarUploadHandler())
+
+You'd probably want to use ``list.insert()`` in this case (instead of
+``append()``) because a progress bar handler would need to run *before* any
+other handlers. Remember, the upload handlers are processed in order.
+
+If you want to replace the upload handlers completely, you can just assign a new
+list::
+
+ request.upload_handlers = [ProgressBarUploadHandler()]
+
+.. note::
+
+ You can only modify upload handlers *before* accessing
+ ``request.POST`` or ``request.FILES`` -- it doesn't make sense to
+ change upload handlers after upload handling has already
+ started. If you try to modify ``request.upload_handlers`` after
+ reading from ``request.POST`` or ``request.FILES`` Django will
+ throw an error.
+
+ Thus, you should always modify uploading handlers as early in your view as
+ possible.
+
+ Also, ``request.POST`` is accessed by
+ :class:`~django.middleware.csrf.CsrfViewMiddleware` which is enabled by
+ default. This means you will probably need to use
+ :func:`~django.views.decorators.csrf.csrf_exempt` on your view to allow you
+ to change the upload handlers. Assuming you do need CSRF protection, you
+ will then need to use :func:`~django.views.decorators.csrf.csrf_protect` on
+ the function that actually processes the request. Note that this means that
+ the handlers may start receiving the file upload before the CSRF checks have
+ been done. Example code:
+
+ .. code-block:: python
+
+ from django.views.decorators.csrf import csrf_exempt, csrf_protect
+
+ @csrf_exempt
+ def upload_file_view(request):
+ request.upload_handlers.insert(0, ProgressBarUploadHandler())
+ return _upload_file_view(request)
+
+ @csrf_protect
+ def _upload_file_view(request):
+ ... # Process request
+
+
+Writing custom upload handlers
+------------------------------
+
+All file upload handlers should be subclasses of
+``django.core.files.uploadhandler.FileUploadHandler``. You can define upload
+handlers wherever you wish.
+
+Required methods
+~~~~~~~~~~~~~~~~
+
+Custom file upload handlers **must** define the following methods:
+
+ ``FileUploadHandler.receive_data_chunk(self, raw_data, start)``
+ Receives a "chunk" of data from the file upload.
+
+ ``raw_data`` is a byte string containing the uploaded data.
+
+ ``start`` is the position in the file where this ``raw_data`` chunk
+ begins.
+
+ The data you return will get fed into the subsequent upload handlers'
+ ``receive_data_chunk`` methods. In this way, one handler can be a
+ "filter" for other handlers.
+
+ Return ``None`` from ``receive_data_chunk`` to sort-circuit remaining
+ upload handlers from getting this chunk.. This is useful if you're
+ storing the uploaded data yourself and don't want future handlers to
+ store a copy of the data.
+
+ If you raise a ``StopUpload`` or a ``SkipFile`` exception, the upload
+ will abort or the file will be completely skipped.
+
+ ``FileUploadHandler.file_complete(self, file_size)``
+ Called when a file has finished uploading.
+
+ The handler should return an ``UploadedFile`` object that will be stored
+ in ``request.FILES``. Handlers may also return ``None`` to indicate that
+ the ``UploadedFile`` object should come from subsequent upload handlers.
+
+Optional methods
+~~~~~~~~~~~~~~~~
+
+Custom upload handlers may also define any of the following optional methods or
+attributes:
+
+ ``FileUploadHandler.chunk_size``
+ Size, in bytes, of the "chunks" Django should store into memory and feed
+ into the handler. That is, this attribute controls the size of chunks
+ fed into ``FileUploadHandler.receive_data_chunk``.
+
+ For maximum performance the chunk sizes should be divisible by ``4`` and
+ should not exceed 2 GB (2\ :sup:`31` bytes) in size. When there are
+ multiple chunk sizes provided by multiple handlers, Django will use the
+ smallest chunk size defined by any handler.
+
+ The default is 64*2\ :sup:`10` bytes, or 64 KB.
+
+ ``FileUploadHandler.new_file(self, field_name, file_name, content_type, content_length, charset)``
+ Callback signaling that a new file upload is starting. This is called
+ before any data has been fed to any upload handlers.
+
+ ``field_name`` is a string name of the file ``<input>`` field.
+
+ ``file_name`` is the unicode filename that was provided by the browser.
+
+ ``content_type`` is the MIME type provided by the browser -- E.g.
+ ``'image/jpeg'``.
+
+ ``content_length`` is the length of the image given by the browser.
+ Sometimes this won't be provided and will be ``None``.
+
+ ``charset`` is the character set (i.e. ``utf8``) given by the browser.
+ Like ``content_length``, this sometimes won't be provided.
+
+ This method may raise a ``StopFutureHandlers`` exception to prevent
+ future handlers from handling this file.
+
+ ``FileUploadHandler.upload_complete(self)``
+ Callback signaling that the entire upload (all files) has completed.
+
+ ``FileUploadHandler.handle_raw_input(self, input_data, META, content_length, boundary, encoding)``
+ Allows the handler to completely override the parsing of the raw
+ HTTP input.
+
+ ``input_data`` is a file-like object that supports ``read()``-ing.
+
+ ``META`` is the same object as ``request.META``.
+
+ ``content_length`` is the length of the data in ``input_data``. Don't
+ read more than ``content_length`` bytes from ``input_data``.
+
+ ``boundary`` is the MIME boundary for this request.
+
+ ``encoding`` is the encoding of the request.
+
+ Return ``None`` if you want upload handling to continue, or a tuple of
+ ``(POST, FILES)`` if you want to return the new data structures suitable
+ for the request directly.
diff --git a/parts/django/docs/topics/http/generic-views.txt b/parts/django/docs/topics/http/generic-views.txt
new file mode 100644
index 0000000..15f895e
--- /dev/null
+++ b/parts/django/docs/topics/http/generic-views.txt
@@ -0,0 +1,5 @@
+=============
+Generic views
+=============
+
+See :doc:`/ref/generic-views`.
diff --git a/parts/django/docs/topics/http/index.txt b/parts/django/docs/topics/http/index.txt
new file mode 100644
index 0000000..5ef776d
--- /dev/null
+++ b/parts/django/docs/topics/http/index.txt
@@ -0,0 +1,15 @@
+Handling HTTP requests
+======================
+
+Information on handling HTTP requests in Django:
+
+.. toctree::
+ :maxdepth: 1
+
+ urls
+ views
+ file-uploads
+ shortcuts
+ generic-views
+ middleware
+ sessions
diff --git a/parts/django/docs/topics/http/middleware.txt b/parts/django/docs/topics/http/middleware.txt
new file mode 100644
index 0000000..d376c6b
--- /dev/null
+++ b/parts/django/docs/topics/http/middleware.txt
@@ -0,0 +1,179 @@
+==========
+Middleware
+==========
+
+Middleware is a framework of hooks into Django's request/response processing.
+It's a light, low-level "plugin" system for globally altering Django's input
+and/or output.
+
+Each middleware component is responsible for doing some specific function. For
+example, Django includes a middleware component, ``XViewMiddleware``, that adds
+an ``"X-View"`` HTTP header to every response to a ``HEAD`` request.
+
+This document explains how middleware works, how you activate middleware, and
+how to write your own middleware. Django ships with some built-in middleware
+you can use right out of the box; they're documented in the :doc:`built-in
+middleware reference </ref/middleware>`.
+
+Activating middleware
+=====================
+
+To activate a middleware component, add it to the :setting:`MIDDLEWARE_CLASSES`
+list in your Django settings. In :setting:`MIDDLEWARE_CLASSES`, each middleware
+component is represented by a string: the full Python path to the middleware's
+class name. For example, here's the default :setting:`MIDDLEWARE_CLASSES`
+created by :djadmin:`django-admin.py startproject <startproject>`::
+
+ MIDDLEWARE_CLASSES = (
+ 'django.middleware.common.CommonMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
+ )
+
+During the request phases (:meth:`process_request` and :meth:`process_view`
+middleware), Django applies middleware in the order it's defined in
+:setting:`MIDDLEWARE_CLASSES`, top-down. During the response phases
+(:meth:`process_response` and :meth:`process_exception` middleware), the
+classes are applied in reverse order, from the bottom up. You can think of it
+like an onion: each middleware class is a "layer" that wraps the view:
+
+.. image:: _images/middleware.png
+ :width: 502
+ :height: 417
+ :alt: Middleware application order.
+
+A Django installation doesn't require any middleware -- e.g.,
+:setting:`MIDDLEWARE_CLASSES` can be empty, if you'd like -- but it's strongly
+suggested that you at least use
+:class:`~django.middleware.common.CommonMiddleware`.
+
+Writing your own middleware
+===========================
+
+Writing your own middleware is easy. Each middleware component is a single
+Python class that defines one or more of the following methods:
+
+.. _request-middleware:
+
+``process_request``
+-------------------
+
+.. method:: process_request(self, request)
+
+``request`` is an :class:`~django.http.HttpRequest` object. This method is
+called on each request, before Django decides which view to execute.
+
+``process_request()`` should return either ``None`` or an
+:class:`~django.http.HttpResponse` object. If it returns ``None``, Django will
+continue processing this request, executing any other middleware and, then, the
+appropriate view. If it returns an :class:`~django.http.HttpResponse` object,
+Django won't bother calling ANY other request, view or exception middleware, or
+the appropriate view; it'll return that :class:`~django.http.HttpResponse`.
+Response middleware is always called on every response.
+
+.. _view-middleware:
+
+``process_view``
+----------------
+
+.. method:: process_view(self, request, view_func, view_args, view_kwargs)
+
+``request`` is an :class:`~django.http.HttpRequest` object. ``view_func`` is
+the Python function that Django is about to use. (It's the actual function
+object, not the name of the function as a string.) ``view_args`` is a list of
+positional arguments that will be passed to the view, and ``view_kwargs`` is a
+dictionary of keyword arguments that will be passed to the view. Neither
+``view_args`` nor ``view_kwargs`` include the first view argument
+(``request``).
+
+``process_view()`` is called just before Django calls the view. It should
+return either ``None`` or an :class:`~django.http.HttpResponse` object. If it
+returns ``None``, Django will continue processing this request, executing any
+other ``process_view()`` middleware and, then, the appropriate view. If it
+returns an :class:`~django.http.HttpResponse` object, Django won't bother
+calling ANY other request, view or exception middleware, or the appropriate
+view; it'll return that :class:`~django.http.HttpResponse`. Response
+middleware is always called on every response.
+
+.. _response-middleware:
+
+``process_response``
+--------------------
+
+.. method:: process_response(self, request, response)
+
+``request`` is an :class:`~django.http.HttpRequest` object. ``response`` is the
+:class:`~django.http.HttpResponse` object returned by a Django view.
+
+``process_response()`` must return an :class:`~django.http.HttpResponse`
+object. It could alter the given ``response``, or it could create and return a
+brand-new :class:`~django.http.HttpResponse`.
+
+Unlike the ``process_request()`` and ``process_view()`` methods, the
+``process_response()`` method is always called, even if the ``process_request()``
+and ``process_view()`` methods of the same middleware class were skipped because
+an earlier middleware method returned an :class:`~django.http.HttpResponse`
+(this means that your ``process_response()`` method cannot rely on setup done in
+``process_request()``, for example). In addition, during the response phase the
+classes are applied in reverse order, from the bottom up. This means classes
+defined at the end of :setting:`MIDDLEWARE_CLASSES` will be run first.
+
+.. _exception-middleware:
+
+``process_exception``
+---------------------
+
+.. method:: process_exception(self, request, exception)
+
+``request`` is an :class:`~django.http.HttpRequest` object. ``exception`` is an
+``Exception`` object raised by the view function.
+
+Django calls ``process_exception()`` when a view raises an exception.
+``process_exception()`` should return either ``None`` or an
+:class:`~django.http.HttpResponse` object. If it returns an
+:class:`~django.http.HttpResponse` object, the response will be returned to
+the browser. Otherwise, default exception handling kicks in.
+
+Again, middleware are run in reverse order during the response phase, which
+includes ``process_exception``. If an exception middleware return a response,
+the middleware classes above that middleware will not be called at all.
+
+``__init__``
+------------
+
+Most middleware classes won't need an initializer since middleware classes are
+essentially placeholders for the ``process_*`` methods. If you do need some
+global state you may use ``__init__`` to set up. However, keep in mind a couple
+of caveats:
+
+ * Django initializes your middleware without any arguments, so you can't
+ define ``__init__`` as requiring any arguments.
+
+ * Unlike the ``process_*`` methods which get called once per request,
+ ``__init__`` gets called only *once*, when the Web server starts up.
+
+Marking middleware as unused
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It's sometimes useful to determine at run-time whether a piece of middleware
+should be used. In these cases, your middleware's ``__init__`` method may raise
+``django.core.exceptions.MiddlewareNotUsed``. Django will then remove that
+piece of middleware from the middleware process.
+
+Guidelines
+----------
+
+ * Middleware classes don't have to subclass anything.
+
+ * The middleware class can live anywhere on your Python path. All Django
+ cares about is that the :setting:`MIDDLEWARE_CLASSES` setting includes
+ the path to it.
+
+ * Feel free to look at :doc:`Django's available middleware
+ </ref/middleware>` for examples.
+
+ * If you write a middleware component that you think would be useful to
+ other people, contribute to the community! :doc:`Let us know
+ </internals/contributing>`, and we'll consider adding it to Django.
diff --git a/parts/django/docs/topics/http/sessions.txt b/parts/django/docs/topics/http/sessions.txt
new file mode 100644
index 0000000..8a0f0d4
--- /dev/null
+++ b/parts/django/docs/topics/http/sessions.txt
@@ -0,0 +1,529 @@
+===================
+How to use sessions
+===================
+
+.. module:: django.contrib.sessions
+ :synopsis: Provides session management for Django projects.
+
+Django provides full support for anonymous sessions. The session framework lets
+you store and retrieve arbitrary data on a per-site-visitor basis. It stores
+data on the server side and abstracts the sending and receiving of cookies.
+Cookies contain a session ID -- not the data itself.
+
+Enabling sessions
+=================
+
+Sessions are implemented via a piece of :doc:`middleware </ref/middleware>`.
+
+To enable session functionality, do the following:
+
+ * Edit the ``MIDDLEWARE_CLASSES`` setting and make sure
+ ``MIDDLEWARE_CLASSES`` contains ``'django.contrib.sessions.middleware.SessionMiddleware'``.
+ The default ``settings.py`` created by ``django-admin.py startproject`` has
+ ``SessionMiddleware`` activated.
+
+If you don't want to use sessions, you might as well remove the
+``SessionMiddleware`` line from ``MIDDLEWARE_CLASSES`` and ``'django.contrib.sessions'``
+from your ``INSTALLED_APPS``. It'll save you a small bit of overhead.
+
+Configuring the session engine
+==============================
+
+.. versionadded:: 1.0
+
+By default, Django stores sessions in your database (using the model
+``django.contrib.sessions.models.Session``). Though this is convenient, in
+some setups it's faster to store session data elsewhere, so Django can be
+configured to store session data on your filesystem or in your cache.
+
+Using database-backed sessions
+------------------------------
+
+If you want to use a database-backed session, you need to add
+``'django.contrib.sessions'`` to your ``INSTALLED_APPS`` setting.
+
+Once you have configured your installation, run ``manage.py syncdb``
+to install the single database table that stores session data.
+
+Using cached sessions
+---------------------
+
+For better performance, you may want to use a cache-based session backend.
+
+.. versionchanged:: 1.1
+ Django 1.0 did not include the ``cached_db`` session backend.
+
+To store session data using Django's cache system, you'll first need to make
+sure you've configured your cache; see the :doc:`cache documentation
+</topics/cache>` for details.
+
+.. warning::
+
+ You should only use cache-based sessions if you're using the Memcached
+ cache backend. The local-memory cache backend doesn't retain data long
+ enough to be a good choice, and it'll be faster to use file or database
+ sessions directly instead of sending everything through the file or
+ database cache backends.
+
+Once your cache is configured, you've got two choices for how to store data in
+the cache:
+
+ * Set :setting:`SESSION_ENGINE` to
+ ``"django.contrib.sessions.backends.cache"`` for a simple caching session
+ store. Session data will be stored directly your cache. However, session
+ data may not be persistent: cached data can be evicted if the cache fills
+ up or if the cache server is restarted.
+
+ * For persistent, cached data, set :setting:`SESSION_ENGINE` to
+ ``"django.contrib.sessions.backends.cached_db"``. This uses a
+ write-through cache -- every write to the cache will also be written to
+ the database. Session reads only use the database if the data is not
+ already in the cache.
+
+Both session stores are quite fast, but the simple cache is faster because it
+disregards persistence. In most cases, the ``cached_db`` backend will be fast
+enough, but if you need that last bit of performance, and are willing to let
+session data be expunged from time to time, the ``cache`` backend is for you.
+
+If you use the ``cached_db`` session backend, you also need to follow the
+configuration instructions for the `using database-backed sessions`_.
+
+Using file-based sessions
+-------------------------
+
+To use file-based sessions, set the ``SESSION_ENGINE`` setting to
+``"django.contrib.sessions.backends.file"``.
+
+You might also want to set the ``SESSION_FILE_PATH`` setting (which defaults
+to output from ``tempfile.gettempdir()``, most likely ``/tmp``) to control
+where Django stores session files. Be sure to check that your Web server has
+permissions to read and write to this location.
+
+
+Using sessions in views
+=======================
+
+When ``SessionMiddleware`` is activated, each ``HttpRequest`` object -- the
+first argument to any Django view function -- will have a ``session``
+attribute, which is a dictionary-like object. You can read it and write to it.
+
+A session object has the following standard dictionary methods:
+
+ * ``__getitem__(key)``
+
+ Example: ``fav_color = request.session['fav_color']``
+
+ * ``__setitem__(key, value)``
+
+ Example: ``request.session['fav_color'] = 'blue'``
+
+ * ``__delitem__(key)``
+
+ Example: ``del request.session['fav_color']``. This raises ``KeyError``
+ if the given ``key`` isn't already in the session.
+
+ * ``__contains__(key)``
+
+ Example: ``'fav_color' in request.session``
+
+ * ``get(key, default=None)``
+
+ Example: ``fav_color = request.session.get('fav_color', 'red')``
+
+ * ``keys()``
+
+ * ``items()``
+
+ * ``setdefault()``
+
+ * ``clear()``
+
+.. versionadded:: 1.0
+ ``setdefault()`` and ``clear()`` are new in this version.
+
+It also has these methods:
+
+ * ``flush()``
+
+ .. versionadded:: 1.0
+
+ Delete the current session data from the session and regenerate the
+ session key value that is sent back to the user in the cookie. This is
+ used if you want to ensure that the previous session data can't be
+ accessed again from the user's browser (for example, the
+ :func:`django.contrib.auth.logout()` function calls it).
+
+ * ``set_test_cookie()``
+
+ Sets a test cookie to determine whether the user's browser supports
+ cookies. Due to the way cookies work, you won't be able to test this
+ until the user's next page request. See `Setting test cookies`_ below for
+ more information.
+
+ * ``test_cookie_worked()``
+
+ Returns either ``True`` or ``False``, depending on whether the user's
+ browser accepted the test cookie. Due to the way cookies work, you'll
+ have to call ``set_test_cookie()`` on a previous, separate page request.
+ See `Setting test cookies`_ below for more information.
+
+ * ``delete_test_cookie()``
+
+ Deletes the test cookie. Use this to clean up after yourself.
+
+ * ``set_expiry(value)``
+
+ .. versionadded:: 1.0
+
+ Sets the expiration time for the session. You can pass a number of
+ different values:
+
+ * If ``value`` is an integer, the session will expire after that
+ many seconds of inactivity. For example, calling
+ ``request.session.set_expiry(300)`` would make the session expire
+ in 5 minutes.
+
+ * If ``value`` is a ``datetime`` or ``timedelta`` object, the
+ session will expire at that specific date/time.
+
+ * If ``value`` is ``0``, the user's session cookie will expire
+ when the user's Web browser is closed.
+
+ * If ``value`` is ``None``, the session reverts to using the global
+ session expiry policy.
+
+ Reading a session is not considered activity for expiration
+ purposes. Session expiration is computed from the last time the
+ session was *modified*.
+
+ * ``get_expiry_age()``
+
+ .. versionadded:: 1.0
+
+ Returns the number of seconds until this session expires. For sessions
+ with no custom expiration (or those set to expire at browser close), this
+ will equal ``settings.SESSION_COOKIE_AGE``.
+
+ * ``get_expiry_date()``
+
+ .. versionadded:: 1.0
+
+ Returns the date this session will expire. For sessions with no custom
+ expiration (or those set to expire at browser close), this will equal the
+ date ``settings.SESSION_COOKIE_AGE`` seconds from now.
+
+ * ``get_expire_at_browser_close()``
+
+ .. versionadded:: 1.0
+
+ Returns either ``True`` or ``False``, depending on whether the user's
+ session cookie will expire when the user's Web browser is closed.
+
+You can edit ``request.session`` at any point in your view. You can edit it
+multiple times.
+
+Session object guidelines
+-------------------------
+
+ * Use normal Python strings as dictionary keys on ``request.session``. This
+ is more of a convention than a hard-and-fast rule.
+
+ * Session dictionary keys that begin with an underscore are reserved for
+ internal use by Django.
+
+ * Don't override ``request.session`` with a new object, and don't access or
+ set its attributes. Use it like a Python dictionary.
+
+Examples
+--------
+
+This simplistic view sets a ``has_commented`` variable to ``True`` after a user
+posts a comment. It doesn't let a user post a comment more than once::
+
+ def post_comment(request, new_comment):
+ if request.session.get('has_commented', False):
+ return HttpResponse("You've already commented.")
+ c = comments.Comment(comment=new_comment)
+ c.save()
+ request.session['has_commented'] = True
+ return HttpResponse('Thanks for your comment!')
+
+This simplistic view logs in a "member" of the site::
+
+ def login(request):
+ m = Member.objects.get(username=request.POST['username'])
+ if m.password == request.POST['password']:
+ request.session['member_id'] = m.id
+ return HttpResponse("You're logged in.")
+ else:
+ return HttpResponse("Your username and password didn't match.")
+
+...And this one logs a member out, according to ``login()`` above::
+
+ def logout(request):
+ try:
+ del request.session['member_id']
+ except KeyError:
+ pass
+ return HttpResponse("You're logged out.")
+
+The standard ``django.contrib.auth.logout()`` function actually does a bit
+more than this to prevent inadvertent data leakage. It calls
+``request.session.flush()``. We are using this example as a demonstration of
+how to work with session objects, not as a full ``logout()`` implementation.
+
+Setting test cookies
+====================
+
+As a convenience, Django provides an easy way to test whether the user's
+browser accepts cookies. Just call ``request.session.set_test_cookie()`` in a
+view, and call ``request.session.test_cookie_worked()`` in a subsequent view --
+not in the same view call.
+
+This awkward split between ``set_test_cookie()`` and ``test_cookie_worked()``
+is necessary due to the way cookies work. When you set a cookie, you can't
+actually tell whether a browser accepted it until the browser's next request.
+
+It's good practice to use ``delete_test_cookie()`` to clean up after yourself.
+Do this after you've verified that the test cookie worked.
+
+Here's a typical usage example::
+
+ def login(request):
+ if request.method == 'POST':
+ if request.session.test_cookie_worked():
+ request.session.delete_test_cookie()
+ return HttpResponse("You're logged in.")
+ else:
+ return HttpResponse("Please enable cookies and try again.")
+ request.session.set_test_cookie()
+ return render_to_response('foo/login_form.html')
+
+Using sessions out of views
+===========================
+
+.. versionadded:: 1.0
+
+An API is available to manipulate session data outside of a view::
+
+ >>> from django.contrib.sessions.backends.db import SessionStore
+ >>> s = SessionStore(session_key='2b1189a188b44ad18c35e113ac6ceead')
+ >>> s['last_login'] = datetime.datetime(2005, 8, 20, 13, 35, 10)
+ >>> s['last_login']
+ datetime.datetime(2005, 8, 20, 13, 35, 0)
+ >>> s.save()
+
+If you're using the ``django.contrib.sessions.backends.db`` backend, each
+session is just a normal Django model. The ``Session`` model is defined in
+``django/contrib/sessions/models.py``. Because it's a normal model, you can
+access sessions using the normal Django database API::
+
+ >>> from django.contrib.sessions.models import Session
+ >>> s = Session.objects.get(pk='2b1189a188b44ad18c35e113ac6ceead')
+ >>> s.expire_date
+ datetime.datetime(2005, 8, 20, 13, 35, 12)
+
+Note that you'll need to call ``get_decoded()`` to get the session dictionary.
+This is necessary because the dictionary is stored in an encoded format::
+
+ >>> s.session_data
+ 'KGRwMQpTJ19hdXRoX3VzZXJfaWQnCnAyCkkxCnMuMTExY2ZjODI2Yj...'
+ >>> s.get_decoded()
+ {'user_id': 42}
+
+When sessions are saved
+=======================
+
+By default, Django only saves to the session database when the session has been
+modified -- that is if any of its dictionary values have been assigned or
+deleted::
+
+ # Session is modified.
+ request.session['foo'] = 'bar'
+
+ # Session is modified.
+ del request.session['foo']
+
+ # Session is modified.
+ request.session['foo'] = {}
+
+ # Gotcha: Session is NOT modified, because this alters
+ # request.session['foo'] instead of request.session.
+ request.session['foo']['bar'] = 'baz'
+
+In the last case of the above example, we can tell the session object
+explicitly that it has been modified by setting the ``modified`` attribute on
+the session object::
+
+ request.session.modified = True
+
+To change this default behavior, set the ``SESSION_SAVE_EVERY_REQUEST`` setting
+to ``True``. If ``SESSION_SAVE_EVERY_REQUEST`` is ``True``, Django will save
+the session to the database on every single request.
+
+Note that the session cookie is only sent when a session has been created or
+modified. If ``SESSION_SAVE_EVERY_REQUEST`` is ``True``, the session cookie
+will be sent on every request.
+
+Similarly, the ``expires`` part of a session cookie is updated each time the
+session cookie is sent.
+
+Browser-length sessions vs. persistent sessions
+===============================================
+
+You can control whether the session framework uses browser-length sessions vs.
+persistent sessions with the ``SESSION_EXPIRE_AT_BROWSER_CLOSE`` setting.
+
+By default, ``SESSION_EXPIRE_AT_BROWSER_CLOSE`` is set to ``False``, which
+means session cookies will be stored in users' browsers for as long as
+``SESSION_COOKIE_AGE``. Use this if you don't want people to have to log in
+every time they open a browser.
+
+If ``SESSION_EXPIRE_AT_BROWSER_CLOSE`` is set to ``True``, Django will use
+browser-length cookies -- cookies that expire as soon as the user closes his or
+her browser. Use this if you want people to have to log in every time they open
+a browser.
+
+.. versionadded:: 1.0
+
+This setting is a global default and can be overwritten at a per-session level
+by explicitly calling ``request.session.set_expiry()`` as described above in
+`using sessions in views`_.
+
+Clearing the session table
+==========================
+
+If you're using the database backend, note that session data can accumulate in
+the ``django_session`` database table and Django does *not* provide automatic
+purging. Therefore, it's your job to purge expired sessions on a regular basis.
+
+To understand this problem, consider what happens when a user uses a session.
+When a user logs in, Django adds a row to the ``django_session`` database
+table. Django updates this row each time the session data changes. If the user
+logs out manually, Django deletes the row. But if the user does *not* log out,
+the row never gets deleted.
+
+Django provides a sample clean-up script: ``django-admin.py cleanup``.
+That script deletes any session in the session table whose ``expire_date`` is
+in the past -- but your application may have different requirements.
+
+Settings
+========
+
+A few :doc:`Django settings </ref/settings>` give you control over session behavior:
+
+SESSION_ENGINE
+--------------
+
+.. versionadded:: 1.0
+
+.. versionchanged:: 1.1
+ The ``cached_db`` backend was added
+
+Default: ``django.contrib.sessions.backends.db``
+
+Controls where Django stores session data. Valid values are:
+
+ * ``'django.contrib.sessions.backends.db'``
+ * ``'django.contrib.sessions.backends.file'``
+ * ``'django.contrib.sessions.backends.cache'``
+ * ``'django.contrib.sessions.backends.cached_db'``
+
+See `configuring the session engine`_ for more details.
+
+SESSION_FILE_PATH
+-----------------
+
+.. versionadded:: 1.0
+
+Default: ``/tmp/``
+
+If you're using file-based session storage, this sets the directory in
+which Django will store session data.
+
+SESSION_COOKIE_AGE
+------------------
+
+Default: ``1209600`` (2 weeks, in seconds)
+
+The age of session cookies, in seconds.
+
+SESSION_COOKIE_DOMAIN
+---------------------
+
+Default: ``None``
+
+The domain to use for session cookies. Set this to a string such as
+``".lawrence.com"`` (note the leading dot!) for cross-domain cookies, or use
+``None`` for a standard domain cookie.
+
+SESSION_COOKIE_NAME
+-------------------
+
+Default: ``'sessionid'``
+
+The name of the cookie to use for sessions. This can be whatever you want.
+
+SESSION_COOKIE_PATH
+-------------------
+
+.. versionadded:: 1.0
+
+Default: ``'/'``
+
+The path set on the session cookie. This should either match the URL path of
+your Django installation or be parent of that path.
+
+This is useful if you have multiple Django instances running under the same
+hostname. They can use different cookie paths, and each instance will only see
+its own session cookie.
+
+SESSION_COOKIE_SECURE
+---------------------
+
+Default: ``False``
+
+Whether to use a secure cookie for the session cookie. If this is set to
+``True``, the cookie will be marked as "secure," which means browsers may
+ensure that the cookie is only sent under an HTTPS connection.
+
+SESSION_EXPIRE_AT_BROWSER_CLOSE
+-------------------------------
+
+Default: ``False``
+
+Whether to expire the session when the user closes his or her browser. See
+"Browser-length sessions vs. persistent sessions" above.
+
+SESSION_SAVE_EVERY_REQUEST
+--------------------------
+
+Default: ``False``
+
+Whether to save the session data on every request. If this is ``False``
+(default), then the session data will only be saved if it has been modified --
+that is, if any of its dictionary values have been assigned or deleted.
+
+.. _Django settings: ../settings/
+
+Technical details
+=================
+
+ * The session dictionary should accept any pickleable Python object. See
+ `the pickle module`_ for more information.
+
+ * Session data is stored in a database table named ``django_session`` .
+
+ * Django only sends a cookie if it needs to. If you don't set any session
+ data, it won't send a session cookie.
+
+.. _`the pickle module`: http://docs.python.org/library/pickle.html
+
+Session IDs in URLs
+===================
+
+The Django sessions framework is entirely, and solely, cookie-based. It does
+not fall back to putting session IDs in URLs as a last resort, as PHP does.
+This is an intentional design decision. Not only does that behavior make URLs
+ugly, it makes your site vulnerable to session-ID theft via the "Referer"
+header.
diff --git a/parts/django/docs/topics/http/shortcuts.txt b/parts/django/docs/topics/http/shortcuts.txt
new file mode 100644
index 0000000..315460e
--- /dev/null
+++ b/parts/django/docs/topics/http/shortcuts.txt
@@ -0,0 +1,229 @@
+=========================
+Django shortcut functions
+=========================
+
+.. module:: django.shortcuts
+ :synopsis:
+ Convience shortcuts that spam multiple levels of Django's MVC stack.
+
+.. index:: shortcuts
+
+The package ``django.shortcuts`` collects helper functions and classes that
+"span" multiple levels of MVC. In other words, these functions/classes
+introduce controlled coupling for convenience's sake.
+
+``render_to_response``
+======================
+
+.. function:: render_to_response(template[, dictionary][, context_instance][, mimetype])
+
+ Renders a given template with a given context dictionary and returns an
+ :class:`~django.http.HttpResponse` object with that rendered text.
+
+Required arguments
+------------------
+
+``template``
+ The full name of a template to use or sequence of template names. If a
+ sequence is given, the first template that exists will be used. See the
+ :ref:`template loader documentation <ref-templates-api-the-python-api>`
+ for more information on how templates are found.
+
+Optional arguments
+------------------
+
+``dictionary``
+ A dictionary of values to add to the template context. By default, this
+ is an empty dictionary. If a value in the dictionary is callable, the
+ view will call it just before rendering the template.
+
+``context_instance``
+ The context instance to render the template with. By default, the template
+ will be rendered with a :class:`~django.template.Context` instance (filled
+ with values from ``dictionary``). If you need to use :ref:`context
+ processors <subclassing-context-requestcontext>`, render the template with
+ a :class:`~django.template.RequestContext` instance instead. Your code
+ might look something like this::
+
+ return render_to_response('my_template.html',
+ my_data_dictionary,
+ context_instance=RequestContext(request))
+
+``mimetype``
+ The MIME type to use for the resulting document. Defaults to the value of
+ the :setting:`DEFAULT_CONTENT_TYPE` setting.
+
+Example
+-------
+
+The following example renders the template ``myapp/index.html`` with the
+MIME type ``application/xhtml+xml``::
+
+ from django.shortcuts import render_to_response
+
+ def my_view(request):
+ # View code here...
+ return render_to_response('myapp/index.html', {"foo": "bar"},
+ mimetype="application/xhtml+xml")
+
+This example is equivalent to::
+
+ from django.http import HttpResponse
+ from django.template import Context, loader
+
+ def my_view(request):
+ # View code here...
+ t = loader.get_template('myapp/template.html')
+ c = Context({'foo': 'bar'})
+ return HttpResponse(t.render(c),
+ mimetype="application/xhtml+xml")
+
+``redirect``
+============
+
+.. function:: redirect(to[, permanent=False], *args, **kwargs)
+
+ .. versionadded:: 1.1
+
+ Returns an :class:`~django.http.HttpResponseRedirect` to the appropriate URL
+ for the arguments passed.
+
+ The arguments could be:
+
+ * A model: the model's `get_absolute_url()` function will be called.
+
+ * A view name, possibly with arguments: `urlresolvers.reverse()` will
+ be used to reverse-resolve the name.
+
+ * A URL, which will be used as-is for the redirect location.
+
+ By default issues a temporary redirect; pass ``permanent=True`` to issue a
+ permanent redirect
+
+Examples
+--------
+
+You can use the :func:`redirect` function in a number of ways.
+
+ 1. By passing some object; that object's
+ :meth:`~django.db.models.Model.get_absolute_url` method will be called
+ to figure out the redirect URL::
+
+ def my_view(request):
+ ...
+ object = MyModel.objects.get(...)
+ return redirect(object)
+
+ 2. By passing the name of a view and optionally some positional or
+ keyword arguments; the URL will be reverse resolved using the
+ :func:`~django.core.urlresolvers.reverse` method::
+
+ def my_view(request):
+ ...
+ return redirect('some-view-name', foo='bar')
+
+ 3. By passing a hardcoded URL to redirect to::
+
+ def my_view(request):
+ ...
+ return redirect('/some/url/')
+
+ This also works with full URLs::
+
+ def my_view(request):
+ ...
+ return redirect('http://example.com/')
+
+By default, :func:`redirect` returns a temporary redirect. All of the above
+forms accept a ``permanent`` argument; if set to ``True`` a permanent redirect
+will be returned::
+
+ def my_view(request):
+ ...
+ object = MyModel.objects.get(...)
+ return redirect(object, permanent=True)
+
+``get_object_or_404``
+=====================
+
+.. function:: get_object_or_404(klass, *args, **kwargs)
+
+ Calls :meth:`~django.db.models.QuerySet.get()` on a given model manager,
+ but it raises :class:`~django.http.Http404` instead of the model's
+ :class:`~django.core.exceptions.DoesNotExist` exception.
+
+Required arguments
+------------------
+
+``klass``
+ A :class:`~django.db.models.Model`, :class:`~django.db.models.Manager` or
+ :class:`~django.db.models.QuerySet` instance from which to get the object.
+
+``**kwargs``
+ Lookup parameters, which should be in the format accepted by ``get()`` and
+ ``filter()``.
+
+Example
+-------
+
+The following example gets the object with the primary key of 1 from
+``MyModel``::
+
+ from django.shortcuts import get_object_or_404
+
+ def my_view(request):
+ my_object = get_object_or_404(MyModel, pk=1)
+
+This example is equivalent to::
+
+ from django.http import Http404
+
+ def my_view(request):
+ try:
+ my_object = MyModel.objects.get(pk=1)
+ except MyModel.DoesNotExist:
+ raise Http404
+
+Note: As with ``get()``, a
+:class:`~django.core.exceptions.MultipleObjectsReturned` exception
+will be raised if more than one object is found.
+
+``get_list_or_404``
+===================
+
+.. function:: get_list_or_404(klass, *args, **kwargs)
+
+ Returns the result of :meth:`~django.db.models.QuerySet.filter()` on a
+ given model manager, raising :class:`~django.http.Http404` if the resulting
+ list is empty.
+
+Required arguments
+------------------
+
+``klass``
+ A :class:`~django.db.models.Model`, :class:`~django.db.models.Manager` or
+ :class:`~django.db.models.query.QuerySet` instance from which to get the
+ list.
+
+``**kwargs``
+ Lookup parameters, which should be in the format accepted by ``get()`` and
+ ``filter()``.
+
+Example
+-------
+
+The following example gets all published objects from ``MyModel``::
+
+ from django.shortcuts import get_list_or_404
+
+ def my_view(request):
+ my_objects = get_list_or_404(MyModel, published=True)
+
+This example is equivalent to::
+
+ from django.http import Http404
+
+ def my_view(request):
+ my_objects = list(MyModel.objects.filter(published=True))
+ if not my_objects:
+ raise Http404
diff --git a/parts/django/docs/topics/http/urls.txt b/parts/django/docs/topics/http/urls.txt
new file mode 100644
index 0000000..2361297
--- /dev/null
+++ b/parts/django/docs/topics/http/urls.txt
@@ -0,0 +1,890 @@
+==============
+URL dispatcher
+==============
+
+.. module:: django.core.urlresolvers
+
+A clean, elegant URL scheme is an important detail in a high-quality Web
+application. Django lets you design URLs however you want, with no framework
+limitations.
+
+There's no ``.php`` or ``.cgi`` required, and certainly none of that
+``0,2097,1-1-1928,00`` nonsense.
+
+See `Cool URIs don't change`_, by World Wide Web creator Tim Berners-Lee, for
+excellent arguments on why URLs should be clean and usable.
+
+.. _Cool URIs don't change: http://www.w3.org/Provider/Style/URI
+
+Overview
+========
+
+To design URLs for an app, you create a Python module informally called a
+**URLconf** (URL configuration). This module is pure Python code and
+is a simple mapping between URL patterns (as simple regular expressions) to
+Python callback functions (your views).
+
+This mapping can be as short or as long as needed. It can reference other
+mappings. And, because it's pure Python code, it can be constructed
+dynamically.
+
+.. _how-django-processes-a-request:
+
+How Django processes a request
+==============================
+
+When a user requests a page from your Django-powered site, this is the
+algorithm the system follows to determine which Python code to execute:
+
+ 1. Django determines the root URLconf module to use. Ordinarily,
+ this is the value of the :setting:`ROOT_URLCONF` setting, but if the incoming
+ ``HttpRequest`` object has an attribute called ``urlconf`` (set by
+ middleware :ref:`request processing <request-middleware>`), its value
+ will be used in place of the :setting:`ROOT_URLCONF` setting.
+
+ 2. Django loads that Python module and looks for the variable
+ ``urlpatterns``. This should be a Python list, in the format returned by
+ the function :func:`django.conf.urls.defaults.patterns`.
+
+ 3. Django runs through each URL pattern, in order, and stops at the first
+ one that matches the requested URL.
+
+ 4. Once one of the regexes matches, Django imports and calls the given
+ view, which is a simple Python function. The view gets passed an
+ :class:`~django.http.HttpRequest` as its first argument and any values
+ captured in the regex as remaining arguments.
+
+Example
+=======
+
+Here's a sample URLconf::
+
+ from django.conf.urls.defaults import *
+
+ urlpatterns = patterns('',
+ (r'^articles/2003/$', 'news.views.special_case_2003'),
+ (r'^articles/(\d{4})/$', 'news.views.year_archive'),
+ (r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
+ (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'),
+ )
+
+Notes:
+
+ * ``from django.conf.urls.defaults import *`` makes the ``patterns()``
+ function available.
+
+ * To capture a value from the URL, just put parenthesis around it.
+
+ * There's no need to add a leading slash, because every URL has that. For
+ example, it's ``^articles``, not ``^/articles``.
+
+ * The ``'r'`` in front of each regular expression string is optional but
+ recommended. It tells Python that a string is "raw" -- that nothing in
+ the string should be escaped. See `Dive Into Python's explanation`_.
+
+Example requests:
+
+ * A request to ``/articles/2005/03/`` would match the third entry in the
+ list. Django would call the function
+ ``news.views.month_archive(request, '2005', '03')``.
+
+ * ``/articles/2005/3/`` would not match any URL patterns, because the
+ third entry in the list requires two digits for the month.
+
+ * ``/articles/2003/`` would match the first pattern in the list, not the
+ second one, because the patterns are tested in order, and the first one
+ is the first test to pass. Feel free to exploit the ordering to insert
+ special cases like this.
+
+ * ``/articles/2003`` would not match any of these patterns, because each
+ pattern requires that the URL end with a slash.
+
+ * ``/articles/2003/03/3/`` would match the final pattern. Django would call
+ the function ``news.views.article_detail(request, '2003', '03', '3')``.
+
+.. _Dive Into Python's explanation: http://diveintopython.org/regular_expressions/street_addresses.html#re.matching.2.3
+
+Named groups
+============
+
+The above example used simple, *non-named* regular-expression groups (via
+parenthesis) to capture bits of the URL and pass them as *positional* arguments
+to a view. In more advanced usage, it's possible to use *named*
+regular-expression groups to capture URL bits and pass them as *keyword*
+arguments to a view.
+
+In Python regular expressions, the syntax for named regular-expression groups
+is ``(?P<name>pattern)``, where ``name`` is the name of the group and
+``pattern`` is some pattern to match.
+
+Here's the above example URLconf, rewritten to use named groups::
+
+ urlpatterns = patterns('',
+ (r'^articles/2003/$', 'news.views.special_case_2003'),
+ (r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
+ (r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', 'news.views.month_archive'),
+ (r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d+)/$', 'news.views.article_detail'),
+ )
+
+This accomplishes exactly the same thing as the previous example, with one
+subtle difference: The captured values are passed to view functions as keyword
+arguments rather than positional arguments. For example:
+
+ * A request to ``/articles/2005/03/`` would call the function
+ ``news.views.month_archive(request, year='2005', month='03')``, instead
+ of ``news.views.month_archive(request, '2005', '03')``.
+
+ * A request to ``/articles/2003/03/3/`` would call the function
+ ``news.views.article_detail(request, year='2003', month='03', day='3')``.
+
+In practice, this means your URLconfs are slightly more explicit and less prone
+to argument-order bugs -- and you can reorder the arguments in your views'
+function definitions. Of course, these benefits come at the cost of brevity;
+some developers find the named-group syntax ugly and too verbose.
+
+The matching/grouping algorithm
+-------------------------------
+
+Here's the algorithm the URLconf parser follows, with respect to named groups
+vs. non-named groups in a regular expression:
+
+If there are any named arguments, it will use those, ignoring non-named arguments.
+Otherwise, it will pass all non-named arguments as positional arguments.
+
+In both cases, it will pass any extra keyword arguments as keyword arguments.
+See "Passing extra options to view functions" below.
+
+What the URLconf searches against
+=================================
+
+The URLconf searches against the requested URL, as a normal Python string. This
+does not include GET or POST parameters, or the domain name.
+
+For example, in a request to ``http://www.example.com/myapp/``, the URLconf
+will look for ``myapp/``.
+
+In a request to ``http://www.example.com/myapp/?page=3``, the URLconf will look
+for ``myapp/``.
+
+The URLconf doesn't look at the request method. In other words, all request
+methods -- ``POST``, ``GET``, ``HEAD``, etc. -- will be routed to the same
+function for the same URL.
+
+Syntax of the urlpatterns variable
+==================================
+
+``urlpatterns`` should be a Python list, in the format returned by the function
+:func:`django.conf.urls.defaults.patterns`. Always use ``patterns()`` to create
+the ``urlpatterns`` variable.
+
+Convention is to use ``from django.conf.urls.defaults import *`` at the top of
+your URLconf. This gives your module access to these objects:
+
+.. module:: django.conf.urls.defaults
+
+patterns
+--------
+
+.. function:: patterns(prefix, pattern_description, ...)
+
+A function that takes a prefix, and an arbitrary number of URL patterns, and
+returns a list of URL patterns in the format Django needs.
+
+The first argument to ``patterns()`` is a string ``prefix``. See
+`The view prefix`_ below.
+
+The remaining arguments should be tuples in this format::
+
+ (regular expression, Python callback function [, optional dictionary [, optional name]])
+
+...where ``optional dictionary`` and ``optional name`` are optional. (See
+`Passing extra options to view functions`_ below.)
+
+.. note::
+ Because `patterns()` is a function call, it accepts a maximum of 255
+ arguments (URL patterns, in this case). This is a limit for all Python
+ function calls. This is rarely a problem in practice, because you'll
+ typically structure your URL patterns modularly by using `include()`
+ sections. However, on the off-chance you do hit the 255-argument limit,
+ realize that `patterns()` returns a Python list, so you can split up the
+ construction of the list.
+
+ ::
+
+ urlpatterns = patterns('',
+ ...
+ )
+ urlpatterns += patterns('',
+ ...
+ )
+
+ Python lists have unlimited size, so there's no limit to how many URL
+ patterns you can construct. The only limit is that you can only create 254
+ at a time (the 255th argument is the initial prefix argument).
+
+url
+---
+
+.. versionadded:: 1.0
+
+.. function:: url(regex, view, kwargs=None, name=None, prefix='')
+
+You can use the ``url()`` function, instead of a tuple, as an argument to
+``patterns()``. This is convenient if you want to specify a name without the
+optional extra arguments dictionary. For example::
+
+ urlpatterns = patterns('',
+ url(r'^index/$', index_view, name="main-view"),
+ ...
+ )
+
+This function takes five arguments, most of which are optional::
+
+ url(regex, view, kwargs=None, name=None, prefix='')
+
+See `Naming URL patterns`_ for why the ``name`` parameter is useful.
+
+The ``prefix`` parameter has the same meaning as the first argument to
+``patterns()`` and is only relevant when you're passing a string as the
+``view`` parameter.
+
+handler404
+----------
+
+.. data:: handler404
+
+A callable, or a string representing the full Python import path to the view
+that should be called if none of the URL patterns match.
+
+By default, this is ``'django.views.defaults.page_not_found'``. That default
+value should suffice.
+
+.. versionchanged:: 1.2
+ Previous versions of Django only accepted strings representing import paths.
+
+handler500
+----------
+
+.. data:: handler500
+
+A callable, or a string representing the full Python import path to the view
+that should be called in case of server errors. Server errors happen when you
+have runtime errors in view code.
+
+By default, this is ``'django.views.defaults.server_error'``. That default
+value should suffice.
+
+.. versionchanged:: 1.2
+ Previous versions of Django only accepted strings representing import paths.
+
+include
+-------
+
+.. function:: include(<module or pattern_list>)
+
+A function that takes a full Python import path to another URLconf module that
+should be "included" in this place.
+
+.. versionadded:: 1.1
+
+:func:`include` also accepts as an argument an iterable that returns URL
+patterns.
+
+See `Including other URLconfs`_ below.
+
+Notes on capturing text in URLs
+===============================
+
+Each captured argument is sent to the view as a plain Python string, regardless
+of what sort of match the regular expression makes. For example, in this
+URLconf line::
+
+ (r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
+
+...the ``year`` argument to ``news.views.year_archive()`` will be a string, not
+an integer, even though the ``\d{4}`` will only match integer strings.
+
+A convenient trick is to specify default parameters for your views' arguments.
+Here's an example URLconf and view::
+
+ # URLconf
+ urlpatterns = patterns('',
+ (r'^blog/$', 'blog.views.page'),
+ (r'^blog/page(?P<num>\d+)/$', 'blog.views.page'),
+ )
+
+ # View (in blog/views.py)
+ def page(request, num="1"):
+ # Output the appropriate page of blog entries, according to num.
+
+In the above example, both URL patterns point to the same view --
+``blog.views.page`` -- but the first pattern doesn't capture anything from the
+URL. If the first pattern matches, the ``page()`` function will use its
+default argument for ``num``, ``"1"``. If the second pattern matches,
+``page()`` will use whatever ``num`` value was captured by the regex.
+
+Performance
+===========
+
+Each regular expression in a ``urlpatterns`` is compiled the first time it's
+accessed. This makes the system blazingly fast.
+
+The view prefix
+===============
+
+You can specify a common prefix in your ``patterns()`` call, to cut down on
+code duplication.
+
+Here's the example URLconf from the :doc:`Django overview </intro/overview>`::
+
+ from django.conf.urls.defaults import *
+
+ urlpatterns = patterns('',
+ (r'^articles/(\d{4})/$', 'news.views.year_archive'),
+ (r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
+ (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'),
+ )
+
+In this example, each view has a common prefix -- ``'news.views'``.
+Instead of typing that out for each entry in ``urlpatterns``, you can use the
+first argument to the ``patterns()`` function to specify a prefix to apply to
+each view function.
+
+With this in mind, the above example can be written more concisely as::
+
+ from django.conf.urls.defaults import *
+
+ urlpatterns = patterns('news.views',
+ (r'^articles/(\d{4})/$', 'year_archive'),
+ (r'^articles/(\d{4})/(\d{2})/$', 'month_archive'),
+ (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'article_detail'),
+ )
+
+Note that you don't put a trailing dot (``"."``) in the prefix. Django puts
+that in automatically.
+
+Multiple view prefixes
+----------------------
+
+In practice, you'll probably end up mixing and matching views to the point
+where the views in your ``urlpatterns`` won't have a common prefix. However,
+you can still take advantage of the view prefix shortcut to remove duplication.
+Just add multiple ``patterns()`` objects together, like this:
+
+Old::
+
+ from django.conf.urls.defaults import *
+
+ urlpatterns = patterns('',
+ (r'^$', 'django.views.generic.date_based.archive_index'),
+ (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', 'django.views.generic.date_based.archive_month'),
+ (r'^tag/(?P<tag>\w+)/$', 'weblog.views.tag'),
+ )
+
+New::
+
+ from django.conf.urls.defaults import *
+
+ urlpatterns = patterns('django.views.generic.date_based',
+ (r'^$', 'archive_index'),
+ (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$','archive_month'),
+ )
+
+ urlpatterns += patterns('weblog.views',
+ (r'^tag/(?P<tag>\w+)/$', 'tag'),
+ )
+
+Including other URLconfs
+========================
+
+At any point, your ``urlpatterns`` can "include" other URLconf modules. This
+essentially "roots" a set of URLs below other ones.
+
+For example, here's the URLconf for the `Django Web site`_ itself. It includes a
+number of other URLconfs::
+
+ from django.conf.urls.defaults import *
+
+ urlpatterns = patterns('',
+ (r'^weblog/', include('django_website.apps.blog.urls.blog')),
+ (r'^documentation/', include('django_website.apps.docs.urls.docs')),
+ (r'^comments/', include('django.contrib.comments.urls')),
+ )
+
+Note that the regular expressions in this example don't have a ``$``
+(end-of-string match character) but do include a trailing slash. Whenever
+Django encounters ``include()``, it chops off whatever part of the URL matched
+up to that point and sends the remaining string to the included URLconf for
+further processing.
+
+.. versionadded:: 1.1
+
+Another possibility is to include additional URL patterns not by specifying the
+URLconf Python module defining them as the `include`_ argument but by using
+directly the pattern list as returned by `patterns`_ instead. For example::
+
+ from django.conf.urls.defaults import *
+
+ extra_patterns = patterns('',
+ url(r'reports/(?P<id>\d+)/$', 'credit.views.report', name='credit-reports'),
+ url(r'charge/$', 'credit.views.charge', name='credit-charge'),
+ )
+
+ urlpatterns = patterns('',
+ url(r'^$', 'apps.main.views.homepage', name='site-homepage'),
+ (r'^help/', include('apps.help.urls')),
+ (r'^credit/', include(extra_patterns)),
+ )
+
+This approach can be seen in use when you deploy an instance of the Django
+Admin application. The Django Admin is deployed as instances of a
+:class:`~django.contrib.admin.AdminSite`; each
+:class:`~django.contrib.admin.AdminSite` instance has an attribute ``urls``
+that returns the url patterns available to that instance. It is this attribute
+that you ``include()`` into your projects ``urlpatterns`` when you deploy the
+admin instance.
+
+.. _`Django Web site`: http://www.djangoproject.com/
+
+Captured parameters
+-------------------
+
+An included URLconf receives any captured parameters from parent URLconfs, so
+the following example is valid::
+
+ # In settings/urls/main.py
+ urlpatterns = patterns('',
+ (r'^(?P<username>\w+)/blog/', include('foo.urls.blog')),
+ )
+
+ # In foo/urls/blog.py
+ urlpatterns = patterns('foo.views',
+ (r'^$', 'blog.index'),
+ (r'^archive/$', 'blog.archive'),
+ )
+
+In the above example, the captured ``"username"`` variable is passed to the
+included URLconf, as expected.
+
+.. _topics-http-defining-url-namespaces:
+
+Defining URL Namespaces
+-----------------------
+
+When you need to deploy multiple instances of a single application, it can be
+helpful to be able to differentiate between instances. This is especially
+important when using :ref:`named URL patterns <naming-url-patterns>`, since
+multiple instances of a single application will share named URLs. Namespaces
+provide a way to tell these named URLs apart.
+
+A URL namespace comes in two parts, both of which are strings:
+
+ * An **application namespace**. This describes the name of the application
+ that is being deployed. Every instance of a single application will have
+ the same application namespace. For example, Django's admin application
+ has the somewhat predictable application namespace of ``admin``.
+
+ * An **instance namespace**. This identifies a specific instance of an
+ application. Instance namespaces should be unique across your entire
+ project. However, an instance namespace can be the same as the
+ application namespace. This is used to specify a default instance of an
+ application. For example, the default Django Admin instance has an
+ instance namespace of ``admin``.
+
+URL Namespaces can be specified in two ways.
+
+Firstly, you can provide the application and instance namespace as arguments
+to ``include()`` when you construct your URL patterns. For example,::
+
+ (r'^help/', include('apps.help.urls', namespace='foo', app_name='bar')),
+
+This will include the URLs defined in ``apps.help.urls`` into the application
+namespace ``bar``, with the instance namespace ``foo``.
+
+Secondly, you can include an object that contains embedded namespace data. If
+you ``include()`` a ``patterns`` object, that object will be added to the
+global namespace. However, you can also ``include()`` an object that contains
+a 3-tuple containing::
+
+ (<patterns object>, <application namespace>, <instance namespace>)
+
+This will include the nominated URL patterns into the given application and
+instance namespace. For example, the ``urls`` attribute of Django's
+:class:`~django.contrib.admin.AdminSite` object returns a 3-tuple that contains
+all the patterns in an admin site, plus the name of the admin instance, and the
+application namespace ``admin``.
+
+Once you have defined namespaced URLs, you can reverse them. For details on
+reversing namespaced urls, see the documentation on :ref:`reversing namespaced
+URLs <topics-http-reversing-url-namespaces>`.
+
+Passing extra options to view functions
+=======================================
+
+URLconfs have a hook that lets you pass extra arguments to your view functions,
+as a Python dictionary.
+
+Any URLconf tuple can have an optional third element, which should be a
+dictionary of extra keyword arguments to pass to the view function.
+
+For example::
+
+ urlpatterns = patterns('blog.views',
+ (r'^blog/(?P<year>\d{4})/$', 'year_archive', {'foo': 'bar'}),
+ )
+
+In this example, for a request to ``/blog/2005/``, Django will call the
+``blog.views.year_archive()`` view, passing it these keyword arguments::
+
+ year='2005', foo='bar'
+
+This technique is used in :doc:`generic views </ref/generic-views>` and in the
+:doc:`syndication framework </ref/contrib/syndication>` to pass metadata and
+options to views.
+
+.. admonition:: Dealing with conflicts
+
+ It's possible to have a URL pattern which captures named keyword arguments,
+ and also passes arguments with the same names in its dictionary of extra
+ arguments. When this happens, the arguments in the dictionary will be used
+ instead of the arguments captured in the URL.
+
+Passing extra options to ``include()``
+--------------------------------------
+
+Similarly, you can pass extra options to ``include()``. When you pass extra
+options to ``include()``, *each* line in the included URLconf will be passed
+the extra options.
+
+For example, these two URLconf sets are functionally identical:
+
+Set one::
+
+ # main.py
+ urlpatterns = patterns('',
+ (r'^blog/', include('inner'), {'blogid': 3}),
+ )
+
+ # inner.py
+ urlpatterns = patterns('',
+ (r'^archive/$', 'mysite.views.archive'),
+ (r'^about/$', 'mysite.views.about'),
+ )
+
+Set two::
+
+ # main.py
+ urlpatterns = patterns('',
+ (r'^blog/', include('inner')),
+ )
+
+ # inner.py
+ urlpatterns = patterns('',
+ (r'^archive/$', 'mysite.views.archive', {'blogid': 3}),
+ (r'^about/$', 'mysite.views.about', {'blogid': 3}),
+ )
+
+Note that extra options will *always* be passed to *every* line in the included
+URLconf, regardless of whether the line's view actually accepts those options
+as valid. For this reason, this technique is only useful if you're certain that
+every view in the included URLconf accepts the extra options you're passing.
+
+Passing callable objects instead of strings
+===========================================
+
+Some developers find it more natural to pass the actual Python function object
+rather than a string containing the path to its module. This alternative is
+supported -- you can pass any callable object as the view.
+
+For example, given this URLconf in "string" notation::
+
+ urlpatterns = patterns('',
+ (r'^archive/$', 'mysite.views.archive'),
+ (r'^about/$', 'mysite.views.about'),
+ (r'^contact/$', 'mysite.views.contact'),
+ )
+
+You can accomplish the same thing by passing objects rather than strings. Just
+be sure to import the objects::
+
+ from mysite.views import archive, about, contact
+
+ urlpatterns = patterns('',
+ (r'^archive/$', archive),
+ (r'^about/$', about),
+ (r'^contact/$', contact),
+ )
+
+The following example is functionally identical. It's just a bit more compact
+because it imports the module that contains the views, rather than importing
+each view individually::
+
+ from mysite import views
+
+ urlpatterns = patterns('',
+ (r'^archive/$', views.archive),
+ (r'^about/$', views.about),
+ (r'^contact/$', views.contact),
+ )
+
+The style you use is up to you.
+
+Note that if you use this technique -- passing objects rather than strings --
+the view prefix (as explained in "The view prefix" above) will have no effect.
+
+.. _naming-url-patterns:
+
+Naming URL patterns
+===================
+
+.. versionadded:: 1.0
+
+It's fairly common to use the same view function in multiple URL patterns in
+your URLconf. For example, these two URL patterns both point to the ``archive``
+view::
+
+ urlpatterns = patterns('',
+ (r'^archive/(\d{4})/$', archive),
+ (r'^archive-summary/(\d{4})/$', archive, {'summary': True}),
+ )
+
+This is completely valid, but it leads to problems when you try to do reverse
+URL matching (through the ``permalink()`` decorator or the :ttag:`url` template
+tag). Continuing this example, if you wanted to retrieve the URL for the
+``archive`` view, Django's reverse URL matcher would get confused, because *two*
+URLpatterns point at that view.
+
+To solve this problem, Django supports **named URL patterns**. That is, you can
+give a name to a URL pattern in order to distinguish it from other patterns
+using the same view and parameters. Then, you can use this name in reverse URL
+matching.
+
+Here's the above example, rewritten to use named URL patterns::
+
+ urlpatterns = patterns('',
+ url(r'^archive/(\d{4})/$', archive, name="full-archive"),
+ url(r'^archive-summary/(\d{4})/$', archive, {'summary': True}, "arch-summary"),
+ )
+
+With these names in place (``full-archive`` and ``arch-summary``), you can
+target each pattern individually by using its name:
+
+.. code-block:: html+django
+
+ {% url arch-summary 1945 %}
+ {% url full-archive 2007 %}
+
+Even though both URL patterns refer to the ``archive`` view here, using the
+``name`` parameter to ``url()`` allows you to tell them apart in templates.
+
+The string used for the URL name can contain any characters you like. You are
+not restricted to valid Python names.
+
+.. note::
+
+ When you name your URL patterns, make sure you use names that are unlikely
+ to clash with any other application's choice of names. If you call your URL
+ pattern ``comment``, and another application does the same thing, there's
+ no guarantee which URL will be inserted into your template when you use
+ this name.
+
+ Putting a prefix on your URL names, perhaps derived from the application
+ name, will decrease the chances of collision. We recommend something like
+ ``myapp-comment`` instead of ``comment``.
+
+.. _topics-http-reversing-url-namespaces:
+
+URL namespaces
+--------------
+
+.. versionadded:: 1.1
+
+Namespaced URLs are specified using the ``:`` operator. For example, the main
+index page of the admin application is referenced using ``admin:index``. This
+indicates a namespace of ``admin``, and a named URL of ``index``.
+
+Namespaces can also be nested. The named URL ``foo:bar:whiz`` would look for
+a pattern named ``whiz`` in the namespace ``bar`` that is itself defined within
+the top-level namespace ``foo``.
+
+When given a namespaced URL (e.g. ``myapp:index``) to resolve, Django splits
+the fully qualified name into parts, and then tries the following lookup:
+
+ 1. First, Django looks for a matching application namespace (in this
+ example, ``myapp``). This will yield a list of instances of that
+ application.
+
+ 2. If there is a *current* application defined, Django finds and returns
+ the URL resolver for that instance. The *current* application can be
+ specified as an attribute on the template context - applications that
+ expect to have multiple deployments should set the ``current_app``
+ attribute on any ``Context`` or ``RequestContext`` that is used to
+ render a template.
+
+ The current application can also be specified manually as an argument
+ to the :func:`reverse()` function.
+
+ 3. If there is no current application. Django looks for a default
+ application instance. The default application instance is the instance
+ that has an instance namespace matching the application namespace (in
+ this example, an instance of the ``myapp`` called ``myapp``).
+
+ 4. If there is no default application instance, Django will pick the last
+ deployed instance of the application, whatever its instance name may be.
+
+ 5. If the provided namespace doesn't match an application namespace in
+ step 1, Django will attempt a direct lookup of the namespace as an
+ instance namespace.
+
+If there are nested namespaces, these steps are repeated for each part of the
+namespace until only the view name is unresolved. The view name will then be
+resolved into a URL in the namespace that has been found.
+
+To show this resolution strategy in action, consider an example of two instances
+of ``myapp``: one called ``foo``, and one called ``bar``. ``myapp`` has a main
+index page with a URL named `index`. Using this setup, the following lookups are
+possible:
+
+ * If one of the instances is current - say, if we were rendering a utility page
+ in the instance ``bar`` - ``myapp:index`` will resolve to the index page of
+ the instance ``bar``.
+
+ * If there is no current instance - say, if we were rendering a page
+ somewhere else on the site - ``myapp:index`` will resolve to the last
+ registered instance of ``myapp``. Since there is no default instance,
+ the last instance of ``myapp`` that is registered will be used. This could
+ be ``foo`` or ``bar``, depending on the order they are introduced into the
+ urlpatterns of the project.
+
+ * ``foo:index`` will always resolve to the index page of the instance ``foo``.
+
+If there was also a default instance - i.e., an instance named `myapp` - the
+following would happen:
+
+ * If one of the instances is current - say, if we were rendering a utility page
+ in the instance ``bar`` - ``myapp:index`` will resolve to the index page of
+ the instance ``bar``.
+
+ * If there is no current instance - say, if we were rendering a page somewhere
+ else on the site - ``myapp:index`` will resolve to the index page of the
+ default instance.
+
+ * ``foo:index`` will again resolve to the index page of the instance ``foo``.
+
+
+Utility methods
+===============
+
+reverse()
+---------
+
+If you need to use something similar to the :ttag:`url` template tag in
+your code, Django provides the following method (in the
+``django.core.urlresolvers`` module):
+
+.. function:: reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)
+
+``viewname`` is either the function name (either a function reference, or the
+string version of the name, if you used that form in ``urlpatterns``) or the
+`URL pattern name`_. Normally, you won't need to worry about the
+``urlconf`` parameter and will only pass in the positional and keyword
+arguments to use in the URL matching. For example::
+
+ from django.core.urlresolvers import reverse
+
+ def myview(request):
+ return HttpResponseRedirect(reverse('arch-summary', args=[1945]))
+
+.. _URL pattern name: `Naming URL patterns`_
+
+The ``reverse()`` function can reverse a large variety of regular expression
+patterns for URLs, but not every possible one. The main restriction at the
+moment is that the pattern cannot contain alternative choices using the
+vertical bar (``"|"``) character. You can quite happily use such patterns for
+matching against incoming URLs and sending them off to views, but you cannot
+reverse such patterns.
+
+.. versionadded:: 1.1
+
+The ``current_app`` argument allows you to provide a hint to the resolver
+indicating the application to which the currently executing view belongs.
+This ``current_app`` argument is used as a hint to resolve application
+namespaces into URLs on specific application instances, according to the
+:ref:`namespaced URL resolution strategy <topics-http-reversing-url-namespaces>`.
+
+.. admonition:: Make sure your views are all correct.
+
+ As part of working out which URL names map to which patterns, the
+ ``reverse()`` function has to import all of your URLconf files and examine
+ the name of each view. This involves importing each view function. If
+ there are *any* errors whilst importing any of your view functions, it
+ will cause ``reverse()`` to raise an error, even if that view function is
+ not the one you are trying to reverse.
+
+ Make sure that any views you reference in your URLconf files exist and can
+ be imported correctly. Do not include lines that reference views you
+ haven't written yet, because those views will not be importable.
+
+resolve()
+---------
+
+The :func:`django.core.urlresolvers.resolve` function can be used for resolving
+URL paths to the corresponding view functions. It has the following signature:
+
+.. function:: resolve(path, urlconf=None)
+
+``path`` is the URL path you want to resolve. As with
+:func:`~django.core.urlresolvers.reverse`, you don't need to
+worry about the ``urlconf`` parameter. The function returns
+the triple (view function, arguments, keyword arguments).
+
+If the URL does not resolve, the function raises an
+:class:`~django.http.Http404` exception.
+
+For example, it can be used for testing if a view would raise a ``Http404``
+error before redirecting to it::
+
+ from urlparse import urlparse
+ from django.core.urlresolvers import resolve
+ from django.http import HttpResponseRedirect, Http404
+
+ def myview(request):
+ next = request.META.get('HTTP_REFERER', None) or '/'
+ response = HttpResponseRedirect(next)
+
+ # modify the request and response as required, e.g. change locale
+ # and set corresponding locale cookie
+
+ view, args, kwargs = resolve(urlparse(next)[2])
+ kwargs['request'] = request
+ try:
+ view(*args, **kwargs)
+ except Http404:
+ return HttpResponseRedirect('/')
+ return response
+
+permalink()
+-----------
+
+The :func:`django.db.models.permalink` decorator is useful for writing short
+methods that return a full URL path. For example, a model's
+``get_absolute_url()`` method. See :func:`django.db.models.permalink` for more.
+
+get_script_prefix()
+-------------------
+
+.. function:: get_script_prefix()
+
+.. versionadded:: 1.0
+
+Normally, you should always use :func:`~django.core.urlresolvers.reverse` or
+:func:`~django.db.models.permalink` to define URLs within your application.
+However, if your application constructs part of the URL hierarchy itself, you
+may occasionally need to generate URLs. In that case, you need to be able to
+find the base URL of the Django project within its web server
+(normally, :func:`~django.core.urlresolvers.reverse` takes care of this for
+you). In that case, you can call ``get_script_prefix()``, which will return the
+script prefix portion of the URL for your Django project. If your Django
+project is at the root of its webserver, this is always ``"/"``, but it can be
+changed, for instance by using ``django.root`` (see :ref:`How to use
+Django with Apache and mod_python <howto-deployment-modpython>`). \ No newline at end of file
diff --git a/parts/django/docs/topics/http/views.txt b/parts/django/docs/topics/http/views.txt
new file mode 100644
index 0000000..2818f42
--- /dev/null
+++ b/parts/django/docs/topics/http/views.txt
@@ -0,0 +1,202 @@
+=============
+Writing Views
+=============
+
+A view function, or *view* for short, is simply a Python function that takes a
+Web request and returns a Web response. This response can be the HTML contents
+of a Web page, or a redirect, or a 404 error, or an XML document, or an image .
+. . or anything, really. The view itself contains whatever arbitrary logic is
+necessary to return that response. This code can live anywhere you want, as long
+as it's on your Python path. There's no other requirement--no "magic," so to
+speak. For the sake of putting the code *somewhere*, let's create a file called
+``views.py`` in the ``mysite`` directory, which you created in the previous
+chapter.
+
+A simple view
+=============
+
+Here's a view that returns the current date and time, as an HTML document:
+
+.. code-block:: python
+
+ from django.http import HttpResponse
+ import datetime
+
+ def current_datetime(request):
+ now = datetime.datetime.now()
+ html = "<html><body>It is now %s.</body></html>" % now
+ return HttpResponse(html)
+
+Let's step through this code one line at a time:
+
+ * First, we import the class :class:`~django.http.HttpResponse` from the
+ :mod:`django.http` module, along with Python's ``datetime`` library.
+
+ * Next, we define a function called ``current_datetime``. This is the view
+ function. Each view function takes an :class:`~django.http.HttpRequest`
+ object as its first parameter, which is typically named ``request``.
+
+ Note that the name of the view function doesn't matter; it doesn't have to
+ be named in a certain way in order for Django to recognize it. We're
+ calling it ``current_datetime`` here, because that name clearly indicates
+ what it does.
+
+ * The view returns an :class:`~django.http.HttpResponse` object that
+ contains the generated response. Each view function is responsible for
+ returning an :class:`~django.http.HttpResponse` object. (There are
+ exceptions, but we'll get to those later.)
+
+.. admonition:: Django's Time Zone
+
+ Django includes a ``TIME_ZONE`` setting that defaults to
+ ``America/Chicago``. This probably isn't where you live, so you might want
+ to change it in your settings file.
+
+Mapping URLs to Views
+=====================
+
+So, to recap, this view function returns an HTML page that includes the current
+date and time. To display this view at a particular URL, you'll need to create a
+*URLconf*; see :doc:`/topics/http/urls` for instructions.
+
+Returning errors
+================
+
+Returning HTTP error codes in Django is easy. There are subclasses of
+:class:`~django.http.HttpResponse` for a number of common HTTP status codes
+other than 200 (which means *"OK"*). You can find the full list of available
+subclasses in the :ref:`request/response <ref-httpresponse-subclasses>`
+documentation. Just return an instance of one of those subclasses instead of
+a normal :class:`~django.http.HttpResponse` in order to signify an error. For
+example::
+
+ def my_view(request):
+ # ...
+ if foo:
+ return HttpResponseNotFound('<h1>Page not found</h1>')
+ else:
+ return HttpResponse('<h1>Page was found</h1>')
+
+There isn't a specialized subclass for every possible HTTP response code,
+since many of them aren't going to be that common. However, as documented in
+the :class:`~django.http.HttpResponse` documentation, you can also pass the
+HTTP status code into the constructor for :class:`~django.http.HttpResponse`
+to create a return class for any status code you like. For example::
+
+ def my_view(request):
+ # ...
+
+ # Return a "created" (201) response code.
+ return HttpResponse(status=201)
+
+Because 404 errors are by far the most common HTTP error, there's an easier way
+to handle those errors.
+
+The Http404 exception
+---------------------
+
+.. class:: django.http.Http404()
+
+When you return an error such as :class:`~django.http.HttpResponseNotFound`,
+you're responsible for defining the HTML of the resulting error page::
+
+ return HttpResponseNotFound('<h1>Page not found</h1>')
+
+For convenience, and because it's a good idea to have a consistent 404 error page
+across your site, Django provides an ``Http404`` exception. If you raise
+``Http404`` at any point in a view function, Django will catch it and return the
+standard error page for your application, along with an HTTP error code 404.
+
+Example usage::
+
+ from django.http import Http404
+
+ def detail(request, poll_id):
+ try:
+ p = Poll.objects.get(pk=poll_id)
+ except Poll.DoesNotExist:
+ raise Http404
+ return render_to_response('polls/detail.html', {'poll': p})
+
+In order to use the ``Http404`` exception to its fullest, you should create a
+template that is displayed when a 404 error is raised. This template should be
+called ``404.html`` and located in the top level of your template tree.
+
+Customizing error views
+=======================
+
+The 404 (page not found) view
+-----------------------------
+
+When you raise an ``Http404`` exception, Django loads a special view devoted
+to handling 404 errors. By default, it's the view
+``django.views.defaults.page_not_found``, which loads and renders the template
+``404.html``.
+
+This means you need to define a ``404.html`` template in your root template
+directory. This template will be used for all 404 errors.
+
+This ``page_not_found`` view should suffice for 99% of Web applications, but if
+you want to override the 404 view, you can specify ``handler404`` in your
+URLconf, like so::
+
+ handler404 = 'mysite.views.my_custom_404_view'
+
+Behind the scenes, Django determines the 404 view by looking for ``handler404``.
+By default, URLconfs contain the following line::
+
+ from django.conf.urls.defaults import *
+
+That takes care of setting ``handler404`` in the current module. As you can see
+in ``django/conf/urls/defaults.py``, ``handler404`` is set to
+``'django.views.defaults.page_not_found'`` by default.
+
+Three things to note about 404 views:
+
+ * The 404 view is also called if Django doesn't find a match after checking
+ every regular expression in the URLconf.
+
+ * If you don't define your own 404 view -- and simply use the
+ default, which is recommended -- you still have one obligation:
+ you must create a ``404.html`` template in the root of your
+ template directory. The default 404 view will use that template
+ for all 404 errors. The default 404 view will pass one variable
+ to the template: ``request_path``, which is the URL that resulted
+ in the 404.
+
+ * The 404 view is passed a :class:`~django.template.RequestContext` and
+ will have access to variables supplied by your
+ :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting (e.g.,
+ :setting:`MEDIA_URL`).
+
+ * If :setting:`DEBUG` is set to ``True`` (in your settings module), then
+ your 404 view will never be used, and the traceback will be displayed
+ instead.
+
+The 500 (server error) view
+----------------------------
+
+Similarly, Django executes special-case behavior in the case of runtime errors
+in view code. If a view results in an exception, Django will, by default, call
+the view ``django.views.defaults.server_error``, which loads and renders the
+template ``500.html``.
+
+This means you need to define a ``500.html`` template in your root template
+directory. This template will be used for all server errors. The default 500
+view passes no variables to this template and is rendered with an empty
+``Context`` to lessen the chance of additional errors.
+
+This ``server_error`` view should suffice for 99% of Web applications, but if
+you want to override the view, you can specify ``handler500`` in your
+URLconf, like so::
+
+ handler500 = 'mysite.views.my_custom_error_view'
+
+Behind the scenes, Django determines the error view by looking for ``handler500``.
+By default, URLconfs contain the following line::
+
+ from django.conf.urls.defaults import *
+
+That takes care of setting ``handler500`` in the current module. As you can see
+in ``django/conf/urls/defaults.py``, ``handler500`` is set to
+``'django.views.defaults.server_error'`` by default.
diff --git a/parts/django/docs/topics/i18n/deployment.txt b/parts/django/docs/topics/i18n/deployment.txt
new file mode 100644
index 0000000..4727841
--- /dev/null
+++ b/parts/django/docs/topics/i18n/deployment.txt
@@ -0,0 +1,191 @@
+==========================
+Deployment of translations
+==========================
+
+If you don't need internationalization
+======================================
+
+Django's internationalization hooks are on by default, and that means there's a
+bit of i18n-related overhead in certain places of the framework. If you don't
+use internationalization, you should take the two seconds to set
+:setting:`USE_I18N = False <USE_I18N>` in your settings file. If
+:setting:`USE_I18N` is set to ``False``, then Django will make some
+optimizations so as not to load the internationalization machinery.
+
+You'll probably also want to remove ``'django.core.context_processors.i18n'``
+from your ``TEMPLATE_CONTEXT_PROCESSORS`` setting.
+
+.. note::
+
+ There is also an independent but related :setting:`USE_L10N` setting that
+ controls if Django should implement format localization.
+
+ If :setting:`USE_L10N` is set to ``True``, Django will handle numbers times,
+ and dates in the format of the current locale. That includes representation
+ of these field types on templates and allowed input formats for dates,
+ times on model forms.
+
+ See :ref:`format-localization` for more details.
+
+If you do need internationalization
+===================================
+
+.. _how-django-discovers-language-preference:
+
+How Django discovers language preference
+----------------------------------------
+
+Once you've prepared your translations -- or, if you just want to use the
+translations that come with Django -- you'll just need to activate translation
+for your app.
+
+Behind the scenes, Django has a very flexible model of deciding which language
+should be used -- installation-wide, for a particular user, or both.
+
+To set an installation-wide language preference, set :setting:`LANGUAGE_CODE`.
+Django uses this language as the default translation -- the final attempt if no
+other translator finds a translation.
+
+If all you want to do is run Django with your native language, and a language
+file is available for it, all you need to do is set ``LANGUAGE_CODE``.
+
+If you want to let each individual user specify which language he or she
+prefers, use ``LocaleMiddleware``. ``LocaleMiddleware`` enables language
+selection based on data from the request. It customizes content for each user.
+
+To use ``LocaleMiddleware``, add ``'django.middleware.locale.LocaleMiddleware'``
+to your ``MIDDLEWARE_CLASSES`` setting. Because middleware order matters, you
+should follow these guidelines:
+
+ * Make sure it's one of the first middlewares installed.
+ * It should come after ``SessionMiddleware``, because ``LocaleMiddleware``
+ makes use of session data.
+ * If you use ``CacheMiddleware``, put ``LocaleMiddleware`` after it.
+
+For example, your ``MIDDLEWARE_CLASSES`` might look like this::
+
+ MIDDLEWARE_CLASSES = (
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.locale.LocaleMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ )
+
+(For more on middleware, see the :doc:`middleware documentation
+</topics/http/middleware>`.)
+
+``LocaleMiddleware`` tries to determine the user's language preference by
+following this algorithm:
+
+ * First, it looks for a ``django_language`` key in the current user's
+ session.
+
+ * Failing that, it looks for a cookie.
+
+ .. versionchanged:: 1.0
+
+ In Django version 0.96 and before, the cookie's name is hard-coded to
+ ``django_language``. In Django 1,0, The cookie name is set by the
+ ``LANGUAGE_COOKIE_NAME`` setting. (The default name is
+ ``django_language``.)
+
+ * Failing that, it looks at the ``Accept-Language`` HTTP header. This
+ header is sent by your browser and tells the server which language(s) you
+ prefer, in order by priority. Django tries each language in the header
+ until it finds one with available translations.
+
+ * Failing that, it uses the global ``LANGUAGE_CODE`` setting.
+
+.. _locale-middleware-notes:
+
+Notes:
+
+ * In each of these places, the language preference is expected to be in the
+ standard :term:`language format<language code>`, as a string. For example,
+ Brazilian Portuguese is ``pt-br``.
+
+ * If a base language is available but the sublanguage specified is not,
+ Django uses the base language. For example, if a user specifies ``de-at``
+ (Austrian German) but Django only has ``de`` available, Django uses
+ ``de``.
+
+ * Only languages listed in the :setting:`LANGUAGES` setting can be selected.
+ If you want to restrict the language selection to a subset of provided
+ languages (because your application doesn't provide all those languages),
+ set ``LANGUAGES`` to a list of languages. For example::
+
+ LANGUAGES = (
+ ('de', _('German')),
+ ('en', _('English')),
+ )
+
+ This example restricts languages that are available for automatic
+ selection to German and English (and any sublanguage, like de-ch or
+ en-us).
+
+ * If you define a custom ``LANGUAGES`` setting, as explained in the
+ previous bullet, it's OK to mark the languages as translation strings
+ -- but use a "dummy" ``ugettext()`` function, not the one in
+ ``django.utils.translation``. You should *never* import
+ ``django.utils.translation`` from within your settings file, because that
+ module in itself depends on the settings, and that would cause a circular
+ import.
+
+ The solution is to use a "dummy" ``ugettext()`` function. Here's a sample
+ settings file::
+
+ ugettext = lambda s: s
+
+ LANGUAGES = (
+ ('de', ugettext('German')),
+ ('en', ugettext('English')),
+ )
+
+ With this arrangement, ``django-admin.py makemessages`` will still find
+ and mark these strings for translation, but the translation won't happen
+ at runtime -- so you'll have to remember to wrap the languages in the
+ *real* ``ugettext()`` in any code that uses ``LANGUAGES`` at runtime.
+
+ * The ``LocaleMiddleware`` can only select languages for which there is a
+ Django-provided base translation. If you want to provide translations
+ for your application that aren't already in the set of translations
+ in Django's source tree, you'll want to provide at least a basic
+ one as described in the :ref:`Locale restrictions<locale-restrictions>`
+ note.
+
+Once ``LocaleMiddleware`` determines the user's preference, it makes this
+preference available as ``request.LANGUAGE_CODE`` for each
+:class:`~django.http.HttpRequest`. Feel free to read this value in your view
+code. Here's a simple example::
+
+ def hello_world(request, count):
+ if request.LANGUAGE_CODE == 'de-at':
+ return HttpResponse("You prefer to read Austrian German.")
+ else:
+ return HttpResponse("You prefer to read another language.")
+
+Note that, with static (middleware-less) translation, the language is in
+``settings.LANGUAGE_CODE``, while with dynamic (middleware) translation, it's
+in ``request.LANGUAGE_CODE``.
+
+.. _settings file: ../settings/
+.. _middleware documentation: ../middleware/
+.. _session: ../sessions/
+.. _request object: ../request_response/#httprequest-objects
+
+How Django discovers translations
+---------------------------------
+
+As described in :ref:`using-translations-in-your-own-projects`,
+at runtime, Django looks for translations by following this algorithm:
+
+ * First, it looks for a ``locale`` directory in the directory containing
+ your settings file.
+ * Second, it looks for a ``locale`` directory in the project directory.
+ * Third, it looks for a ``locale`` directory in each of the installed apps.
+ It does this in the reverse order of INSTALLED_APPS
+ * Finally, it checks the Django-provided base translation in
+ ``django/conf/locale``.
+
+In all cases the name of the directory containing the translation is expected to
+be named using :term:`locale name` notation. E.g. ``de``, ``pt_BR``, ``es_AR``,
+etc.
diff --git a/parts/django/docs/topics/i18n/index.txt b/parts/django/docs/topics/i18n/index.txt
new file mode 100644
index 0000000..9c25192
--- /dev/null
+++ b/parts/django/docs/topics/i18n/index.txt
@@ -0,0 +1,113 @@
+=====================================
+Internationalization and localization
+=====================================
+
+Overview
+========
+
+Django has full support for internationalization of text in code and
+templates, and format localization of dates and numbers. Here's how it works.
+
+Essentially, Django does two things:
+
+ * It allows developers and template authors to specify which parts of
+ their apps should be translatable.
+ * It uses these hooks to translate Web apps for particular users according
+ to their language preferences.
+
+The complete process can be seen as divided in three stages. It is also possible
+to identify an identical number of roles with very well defined responsibilities
+associated with each of these tasks (although it's perfectly normal if you
+find yourself performing more than one of these roles):
+
+ * For application authors wishing to make sure their Django apps can be
+ used in different locales: :doc:`/topics/i18n/internationalization`.
+ * For translators wanting to translate Django apps: :doc:`/topics/i18n/localization`.
+ * For system administrators/final users setting up internationalized apps or
+ developers integrating third party apps: :doc:`/topics/i18n/deployment`.
+
+.. toctree::
+ :hidden:
+ :maxdepth: 1
+
+ internationalization
+ localization
+ deployment
+
+.. _ seealso::
+
+For more general information about the topic, see the `GNU gettext documentation`_
+and the `Wikipedia article`_.
+
+.. _GNU gettext documentation: http://www.gnu.org/software/gettext/manual/gettext.html#Concepts
+.. _Wikipedia article: http://en.wikipedia.org/wiki/Internationalization_and_localization
+
+Glossary
+========
+
+First lets define some terms that will help us to handle a common language:
+
+.. glossary::
+
+ locale name
+ A locale name, either a language specification of the form ``ll`` or a
+ combined language and country specification of the form ``ll_CC``.
+ Examples: ``it``, ``de_AT``, ``es``, ``pt_BR``. Note the underscore in
+ some of them and the case of the part located to its right.
+
+ language code
+ Represents the name of a language. Browsers send the names of the
+ languages they accept in the ``Accept-Language`` HTTP header using this
+ format. Examples: ``it``, ``de-at``, ``es``, ``pt-br``. Note the ``-``
+ separator.
+
+ message file
+ A message file is a plain-text file, representing a single language,
+ that contains all available :term:`translation strings
+ <translation string>` and how they should be represented in the given
+ language. Message files have a ``.po`` file extension.
+
+ translation string
+ A literal that can be translated.
+
+.. _specialties-of-django-i18n:
+
+Specialties of Django translation
+=================================
+
+Django's translation machinery uses the standard ``gettext`` module that comes
+with Python. If you know ``gettext``, you might note these specialties in the
+way Django does translation:
+
+ * The string domain is ``django`` or ``djangojs``. This string domain is
+ used to differentiate between different programs that store their data
+ in a common message-file library (usually ``/usr/share/locale/``). The
+ ``django`` domain is used for python and template translation strings
+ and is loaded into the global translation catalogs. The ``djangojs``
+ domain is only used for JavaScript translation catalogs to make sure
+ that those are as small as possible.
+ * Django doesn't use ``xgettext`` alone. It uses Python wrappers around
+ ``xgettext`` and ``msgfmt``. This is mostly for convenience.
+
+.. _technical-messages:
+
+Django technical message IDs
+----------------------------
+
+.. versionchanged:: 1.2
+ Starting with Django 1.2, technical message IDs are being replaced by :ref:`format-localization`
+
+Django uses technical message IDs to translate date formats and time formats.
+Technical message IDs are :term:`translation strings <translation string>` and
+can be easily recognized; they're all upper case. You don't translate the
+message ID as with other translation strings, you provide the correct local
+variant on the provided English value. The format is identical to the format
+strings used by the ``now`` template tag.
+
+For example, with ``DATETIME_FORMAT`` (or ``DATE_FORMAT`` or ``TIME_FORMAT``),
+this would be the format string that you want to use in your language. A Django
+contributor localizing it to Spanish probably would provide a ``"j N Y P"``
+"translation" for it in the relevant ``django.po`` file::
+
+ msgid "DATETIME_FORMAT"
+ msgstr "j N Y P"
diff --git a/parts/django/docs/topics/i18n/internationalization.txt b/parts/django/docs/topics/i18n/internationalization.txt
new file mode 100644
index 0000000..b6847ea
--- /dev/null
+++ b/parts/django/docs/topics/i18n/internationalization.txt
@@ -0,0 +1,624 @@
+====================
+Internationalization
+====================
+
+Overview
+========
+
+The goal of internationalization is to allow a single Web application to offer
+its content and functionality in multiple languages and locales.
+
+For text translations, you, the Django developer, can accomplish this goal by
+adding a minimal amount of hooks to your Python and templates. These hooks
+are called **translation strings**. They tell Django: "This text should be
+translated into the end user's language, if a translation for this text is
+available in that language." It's your responsibility to mark translatable
+strings; the system can only translate strings it knows about.
+
+Django takes care of using these hooks to translate Web apps, on the fly,
+according to users' language preferences.
+
+Specifying translation strings: In Python code
+==============================================
+
+Standard translation
+--------------------
+
+Specify a translation string by using the function ``ugettext()``. It's
+convention to import this as a shorter alias, ``_``, to save typing.
+
+.. note::
+ Python's standard library ``gettext`` module installs ``_()`` into the
+ global namespace, as an alias for ``gettext()``. In Django, we have chosen
+ not to follow this practice, for a couple of reasons:
+
+ 1. For international character set (Unicode) support, ``ugettext()`` is
+ more useful than ``gettext()``. Sometimes, you should be using
+ ``ugettext_lazy()`` as the default translation method for a particular
+ file. Without ``_()`` in the global namespace, the developer has to
+ think about which is the most appropriate translation function.
+
+ 2. The underscore character (``_``) is used to represent "the previous
+ result" in Python's interactive shell and doctest tests. Installing a
+ global ``_()`` function causes interference. Explicitly importing
+ ``ugettext()`` as ``_()`` avoids this problem.
+
+.. highlightlang:: python
+
+In this example, the text ``"Welcome to my site."`` is marked as a translation
+string::
+
+ from django.utils.translation import ugettext as _
+
+ def my_view(request):
+ output = _("Welcome to my site.")
+ return HttpResponse(output)
+
+Obviously, you could code this without using the alias. This example is
+identical to the previous one::
+
+ from django.utils.translation import ugettext
+
+ def my_view(request):
+ output = ugettext("Welcome to my site.")
+ return HttpResponse(output)
+
+Translation works on computed values. This example is identical to the previous
+two::
+
+ def my_view(request):
+ words = ['Welcome', 'to', 'my', 'site.']
+ output = _(' '.join(words))
+ return HttpResponse(output)
+
+Translation works on variables. Again, here's an identical example::
+
+ def my_view(request):
+ sentence = 'Welcome to my site.'
+ output = _(sentence)
+ return HttpResponse(output)
+
+(The caveat with using variables or computed values, as in the previous two
+examples, is that Django's translation-string-detecting utility,
+``django-admin.py makemessages``, won't be able to find these strings. More on
+``makemessages`` later.)
+
+The strings you pass to ``_()`` or ``ugettext()`` can take placeholders,
+specified with Python's standard named-string interpolation syntax. Example::
+
+ def my_view(request, m, d):
+ output = _('Today is %(month)s %(day)s.') % {'month': m, 'day': d}
+ return HttpResponse(output)
+
+This technique lets language-specific translations reorder the placeholder
+text. For example, an English translation may be ``"Today is November 26."``,
+while a Spanish translation may be ``"Hoy es 26 de Noviembre."`` -- with the
+the month and the day placeholders swapped.
+
+For this reason, you should use named-string interpolation (e.g., ``%(day)s``)
+instead of positional interpolation (e.g., ``%s`` or ``%d``) whenever you
+have more than a single parameter. If you used positional interpolation,
+translations wouldn't be able to reorder placeholder text.
+
+Marking strings as no-op
+------------------------
+
+Use the function ``django.utils.translation.ugettext_noop()`` to mark a string
+as a translation string without translating it. The string is later translated
+from a variable.
+
+Use this if you have constant strings that should be stored in the source
+language because they are exchanged over systems or users -- such as strings in
+a database -- but should be translated at the last possible point in time, such
+as when the string is presented to the user.
+
+Pluralization
+-------------
+
+Use the function ``django.utils.translation.ungettext()`` to specify pluralized
+messages.
+
+``ungettext`` takes three arguments: the singular translation string, the plural
+translation string and the number of objects.
+
+This function is useful when you need your Django application to be localizable
+to languages where the number and complexity of `plural forms
+<http://www.gnu.org/software/gettext/manual/gettext.html#Plural-forms>`_ is
+greater than the two forms used in English ('object' for the singular and
+'objects' for all the cases where ``count`` is different from zero, irrespective
+of its value.)
+
+For example::
+
+ from django.utils.translation import ungettext
+ def hello_world(request, count):
+ page = ungettext('there is %(count)d object', 'there are %(count)d objects', count) % {
+ 'count': count,
+ }
+ return HttpResponse(page)
+
+In this example the number of objects is passed to the translation languages as
+the ``count`` variable.
+
+Lets see a slightly more complex usage example::
+
+ from django.utils.translation import ungettext
+
+ count = Report.objects.count()
+ if count == 1:
+ name = Report._meta.verbose_name
+ else:
+ name = Report._meta.verbose_name_plural
+
+ text = ungettext(
+ 'There is %(count)d %(name)s available.',
+ 'There are %(count)d %(name)s available.',
+ count
+ ) % {
+ 'count': count,
+ 'name': name
+ }
+
+Here we reuse localizable, hopefully already translated literals (contained in
+the ``verbose_name`` and ``verbose_name_plural`` model ``Meta`` options) for
+other parts of the sentence so all of it is consistently based on the
+cardinality of the elements at play.
+
+.. _pluralization-var-notes:
+
+.. note::
+
+ When using this technique, make sure you use a single name for every
+ extrapolated variable included in the literal. In the example above note how
+ we used the ``name`` Python variable in both translation strings. This
+ example would fail::
+
+ from django.utils.translation import ungettext
+ from myapp.models import Report
+
+ count = Report.objects.count()
+ d = {
+ 'count': count,
+ 'name': Report._meta.verbose_name,
+ 'plural_name': Report._meta.verbose_name_plural
+ }
+ text = ungettext(
+ 'There is %(count)d %(name)s available.',
+ 'There are %(count)d %(plural_name)s available.',
+ count
+ ) % d
+
+ You would get a ``a format specification for argument 'name', as in
+ 'msgstr[0]', doesn't exist in 'msgid'`` error when running
+ ``django-admin.py compilemessages``.
+
+.. _lazy-translations:
+
+Lazy translation
+----------------
+
+Use the function ``django.utils.translation.ugettext_lazy()`` to translate
+strings lazily -- when the value is accessed rather than when the
+``ugettext_lazy()`` function is called.
+
+For example, to translate a model's ``help_text``, do the following::
+
+ from django.utils.translation import ugettext_lazy
+
+ class MyThing(models.Model):
+ name = models.CharField(help_text=ugettext_lazy('This is the help text'))
+
+In this example, ``ugettext_lazy()`` stores a lazy reference to the string --
+not the actual translation. The translation itself will be done when the string
+is used in a string context, such as template rendering on the Django admin
+site.
+
+The result of a ``ugettext_lazy()`` call can be used wherever you would use a
+unicode string (an object with type ``unicode``) in Python. If you try to use
+it where a bytestring (a ``str`` object) is expected, things will not work as
+expected, since a ``ugettext_lazy()`` object doesn't know how to convert
+itself to a bytestring. You can't use a unicode string inside a bytestring,
+either, so this is consistent with normal Python behavior. For example::
+
+ # This is fine: putting a unicode proxy into a unicode string.
+ u"Hello %s" % ugettext_lazy("people")
+
+ # This will not work, since you cannot insert a unicode object
+ # into a bytestring (nor can you insert our unicode proxy there)
+ "Hello %s" % ugettext_lazy("people")
+
+If you ever see output that looks like ``"hello
+<django.utils.functional...>"``, you have tried to insert the result of
+``ugettext_lazy()`` into a bytestring. That's a bug in your code.
+
+If you don't like the verbose name ``ugettext_lazy``, you can just alias it as
+``_`` (underscore), like so::
+
+ from django.utils.translation import ugettext_lazy as _
+
+ class MyThing(models.Model):
+ name = models.CharField(help_text=_('This is the help text'))
+
+Always use lazy translations in :doc:`Django models </topics/db/models>`.
+Field names and table names should be marked for translation (otherwise, they
+won't be translated in the admin interface). This means writing explicit
+``verbose_name`` and ``verbose_name_plural`` options in the ``Meta`` class,
+though, rather than relying on Django's default determination of
+``verbose_name`` and ``verbose_name_plural`` by looking at the model's class
+name::
+
+ from django.utils.translation import ugettext_lazy as _
+
+ class MyThing(models.Model):
+ name = models.CharField(_('name'), help_text=_('This is the help text'))
+ class Meta:
+ verbose_name = _('my thing')
+ verbose_name_plural = _('mythings')
+
+Working with lazy translation objects
+-------------------------------------
+
+.. highlightlang:: python
+
+Using ``ugettext_lazy()`` and ``ungettext_lazy()`` to mark strings in models
+and utility functions is a common operation. When you're working with these
+objects elsewhere in your code, you should ensure that you don't accidentally
+convert them to strings, because they should be converted as late as possible
+(so that the correct locale is in effect). This necessitates the use of a
+couple of helper functions.
+
+Joining strings: string_concat()
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Standard Python string joins (``''.join([...])``) will not work on lists
+containing lazy translation objects. Instead, you can use
+``django.utils.translation.string_concat()``, which creates a lazy object that
+concatenates its contents *and* converts them to strings only when the result
+is included in a string. For example::
+
+ from django.utils.translation import string_concat
+ ...
+ name = ugettext_lazy(u'John Lennon')
+ instrument = ugettext_lazy(u'guitar')
+ result = string_concat(name, ': ', instrument)
+
+In this case, the lazy translations in ``result`` will only be converted to
+strings when ``result`` itself is used in a string (usually at template
+rendering time).
+
+The allow_lazy() decorator
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Django offers many utility functions (particularly in ``django.utils``) that
+take a string as their first argument and do something to that string. These
+functions are used by template filters as well as directly in other code.
+
+If you write your own similar functions and deal with translations, you'll
+face the problem of what to do when the first argument is a lazy translation
+object. You don't want to convert it to a string immediately, because you might
+be using this function outside of a view (and hence the current thread's locale
+setting will not be correct).
+
+For cases like this, use the ``django.utils.functional.allow_lazy()``
+decorator. It modifies the function so that *if* it's called with a lazy
+translation as the first argument, the function evaluation is delayed until it
+needs to be converted to a string.
+
+For example::
+
+ from django.utils.functional import allow_lazy
+
+ def fancy_utility_function(s, ...):
+ # Do some conversion on string 's'
+ ...
+ fancy_utility_function = allow_lazy(fancy_utility_function, unicode)
+
+The ``allow_lazy()`` decorator takes, in addition to the function to decorate,
+a number of extra arguments (``*args``) specifying the type(s) that the
+original function can return. Usually, it's enough to include ``unicode`` here
+and ensure that your function returns only Unicode strings.
+
+Using this decorator means you can write your function and assume that the
+input is a proper string, then add support for lazy translation objects at the
+end.
+
+.. _specifying-translation-strings-in-template-code:
+
+Specifying translation strings: In template code
+================================================
+
+.. highlightlang:: html+django
+
+Translations in :doc:`Django templates </topics/templates>` uses two template
+tags and a slightly different syntax than in Python code. To give your template
+access to these tags, put ``{% load i18n %}`` toward the top of your template.
+
+``trans`` template tag
+----------------------
+
+The ``{% trans %}`` template tag translates either a constant string
+(enclosed in single or double quotes) or variable content::
+
+ <title>{% trans "This is the title." %}</title>
+ <title>{% trans myvar %}</title>
+
+If the ``noop`` option is present, variable lookup still takes place but the
+translation is skipped. This is useful when "stubbing out" content that will
+require translation in the future::
+
+ <title>{% trans "myvar" noop %}</title>
+
+Internally, inline translations use an ``ugettext`` call.
+
+In case a template var (``myvar`` above) is passed to the tag, the tag will
+first resolve such variable to a string at run-time and then look up that
+string in the message catalogs.
+
+It's not possible to mix a template variable inside a string within ``{% trans
+%}``. If your translations require strings with variables (placeholders), use
+``{% blocktrans %}`` instead.
+
+``blocktrans`` template tag
+---------------------------
+
+Contrarily to the ``trans`` tag, the ``blocktrans`` tag allows you to mark
+complex sentences consisting of literals and variable content for translation
+by making use of placeholders::
+
+ {% blocktrans %}This string will have {{ value }} inside.{% endblocktrans %}
+
+To translate a template expression -- say, accessing object attributes or
+using template filters -- you need to bind the expression to a local variable
+for use within the translation block. Examples::
+
+ {% blocktrans with article.price as amount %}
+ That will cost $ {{ amount }}.
+ {% endblocktrans %}
+
+ {% blocktrans with value|filter as myvar %}
+ This will have {{ myvar }} inside.
+ {% endblocktrans %}
+
+If you need to bind more than one expression inside a ``blocktrans`` tag,
+separate the pieces with ``and``::
+
+ {% blocktrans with book|title as book_t and author|title as author_t %}
+ This is {{ book_t }} by {{ author_t }}
+ {% endblocktrans %}
+
+This tag also provides for pluralization. To use it:
+
+ * Designate and bind a counter value with the name ``count``. This value will
+ be the one used to select the right plural form.
+
+ * Specify both the singular and plural forms separating them with the
+ ``{% plural %}`` tag within the ``{% blocktrans %}`` and
+ ``{% endblocktrans %}`` tags.
+
+An example::
+
+ {% blocktrans count list|length as counter %}
+ There is only one {{ name }} object.
+ {% plural %}
+ There are {{ counter }} {{ name }} objects.
+ {% endblocktrans %}
+
+A more complex example::
+
+ {% blocktrans with article.price as amount count i.length as years %}
+ That will cost $ {{ amount }} per year.
+ {% plural %}
+ That will cost $ {{ amount }} per {{ years }} years.
+ {% endblocktrans %}
+
+When you use both the pluralization feature and bind values to local variables
+in addition to the counter value, keep in mind that the ``blocktrans``
+construct is internally converted to an ``ungettext`` call. This means the
+same :ref:`notes regarding ungettext variables <pluralization-var-notes>`
+apply.
+
+.. _template-translation-vars:
+
+Other tags
+----------
+
+Each ``RequestContext`` has access to three translation-specific variables:
+
+ * ``LANGUAGES`` is a list of tuples in which the first element is the
+ :term:`language code` and the second is the language name (translated into
+ the currently active locale).
+
+ * ``LANGUAGE_CODE`` is the current user's preferred language, as a string.
+ Example: ``en-us``. (See :ref:`how-django-discovers-language-preference`.)
+
+ * ``LANGUAGE_BIDI`` is the current locale's direction. If True, it's a
+ right-to-left language, e.g.: Hebrew, Arabic. If False it's a
+ left-to-right language, e.g.: English, French, German etc.
+
+If you don't use the ``RequestContext`` extension, you can get those values with
+three tags::
+
+ {% get_current_language as LANGUAGE_CODE %}
+ {% get_available_languages as LANGUAGES %}
+ {% get_current_language_bidi as LANGUAGE_BIDI %}
+
+These tags also require a ``{% load i18n %}``.
+
+Translation hooks are also available within any template block tag that accepts
+constant strings. In those cases, just use ``_()`` syntax to specify a
+translation string::
+
+ {% some_special_tag _("Page not found") value|yesno:_("yes,no") %}
+
+In this case, both the tag and the filter will see the already-translated
+string, so they don't need to be aware of translations.
+
+.. note::
+ In this example, the translation infrastructure will be passed the string
+ ``"yes,no"``, not the individual strings ``"yes"`` and ``"no"``. The
+ translated string will need to contain the comma so that the filter
+ parsing code knows how to split up the arguments. For example, a German
+ translator might translate the string ``"yes,no"`` as ``"ja,nein"``
+ (keeping the comma intact).
+
+.. _Django templates: ../templates_python/
+
+Specifying translation strings: In JavaScript code
+==================================================
+
+Adding translations to JavaScript poses some problems:
+
+ * JavaScript code doesn't have access to a ``gettext`` implementation.
+
+ * JavaScript code doesn't have access to .po or .mo files; they need to be
+ delivered by the server.
+
+ * The translation catalogs for JavaScript should be kept as small as
+ possible.
+
+Django provides an integrated solution for these problems: It passes the
+translations into JavaScript, so you can call ``gettext``, etc., from within
+JavaScript.
+
+The ``javascript_catalog`` view
+-------------------------------
+
+.. module:: django.views.i18n
+
+.. function:: javascript_catalog(request, domain='djangojs', packages=None)
+
+The main solution to these problems is the :meth:`django.views.i18n.javascript_catalog`
+view, which sends out a JavaScript code library with functions that mimic the
+``gettext`` interface, plus an array of translation strings. Those translation
+strings are taken from the application, project or Django core, according to what
+you specify in either the info_dict or the URL.
+
+You hook it up like this::
+
+ js_info_dict = {
+ 'packages': ('your.app.package',),
+ }
+
+ urlpatterns = patterns('',
+ (r'^jsi18n/$', 'django.views.i18n.javascript_catalog', js_info_dict),
+ )
+
+Each string in ``packages`` should be in Python dotted-package syntax (the
+same format as the strings in ``INSTALLED_APPS``) and should refer to a package
+that contains a ``locale`` directory. If you specify multiple packages, all
+those catalogs are merged into one catalog. This is useful if you have
+JavaScript that uses strings from different applications.
+
+By default, the view uses the ``djangojs`` gettext domain. This can be
+changed by altering the ``domain`` argument.
+
+You can make the view dynamic by putting the packages into the URL pattern::
+
+ urlpatterns = patterns('',
+ (r'^jsi18n/(?P<packages>\S+?)/$', 'django.views.i18n.javascript_catalog'),
+ )
+
+With this, you specify the packages as a list of package names delimited by '+'
+signs in the URL. This is especially useful if your pages use code from
+different apps and this changes often and you don't want to pull in one big
+catalog file. As a security measure, these values can only be either
+``django.conf`` or any package from the ``INSTALLED_APPS`` setting.
+
+Using the JavaScript translation catalog
+----------------------------------------
+
+To use the catalog, just pull in the dynamically generated script like this::
+
+ <script type="text/javascript" src="{% url django.views.i18n.javascript_catalog %}"></script>
+
+This uses reverse URL lookup to find the URL of the JavaScript catalog view.
+When the catalog is loaded, your JavaScript code can use the standard
+``gettext`` interface to access it::
+
+ document.write(gettext('this is to be translated'));
+
+There is also an ``ngettext`` interface::
+
+ var object_cnt = 1 // or 0, or 2, or 3, ...
+ s = ngettext('literal for the singular case',
+ 'literal for the plural case', object_cnt);
+
+and even a string interpolation function::
+
+ function interpolate(fmt, obj, named);
+
+The interpolation syntax is borrowed from Python, so the ``interpolate``
+function supports both positional and named interpolation:
+
+ * Positional interpolation: ``obj`` contains a JavaScript Array object
+ whose elements values are then sequentially interpolated in their
+ corresponding ``fmt`` placeholders in the same order they appear.
+ For example::
+
+ fmts = ngettext('There is %s object. Remaining: %s',
+ 'There are %s objects. Remaining: %s', 11);
+ s = interpolate(fmts, [11, 20]);
+ // s is 'There are 11 objects. Remaining: 20'
+
+ * Named interpolation: This mode is selected by passing the optional
+ boolean ``named`` parameter as true. ``obj`` contains a JavaScript
+ object or associative array. For example::
+
+ d = {
+ count: 10,
+ total: 50
+ };
+
+ fmts = ngettext('Total: %(total)s, there is %(count)s object',
+ 'there are %(count)s of a total of %(total)s objects', d.count);
+ s = interpolate(fmts, d, true);
+
+You shouldn't go over the top with string interpolation, though: this is still
+JavaScript, so the code has to make repeated regular-expression substitutions.
+This isn't as fast as string interpolation in Python, so keep it to those
+cases where you really need it (for example, in conjunction with ``ngettext``
+to produce proper pluralizations).
+
+The ``set_language`` redirect view
+==================================
+
+.. function:: set_language(request)
+
+As a convenience, Django comes with a view, :meth:`django.views.i18n.set_language`,
+that sets a user's language preference and redirects back to the previous page.
+
+Activate this view by adding the following line to your URLconf::
+
+ (r'^i18n/', include('django.conf.urls.i18n')),
+
+(Note that this example makes the view available at ``/i18n/setlang/``.)
+
+The view expects to be called via the ``POST`` method, with a ``language``
+parameter set in request. If session support is enabled, the view
+saves the language choice in the user's session. Otherwise, it saves the
+language choice in a cookie that is by default named ``django_language``.
+(The name can be changed through the ``LANGUAGE_COOKIE_NAME`` setting.)
+
+After setting the language choice, Django redirects the user, following this
+algorithm:
+
+ * Django looks for a ``next`` parameter in the ``POST`` data.
+ * If that doesn't exist, or is empty, Django tries the URL in the
+ ``Referrer`` header.
+ * If that's empty -- say, if a user's browser suppresses that header --
+ then the user will be redirected to ``/`` (the site root) as a fallback.
+
+Here's example HTML template code:
+
+.. code-block:: html+django
+
+ <form action="/i18n/setlang/" method="post">
+ {% csrf_token %}
+ <input name="next" type="hidden" value="/next/page/" />
+ <select name="language">
+ {% for lang in LANGUAGES %}
+ <option value="{{ lang.0 }}">{{ lang.1 }}</option>
+ {% endfor %}
+ </select>
+ <input type="submit" value="Go" />
+ </form>
diff --git a/parts/django/docs/topics/i18n/localization.txt b/parts/django/docs/topics/i18n/localization.txt
new file mode 100644
index 0000000..38d74e6
--- /dev/null
+++ b/parts/django/docs/topics/i18n/localization.txt
@@ -0,0 +1,317 @@
+============
+Localization
+============
+
+This document covers two localization-related topics: `Creating language
+files`_ and `locale aware date, time and numbers input/output in forms`_
+
+.. _`Creating language files`: how-to-create-language-files_
+.. _`locale aware date, time and numbers input/output in forms`: format-localization_
+
+.. seealso::
+
+ The :doc:`/howto/i18n` document included with the Django HOW-TO documents collection.
+
+.. _how-to-create-language-files:
+
+How to create language files
+============================
+
+Once the string literals of an application have been tagged for later
+translation, the translation themselves need to be written (or obtained). Here's
+how that works.
+
+.. _locale-restrictions:
+
+.. admonition:: Locale restrictions
+
+ Django does not support localizing your application into a locale for which
+ Django itself has not been translated. In this case, it will ignore your
+ translation files. If you were to try this and Django supported it, you
+ would inevitably see a mixture of translated strings (from your application)
+ and English strings (from Django itself). If you want to support a locale
+ for your application that is not already part of Django, you'll need to make
+ at least a minimal translation of the Django core.
+
+ A good starting point is to copy the Django English ``.po`` file and to
+ translate at least some :term:`translation strings <translation string>`.
+
+Message files
+-------------
+
+The first step is to create a :term:`message file` for a new language. A message
+file is a plain-text file, representing a single language, that contains all
+available translation strings and how they should be represented in the given
+language. Message files have a ``.po`` file extension.
+
+Django comes with a tool, ``django-admin.py makemessages``, that automates the
+creation and upkeep of these files.
+
+.. admonition:: A note to Django veterans
+
+ The old tool ``bin/make-messages.py`` has been moved to the command
+ ``django-admin.py makemessages`` to provide consistency throughout Django.
+
+.. admonition:: Gettext utilities
+
+ The ``makemessages`` command (and ``compilemessages`` discussed later) use
+ commands from the GNU gettext toolset: ``xgettext``, ``msgfmt``,
+ ``msgmerge`` and ``msguniq``.
+
+ .. versionchanged:: 1.2
+
+ The minimum version of the ``gettext`` utilities supported is 0.15.
+
+To create or update a message file, run this command::
+
+ django-admin.py makemessages -l de
+
+...where ``de`` is the language code for the message file you want to create.
+The language code, in this case, is in :term:`locale format<locale name>`. For
+example, it's ``pt_BR`` for Brazilian Portuguese and ``de_AT`` for Austrian
+German.
+
+The script should be run from one of two places:
+
+ * The root directory of your Django project.
+ * The root directory of your Django app.
+
+The script runs over your project source tree or your application source tree
+and pulls out all strings marked for translation. It creates (or updates) a
+message file in the directory ``locale/LANG/LC_MESSAGES``. In the ``de``
+example, the file will be ``locale/de/LC_MESSAGES/django.po``.
+
+By default ``django-admin.py makemessages`` examines every file that has the
+``.html`` file extension. In case you want to override that default, use the
+``--extension`` or ``-e`` option to specify the file extensions to examine::
+
+ django-admin.py makemessages -l de -e txt
+
+Separate multiple extensions with commas and/or use ``-e`` or ``--extension``
+multiple times::
+
+ django-admin.py makemessages -l de -e html,txt -e xml
+
+When :ref:`creating message files from JavaScript source code
+<creating-message-files-from-js-code>` you need to use the special 'djangojs'
+domain, **not** ``-e js``.
+
+.. admonition:: No gettext?
+
+ If you don't have the ``gettext`` utilities installed, ``django-admin.py
+ makemessages`` will create empty files. If that's the case, either install
+ the ``gettext`` utilities or just copy the English message file
+ (``locale/en/LC_MESSAGES/django.po``) if available and use it as a starting
+ point; it's just an empty translation file.
+
+.. admonition:: Working on Windows?
+
+ If you're using Windows and need to install the GNU gettext utilities so
+ ``django-admin makemessages`` works see :ref:`gettext_on_windows` for more
+ information.
+
+The format of ``.po`` files is straightforward. Each ``.po`` file contains a
+small bit of metadata, such as the translation maintainer's contact
+information, but the bulk of the file is a list of **messages** -- simple
+mappings between translation strings and the actual translated text for the
+particular language.
+
+For example, if your Django app contained a translation string for the text
+``"Welcome to my site."``, like so::
+
+ _("Welcome to my site.")
+
+...then ``django-admin.py makemessages`` will have created a ``.po`` file
+containing the following snippet -- a message::
+
+ #: path/to/python/module.py:23
+ msgid "Welcome to my site."
+ msgstr ""
+
+A quick explanation:
+
+ * ``msgid`` is the translation string, which appears in the source. Don't
+ change it.
+ * ``msgstr`` is where you put the language-specific translation. It starts
+ out empty, so it's your responsibility to change it. Make sure you keep
+ the quotes around your translation.
+ * As a convenience, each message includes, in the form of a comment line
+ prefixed with ``#`` and located above the ``msgid`` line, the filename and
+ line number from which the translation string was gleaned.
+
+Long messages are a special case. There, the first string directly after the
+``msgstr`` (or ``msgid``) is an empty string. Then the content itself will be
+written over the next few lines as one string per line. Those strings are
+directly concatenated. Don't forget trailing spaces within the strings;
+otherwise, they'll be tacked together without whitespace!
+
+.. admonition:: Mind your charset
+
+ When creating a PO file with your favorite text editor, first edit
+ the charset line (search for ``"CHARSET"``) and set it to the charset
+ you'll be using to edit the content. Due to the way the ``gettext`` tools
+ work internally and because we want to allow non-ASCII source strings in
+ Django's core and your applications, you **must** use UTF-8 as the encoding
+ for your PO file. This means that everybody will be using the same
+ encoding, which is important when Django processes the PO files.
+
+To reexamine all source code and templates for new translation strings and
+update all message files for **all** languages, run this::
+
+ django-admin.py makemessages -a
+
+Compiling message files
+-----------------------
+
+After you create your message file -- and each time you make changes to it --
+you'll need to compile it into a more efficient form, for use by ``gettext``.
+Do this with the ``django-admin.py compilemessages`` utility.
+
+This tool runs over all available ``.po`` files and creates ``.mo`` files, which
+are binary files optimized for use by ``gettext``. In the same directory from
+which you ran ``django-admin.py makemessages``, run ``django-admin.py
+compilemessages`` like this::
+
+ django-admin.py compilemessages
+
+That's it. Your translations are ready for use.
+
+.. admonition:: A note to Django veterans
+
+ The old tool ``bin/compile-messages.py`` has been moved to the command
+ ``django-admin.py compilemessages`` to provide consistency throughout
+ Django.
+
+.. admonition:: Working on Windows?
+
+ If you're using Windows and need to install the GNU gettext utilities so
+ ``django-admin compilemessages`` works see :ref:`gettext_on_windows` for more
+ information.
+
+.. admonition:: .po files: Encoding and BOM usage.
+
+ Django only supports ``.po`` files encoded in UTF-8 and without any BOM
+ (Byte Order Mark) so if your text editor adds such marks to the beginning of
+ files by default then you will need to reconfigure it.
+
+.. _creating-message-files-from-js-code:
+
+Creating message files from JavaScript source code
+==================================================
+
+You create and update the message files the same way as the other Django message
+files -- with the ``django-admin.py makemessages`` tool. The only difference is
+you need to provide a ``-d djangojs`` parameter, like this::
+
+ django-admin.py makemessages -d djangojs -l de
+
+This would create or update the message file for JavaScript for German.
+After updating message files, just run ``django-admin.py compilemessages``
+the same way as you do with normal Django message files.
+
+.. _gettext_on_windows:
+
+``gettext`` on Windows
+======================
+
+This is only needed for people who either want to extract message IDs or compile
+message files (``.po``). Translation work itself just involves editing existing
+files of this type, but if you want to create your own message files, or want to
+test or compile a changed message file, you will need the ``gettext`` utilities:
+
+ * Download the following zip files from the GNOME servers
+ http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/ or from one
+ of its mirrors_
+
+ * ``gettext-runtime-X.zip``
+ * ``gettext-tools-X.zip``
+
+ ``X`` is the version number, we are requiring ``0.15`` or higher.
+
+ * Extract the contents of the ``bin\`` directories in both files to the
+ same folder on your system (i.e. ``C:\Program Files\gettext-utils``)
+
+ * Update the system PATH:
+
+ * ``Control Panel > System > Advanced > Environment Variables``.
+ * In the ``System variables`` list, click ``Path``, click ``Edit``.
+ * Add ``;C:\Program Files\gettext-utils\bin`` at the end of the
+ ``Variable value`` field.
+
+.. _mirrors: http://ftp.gnome.org/pub/GNOME/MIRRORS
+
+You may also use ``gettext`` binaries you have obtained elsewhere, so long as
+the ``xgettext --version`` command works properly. Do not attempt to use Django
+translation utilities with a ``gettext`` package if the command ``xgettext
+--version`` entered at a Windows command prompt causes a popup window saying
+"xgettext.exe has generated errors and will be closed by Windows".
+
+.. _format-localization:
+
+Format localization
+===================
+
+.. versionadded:: 1.2
+
+Django's formatting system is disabled by default. To enable it, it's
+necessary to set :setting:`USE_L10N = True <USE_L10N>` in your settings file.
+
+.. note::
+ The default :file:`settings.py` file created by
+ :djadmin:`django-admin.py startproject <startproject>` includes
+ :setting:`USE_L10N = True <USE_L10N>` for convenience.
+
+When using Django's formatting system, dates and numbers on templates will be
+displayed using the format specified for the current locale. Two users
+accessing the same content, but in different language, will see date and
+number fields formatted in different ways, depending on the format for their
+current locale.
+
+Django will also use localized formats when parsing data in forms. That means
+Django uses different formats for different locales when guessing the format
+used by the user when inputting data on forms.
+
+.. note::
+ Django uses different formats for displaying data to those it uses for
+ parsing data. Most notably, the formats for parsing dates can't use the
+ ``%a`` (abbreviated weekday name), ``%A`` (full weekday name),
+ ``%b`` (abbreviated month name), ``%B`` (full month name),
+ or ``%p`` (AM/PM).
+
+To enable a form field to localize input and output data simply use its
+``localize`` argument::
+
+ class CashRegisterForm(forms.Form):
+ product = forms.CharField()
+ revenue = forms.DecimalField(max_digits=4, decimal_places=2, localize=True)
+
+Creating custom format files
+----------------------------
+
+Django provides format definitions for many locales, but sometimes you might
+want to create your own, because a format files doesn't exist for your locale,
+or because you want to overwrite some of the values.
+
+To use custom formats, first thing to do, is to specify the path where you'll
+place format files. To do that, just set your :setting:`FORMAT_MODULE_PATH`
+setting to the path (in the format ``'foo.bar.baz``) where format files
+will exists.
+
+Files are not placed directly in this directory, but in a directory named as
+the locale, and must be named ``formats.py``.
+
+To customize the English formats, a structure like this would be needed::
+
+ mysite/
+ formats/
+ __init__.py
+ en/
+ __init__.py
+ formats.py
+
+where :file:`formats.py` contains custom format definitions. For example::
+
+ THOUSAND_SEPARATOR = ' '
+
+to use a space as a thousand separator, instead of the default for English,
+a comma.
diff --git a/parts/django/docs/topics/index.txt b/parts/django/docs/topics/index.txt
new file mode 100644
index 0000000..4c6b7fc
--- /dev/null
+++ b/parts/django/docs/topics/index.txt
@@ -0,0 +1,27 @@
+Using Django
+============
+
+Introductions to all the key parts of Django you'll need to know:
+
+.. toctree::
+ :maxdepth: 1
+
+ install
+ db/index
+ http/index
+ forms/index
+ forms/modelforms
+ templates
+ generic-views
+ files
+ testing
+ auth
+ cache
+ conditional-view-processing
+ email
+ i18n/index
+ pagination
+ serialization
+ settings
+ signals
+
diff --git a/parts/django/docs/topics/install.txt b/parts/django/docs/topics/install.txt
new file mode 100644
index 0000000..20c8074
--- /dev/null
+++ b/parts/django/docs/topics/install.txt
@@ -0,0 +1,298 @@
+=====================
+How to install Django
+=====================
+
+This document will get you up and running with Django.
+
+Install Python
+==============
+
+Being a Python Web framework, Django requires Python.
+
+It works with any Python version from 2.4 to 2.7 (due to backwards
+incompatibilities in Python 3.0, Django does not currently work with
+Python 3.0; see :doc:`the Django FAQ </faq/install>` for more
+information on supported Python versions and the 3.0 transition).
+
+Get Python at http://www.python.org. If you're running Linux or Mac OS X, you
+probably already have it installed.
+
+.. admonition:: Django on Jython
+
+ If you use Jython_ (a Python implementation for the Java platform), you'll
+ need to follow a few additional steps. See :doc:`/howto/jython` for details.
+
+.. _jython: http://jython.org/
+
+Install Apache and mod_wsgi
+=============================
+
+If you just want to experiment with Django, skip ahead to the next section;
+Django includes a lightweight Web server you can use for testing, so you won't
+need to set up Apache until you're ready to deploy Django in production.
+
+If you want to use Django on a production site, use Apache with `mod_wsgi`_.
+mod_wsgi is similar to mod_perl -- it embeds Python within Apache and loads
+Python code into memory when the server starts. Code stays in memory throughout
+the life of an Apache process, which leads to significant performance gains over
+other server arrangements. Make sure you have Apache installed, with the
+mod_wsgi module activated. Django will work with any version of Apache that
+supports mod_wsgi.
+
+See :doc:`How to use Django with mod_wsgi </howto/deployment/modwsgi>` for
+information on how to configure mod_wsgi once you have it installed.
+
+If you can't use mod_wsgi for some reason, fear not: Django supports many other
+deployment options. A great second choice is :doc:`mod_python
+</howto/deployment/modpython>`, the predecessor to mod_wsgi. Additionally, Django
+follows the WSGI_ spec, which allows it to run on a variety of server platforms.
+See the `server-arrangements wiki page`_ for specific installation instructions
+for each platform.
+
+.. _Apache: http://httpd.apache.org/
+.. _mod_wsgi: http://code.google.com/p/modwsgi/
+.. _WSGI: http://www.python.org/dev/peps/pep-0333/
+.. _server-arrangements wiki page: http://code.djangoproject.com/wiki/ServerArrangements
+
+.. _database-installation:
+
+Get your database running
+=========================
+
+If you plan to use Django's database API functionality, you'll need to make
+sure a database server is running. Django supports many different database
+servers and is officially supported with PostgreSQL_, MySQL_, Oracle_ and
+SQLite_ (although SQLite doesn't require a separate server to be running).
+
+In addition to the officially supported databases, there are backends provided
+by 3rd parties that allow you to use other databases with Django:
+
+* `Sybase SQL Anywhere`_
+* `IBM DB2`_
+* `Microsoft SQL Server 2005`_
+* Firebird_
+* ODBC_
+
+The Django versions and ORM features supported by these unofficial backends
+vary considerably. Queries regarding the specific capabilities of these
+unofficial backends, along with any support queries, should be directed to the
+support channels provided by each 3rd party project.
+
+In addition to a database backend, you'll need to make sure your Python
+database bindings are installed.
+
+* If you're using PostgreSQL, you'll need the psycopg_ package. Django supports
+ both version 1 and 2. (When you configure Django's database layer, specify
+ either ``postgresql`` [for version 1] or ``postgresql_psycopg2`` [for version 2].)
+ You might want to refer to our :ref:`PostgreSQL notes <postgresql-notes>` for
+ further technical details specific to this database.
+
+ If you're on Windows, check out the unofficial `compiled Windows version`_.
+
+* If you're using MySQL, you'll need MySQLdb_, version 1.2.1p2 or higher. You
+ will also want to read the database-specific :ref:`notes for the MySQL
+ backend <mysql-notes>`.
+
+* If you're using SQLite and Python 2.4, you'll need pysqlite_. Use version
+ 2.0.3 or higher. Python 2.5 ships with an SQLite wrapper in the standard
+ library, so you don't need to install anything extra in that case. Please
+ read the :ref:`SQLite backend notes <sqlite-notes>`.
+
+* If you're using Oracle, you'll need a copy of cx_Oracle_, but please
+ read the database-specific :ref:`notes for the Oracle backend <oracle-notes>`
+ for important information regarding supported versions of both Oracle and
+ ``cx_Oracle``.
+
+* If you're using an unofficial 3rd party backend, please consult the
+ documentation provided for any additional requirements.
+
+If you plan to use Django's ``manage.py syncdb`` command to
+automatically create database tables for your models, you'll need to
+ensure that Django has permission to create and alter tables in the
+database you're using; if you plan to manually create the tables, you
+can simply grant Django ``SELECT``, ``INSERT``, ``UPDATE`` and
+``DELETE`` permissions. On some databases, Django will need
+``ALTER TABLE`` privileges during ``syncdb`` but won't issue
+``ALTER TABLE`` statements on a table once ``syncdb`` has created it.
+
+If you're using Django's :doc:`testing framework</topics/testing>` to test database queries,
+Django will need permission to create a test database.
+
+.. _PostgreSQL: http://www.postgresql.org/
+.. _MySQL: http://www.mysql.com/
+.. _psycopg: http://initd.org/pub/software/psycopg/
+.. _compiled Windows version: http://stickpeople.com/projects/python/win-psycopg/
+.. _MySQLdb: http://sourceforge.net/projects/mysql-python
+.. _SQLite: http://www.sqlite.org/
+.. _pysqlite: http://trac.edgewall.org/wiki/PySqlite
+.. _cx_Oracle: http://cx-oracle.sourceforge.net/
+.. _Oracle: http://www.oracle.com/
+.. _Sybase SQL Anywhere: http://code.google.com/p/sqlany-django/
+.. _IBM DB2: http://code.google.com/p/ibm-db/
+.. _Microsoft SQL Server 2005: http://code.google.com/p/django-mssql/
+.. _Firebird: http://code.google.com/p/django-firebird/
+.. _ODBC: http://code.google.com/p/django-pyodbc/
+.. _removing-old-versions-of-django:
+
+Remove any old versions of Django
+=================================
+
+If you are upgrading your installation of Django from a previous version,
+you will need to uninstall the old Django version before installing the
+new version.
+
+If you installed Django using ``setup.py install``, uninstalling
+is as simple as deleting the ``django`` directory from your Python
+``site-packages``.
+
+If you installed Django from a Python egg, remove the Django ``.egg`` file,
+and remove the reference to the egg in the file named ``easy-install.pth``.
+This file should also be located in your ``site-packages`` directory.
+
+.. admonition:: Where are my ``site-packages`` stored?
+
+ The location of the ``site-packages`` directory depends on the operating
+ system, and the location in which Python was installed. To find out your
+ system's ``site-packages`` location, execute the following:
+
+ .. code-block:: bash
+
+ python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
+
+ (Note that this should be run from a shell prompt, not a Python interactive
+ prompt.)
+
+.. _install-django-code:
+
+Install the Django code
+=======================
+
+Installation instructions are slightly different depending on whether you're
+installing a distribution-specific package, downloading the latest official
+release, or fetching the latest development version.
+
+It's easy, no matter which way you choose.
+
+Installing a distribution-specific package
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Check the :doc:`distribution specific notes </misc/distributions>` to see if your
+platform/distribution provides official Django packages/installers.
+Distribution-provided packages will typically allow for automatic installation
+of dependencies and easy upgrade paths.
+
+.. _installing-official-release:
+
+Installing an official release
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+ 1. Download the latest release from our `download page`_.
+
+ 2. Untar the downloaded file (e.g. ``tar xzvf Django-NNN.tar.gz``,
+ where ``NNN`` is the version number of the latest release).
+ If you're using Windows, you can download the command-line tool
+ bsdtar_ to do this, or you can use a GUI-based tool such as 7-zip_.
+
+ 3. Change into the directory created in step 2 (e.g. ``cd Django-NNN``).
+
+ 4. If you're using Linux, Mac OS X or some other flavor of Unix, enter
+ the command ``sudo python setup.py install`` at the shell prompt.
+ If you're using Windows, start up a command shell with administrator
+ privileges and run the command ``setup.py install``.
+
+These commands will install Django in your Python installation's
+``site-packages`` directory.
+
+.. _bsdtar: http://gnuwin32.sourceforge.net/packages/bsdtar.htm
+.. _7-zip: http://www.7-zip.org/
+
+.. _installing-development-version:
+
+Installing the development version
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. admonition:: Tracking Django development
+
+ If you decide to use the latest development version of Django,
+ you'll want to pay close attention to `the development timeline`_,
+ and you'll want to keep an eye on `the list of
+ backwards-incompatible changes`_. This will help you stay on top
+ of any new features you might want to use, as well as any changes
+ you'll need to make to your code when updating your copy of Django.
+ (For stable releases, any necessary changes are documented in the
+ release notes.)
+
+.. _the development timeline: http://code.djangoproject.com/timeline
+.. _the list of backwards-incompatible changes: http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges
+
+If you'd like to be able to update your Django code occasionally with the
+latest bug fixes and improvements, follow these instructions:
+
+1. Make sure that you have Subversion_ installed, and that you can run its
+ commands from a shell. (Enter ``svn help`` at a shell prompt to test
+ this.)
+
+2. Check out Django's main development branch (the 'trunk') like so:
+
+ .. code-block:: bash
+
+ svn co http://code.djangoproject.com/svn/django/trunk/ django-trunk
+
+3. Next, make sure that the Python interpreter can load Django's code. There
+ are various ways of accomplishing this. One of the most convenient, on
+ Linux, Mac OSX or other Unix-like systems, is to use a symbolic link:
+
+ .. code-block:: bash
+
+ ln -s WORKING-DIR/django-trunk/django SITE-PACKAGES-DIR/django
+
+ (In the above line, change ``SITE-PACKAGES-DIR`` to match the location of
+ your system's ``site-packages`` directory, as explained in the
+ "Where are my ``site-packages`` stored?" section above. Change WORKING-DIR
+ to match the full path to your new ``django-trunk`` directory.)
+
+ Alternatively, you can define your ``PYTHONPATH`` environment variable
+ so that it includes the ``django-trunk`` directory. This is perhaps the
+ most convenient solution on Windows systems, which don't support symbolic
+ links. (Environment variables can be defined on Windows systems `from the
+ Control Panel`_.)
+
+ .. admonition:: What about Apache and mod_python?
+
+ If you take the approach of setting ``PYTHONPATH``, you'll need to
+ remember to do the same thing in your Apache configuration once you
+ deploy your production site. Do this by setting ``PythonPath`` in your
+ Apache configuration file.
+
+ More information about deployment is available, of course, in our
+ :doc:`How to use Django with mod_python </howto/deployment/modpython>`
+ documentation.
+
+4. On Unix-like systems, create a symbolic link to the file
+ ``django-trunk/django/bin/django-admin.py`` in a directory on your system
+ path, such as ``/usr/local/bin``. For example:
+
+ .. code-block:: bash
+
+ ln -s WORKING-DIR/django-trunk/django/bin/django-admin.py /usr/local/bin
+
+ (In the above line, change WORKING-DIR to match the full path to your new
+ ``django-trunk`` directory.)
+
+ This simply lets you type ``django-admin.py`` from within any directory,
+ rather than having to qualify the command with the full path to the file.
+
+ On Windows systems, the same result can be achieved by copying the file
+ ``django-trunk/django/bin/django-admin.py`` to somewhere on your system
+ path, for example ``C:\Python24\Scripts``.
+
+You *don't* have to run ``python setup.py install``, because you've already
+carried out the equivalent actions in steps 3 and 4.
+
+When you want to update your copy of the Django source code, just run the
+command ``svn update`` from within the ``django-trunk`` directory. When you do
+this, Subversion will automatically download any changes.
+
+.. _`download page`: http://www.djangoproject.com/download/
+.. _Subversion: http://subversion.tigris.org/
+.. _from the Control Panel: http://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/sysdm_advancd_environmnt_addchange_variable.mspx
diff --git a/parts/django/docs/topics/pagination.txt b/parts/django/docs/topics/pagination.txt
new file mode 100644
index 0000000..ee8a433
--- /dev/null
+++ b/parts/django/docs/topics/pagination.txt
@@ -0,0 +1,281 @@
+==========
+Pagination
+==========
+
+.. module:: django.core.paginator
+ :synopsis: Classes to help you easily manage paginated data.
+
+.. versionchanged:: 1.0
+ Pagination facilities have been almost fully reworked.
+
+Django provides a few classes that help you manage paginated data -- that is,
+data that's split across several pages, with "Previous/Next" links. These
+classes live in :file:`django/core/paginator.py`.
+
+Example
+=======
+
+Give :class:`Paginator` a list of objects, plus the number of items you'd like to
+have on each page, and it gives you methods for accessing the items for each
+page::
+
+ >>> from django.core.paginator import Paginator
+ >>> objects = ['john', 'paul', 'george', 'ringo']
+ >>> p = Paginator(objects, 2)
+
+ >>> p.count
+ 4
+ >>> p.num_pages
+ 2
+ >>> p.page_range
+ [1, 2]
+
+ >>> page1 = p.page(1)
+ >>> page1
+ <Page 1 of 2>
+ >>> page1.object_list
+ ['john', 'paul']
+
+ >>> page2 = p.page(2)
+ >>> page2.object_list
+ ['george', 'ringo']
+ >>> page2.has_next()
+ False
+ >>> page2.has_previous()
+ True
+ >>> page2.has_other_pages()
+ True
+ >>> page2.next_page_number()
+ 3
+ >>> page2.previous_page_number()
+ 1
+ >>> page2.start_index() # The 1-based index of the first item on this page
+ 3
+ >>> page2.end_index() # The 1-based index of the last item on this page
+ 4
+
+ >>> p.page(0)
+ Traceback (most recent call last):
+ ...
+ EmptyPage: That page number is less than 1
+ >>> p.page(3)
+ Traceback (most recent call last):
+ ...
+ EmptyPage: That page contains no results
+
+.. note::
+
+ Note that you can give ``Paginator`` a list/tuple, a Django ``QuerySet``, or
+ any other object with a ``count()`` or ``__len__()`` method. When
+ determining the number of objects contained in the passed object,
+ ``Paginator`` will first try calling ``count()``, then fallback to using
+ ``len()`` if the passed object has no ``count()`` method. This allows
+ objects such as Django's ``QuerySet`` to use a more efficient ``count()``
+ method when available.
+
+
+Using ``Paginator`` in a view
+==============================
+
+Here's a slightly more complex example using :class:`Paginator` in a view to
+paginate a queryset. We give both the view and the accompanying template to
+show how you can display the results. This example assumes you have a
+``Contacts`` model that has already been imported.
+
+The view function looks like this::
+
+ from django.core.paginator import Paginator, InvalidPage, EmptyPage
+
+ def listing(request):
+ contact_list = Contacts.objects.all()
+ paginator = Paginator(contact_list, 25) # Show 25 contacts per page
+
+ # Make sure page request is an int. If not, deliver first page.
+ try:
+ page = int(request.GET.get('page', '1'))
+ except ValueError:
+ page = 1
+
+ # If page request (9999) is out of range, deliver last page of results.
+ try:
+ contacts = paginator.page(page)
+ except (EmptyPage, InvalidPage):
+ contacts = paginator.page(paginator.num_pages)
+
+ return render_to_response('list.html', {"contacts": contacts})
+
+In the template :file:`list.html`, you'll want to include navigation between
+pages along with any interesting information from the objects themselves::
+
+ {% for contact in contacts.object_list %}
+ {# Each "contact" is a Contact model object. #}
+ {{ contact.full_name|upper }}<br />
+ ...
+ {% endfor %}
+
+ <div class="pagination">
+ <span class="step-links">
+ {% if contacts.has_previous %}
+ <a href="?page={{ contacts.previous_page_number }}">previous</a>
+ {% endif %}
+
+ <span class="current">
+ Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.
+ </span>
+
+ {% if contacts.has_next %}
+ <a href="?page={{ contacts.next_page_number }}">next</a>
+ {% endif %}
+ </span>
+ </div>
+
+
+``Paginator`` objects
+=====================
+
+The :class:`Paginator` class has this constructor:
+
+.. class:: Paginator(object_list, per_page, orphans=0, allow_empty_first_page=True)
+
+Required arguments
+------------------
+
+``object_list``
+ A list, tuple, Django ``QuerySet``, or other sliceable object with a
+ ``count()`` or ``__len__()`` method.
+
+``per_page``
+ The maximum number of items to include on a page, not including orphans
+ (see the ``orphans`` optional argument below).
+
+Optional arguments
+------------------
+
+``orphans``
+ The minimum number of items allowed on the last page, defaults to zero.
+ Use this when you don't want to have a last page with very few items.
+ If the last page would normally have a number of items less than or equal
+ to ``orphans``, then those items will be added to the previous page (which
+ becomes the last page) instead of leaving the items on a page by
+ themselves. For example, with 23 items, ``per_page=10``, and
+ ``orphans=3``, there will be two pages; the first page with 10 items and
+ the second (and last) page with 13 items.
+
+``allow_empty_first_page``
+ Whether or not the first page is allowed to be empty. If ``False`` and
+ ``object_list`` is empty, then an ``EmptyPage`` error will be raised.
+
+Methods
+-------
+
+.. method:: Paginator.page(number)
+
+ Returns a :class:`Page` object with the given 1-based index. Raises
+ :exc:`InvalidPage` if the given page number doesn't exist.
+
+Attributes
+----------
+
+.. attribute:: Paginator.count
+
+ The total number of objects, across all pages.
+
+ .. note::
+
+ When determining the number of objects contained in ``object_list``,
+ ``Paginator`` will first try calling ``object_list.count()``. If
+ ``object_list`` has no ``count()`` method, then ``Paginator`` will
+ fallback to using ``object_list.__len__()``. This allows objects, such
+ as Django's ``QuerySet``, to use a more efficient ``count()`` method
+ when available.
+
+.. attribute:: Paginator.num_pages
+
+ The total number of pages.
+
+.. attribute:: Paginator.page_range
+
+ A 1-based range of page numbers, e.g., ``[1, 2, 3, 4]``.
+
+``InvalidPage`` exceptions
+==========================
+
+The ``page()`` method raises ``InvalidPage`` if the requested page is invalid
+(i.e., not an integer) or contains no objects. Generally, it's enough to trap
+the ``InvalidPage`` exception, but if you'd like more granularity, you can trap
+either of the following exceptions:
+
+``PageNotAnInteger``
+ Raised when ``page()`` is given a value that isn't an integer.
+
+``EmptyPage``
+ Raised when ``page()`` is given a valid value but no objects exist on that
+ page.
+
+Both of the exceptions are subclasses of ``InvalidPage``, so you can handle
+them both with a simple ``except InvalidPage``.
+
+
+``Page`` objects
+================
+
+.. class:: Page(object_list, number, paginator)
+
+You usually won't construct :class:`Pages <Page>` by hand -- you'll get them
+using :meth:`Paginator.page`.
+
+
+Methods
+-------
+
+.. method:: Page.has_next()
+
+ Returns ``True`` if there's a next page.
+
+.. method:: Page.has_previous()
+
+ Returns ``True`` if there's a previous page.
+
+.. method:: Page.has_other_pages()
+
+ Returns ``True`` if there's a next *or* previous page.
+
+.. method:: Page.next_page_number()
+
+ Returns the next page number. Note that this is "dumb" and will return the
+ next page number regardless of whether a subsequent page exists.
+
+.. method:: Page.previous_page_number()
+
+ Returns the previous page number. Note that this is "dumb" and will return
+ the previous page number regardless of whether a previous page exists.
+
+.. method:: Page.start_index()
+
+ Returns the 1-based index of the first object on the page, relative to all
+ of the objects in the paginator's list. For example, when paginating a list
+ of 5 objects with 2 objects per page, the second page's :meth:`~Page.start_index`
+ would return ``3``.
+
+.. method:: Page.end_index()
+
+ Returns the 1-based index of the last object on the page, relative to all of
+ the objects in the paginator's list. For example, when paginating a list of
+ 5 objects with 2 objects per page, the second page's :meth:`~Page.end_index`
+ would return ``4``.
+
+Attributes
+----------
+
+.. attribute:: Page.object_list
+
+ The list of objects on this page.
+
+.. attribute:: Page.number
+
+ The 1-based page number for this page.
+
+.. attribute:: Page.paginator
+
+ The associated :class:`Paginator` object.
+
diff --git a/parts/django/docs/topics/serialization.txt b/parts/django/docs/topics/serialization.txt
new file mode 100644
index 0000000..c8acc85
--- /dev/null
+++ b/parts/django/docs/topics/serialization.txt
@@ -0,0 +1,402 @@
+==========================
+Serializing Django objects
+==========================
+
+Django's serialization framework provides a mechanism for "translating" Django
+objects into other formats. Usually these other formats will be text-based and
+used for sending Django objects over a wire, but it's possible for a
+serializer to handle any format (text-based or not).
+
+.. seealso::
+
+ If you just want to get some data from your tables into a serialized
+ form, you could use the :djadmin:`dumpdata` management command.
+
+Serializing data
+----------------
+
+At the highest level, serializing data is a very simple operation::
+
+ from django.core import serializers
+ data = serializers.serialize("xml", SomeModel.objects.all())
+
+The arguments to the ``serialize`` function are the format to serialize the data
+to (see `Serialization formats`_) and a :class:`~django.db.models.QuerySet` to
+serialize. (Actually, the second argument can be any iterator that yields Django
+objects, but it'll almost always be a QuerySet).
+
+You can also use a serializer object directly::
+
+ XMLSerializer = serializers.get_serializer("xml")
+ xml_serializer = XMLSerializer()
+ xml_serializer.serialize(queryset)
+ data = xml_serializer.getvalue()
+
+This is useful if you want to serialize data directly to a file-like object
+(which includes an :class:`~django.http.HttpResponse`)::
+
+ out = open("file.xml", "w")
+ xml_serializer.serialize(SomeModel.objects.all(), stream=out)
+
+Subset of fields
+~~~~~~~~~~~~~~~~
+
+If you only want a subset of fields to be serialized, you can
+specify a ``fields`` argument to the serializer::
+
+ from django.core import serializers
+ data = serializers.serialize('xml', SomeModel.objects.all(), fields=('name','size'))
+
+In this example, only the ``name`` and ``size`` attributes of each model will
+be serialized.
+
+.. note::
+
+ Depending on your model, you may find that it is not possible to
+ deserialize a model that only serializes a subset of its fields. If a
+ serialized object doesn't specify all the fields that are required by a
+ model, the deserializer will not be able to save deserialized instances.
+
+Inherited Models
+~~~~~~~~~~~~~~~~
+
+If you have a model that is defined using an :ref:`abstract base class
+<abstract-base-classes>`, you don't have to do anything special to serialize
+that model. Just call the serializer on the object (or objects) that you want to
+serialize, and the output will be a complete representation of the serialized
+object.
+
+However, if you have a model that uses :ref:`multi-table inheritance
+<multi-table-inheritance>`, you also need to serialize all of the base classes
+for the model. This is because only the fields that are locally defined on the
+model will be serialized. For example, consider the following models::
+
+ class Place(models.Model):
+ name = models.CharField(max_length=50)
+
+ class Restaurant(Place):
+ serves_hot_dogs = models.BooleanField()
+
+If you only serialize the Restaurant model::
+
+ data = serializers.serialize('xml', Restaurant.objects.all())
+
+the fields on the serialized output will only contain the `serves_hot_dogs`
+attribute. The `name` attribute of the base class will be ignored.
+
+In order to fully serialize your Restaurant instances, you will need to
+serialize the Place models as well::
+
+ all_objects = list(Restaurant.objects.all()) + list(Place.objects.all())
+ data = serializers.serialize('xml', all_objects)
+
+Deserializing data
+------------------
+
+Deserializing data is also a fairly simple operation::
+
+ for obj in serializers.deserialize("xml", data):
+ do_something_with(obj)
+
+As you can see, the ``deserialize`` function takes the same format argument as
+``serialize``, a string or stream of data, and returns an iterator.
+
+However, here it gets slightly complicated. The objects returned by the
+``deserialize`` iterator *aren't* simple Django objects. Instead, they are
+special ``DeserializedObject`` instances that wrap a created -- but unsaved --
+object and any associated relationship data.
+
+Calling ``DeserializedObject.save()`` saves the object to the database.
+
+This ensures that deserializing is a non-destructive operation even if the
+data in your serialized representation doesn't match what's currently in the
+database. Usually, working with these ``DeserializedObject`` instances looks
+something like::
+
+ for deserialized_object in serializers.deserialize("xml", data):
+ if object_should_be_saved(deserialized_object):
+ deserialized_object.save()
+
+In other words, the usual use is to examine the deserialized objects to make
+sure that they are "appropriate" for saving before doing so. Of course, if you
+trust your data source you could just save the object and move on.
+
+The Django object itself can be inspected as ``deserialized_object.object``.
+
+.. _serialization-formats:
+
+Serialization formats
+---------------------
+
+Django supports a number of serialization formats, some of which require you
+to install third-party Python modules:
+
+ ========== ==============================================================
+ Identifier Information
+ ========== ==============================================================
+ ``xml`` Serializes to and from a simple XML dialect.
+
+ ``json`` Serializes to and from JSON_ (using a version of simplejson_
+ bundled with Django).
+
+ ``yaml`` Serializes to YAML (YAML Ain't a Markup Language). This
+ serializer is only available if PyYAML_ is installed.
+ ========== ==============================================================
+
+.. _json: http://json.org/
+.. _simplejson: http://undefined.org/python/#simplejson
+.. _PyYAML: http://www.pyyaml.org/
+
+Notes for specific serialization formats
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+json
+^^^^
+
+If you're using UTF-8 (or any other non-ASCII encoding) data with the JSON
+serializer, you must pass ``ensure_ascii=False`` as a parameter to the
+``serialize()`` call. Otherwise, the output won't be encoded correctly.
+
+For example::
+
+ json_serializer = serializers.get_serializer("json")()
+ json_serializer.serialize(queryset, ensure_ascii=False, stream=response)
+
+The Django source code includes the simplejson_ module. However, if you're
+using Python 2.6 or later (which includes a builtin version of the module), Django will
+use the builtin ``json`` module automatically. If you have a system installed
+version that includes the C-based speedup extension, or your system version is
+more recent than the version shipped with Django (currently, 2.0.7), the
+system version will be used instead of the version included with Django.
+
+Be aware that if you're serializing using that module directly, not all Django
+output can be passed unmodified to simplejson. In particular, :ref:`lazy
+translation objects <lazy-translations>` need a `special encoder`_ written for
+them. Something like this will work::
+
+ from django.utils.functional import Promise
+ from django.utils.encoding import force_unicode
+
+ class LazyEncoder(simplejson.JSONEncoder):
+ def default(self, obj):
+ if isinstance(obj, Promise):
+ return force_unicode(obj)
+ return super(LazyEncoder, self).default(obj)
+
+.. _special encoder: http://svn.red-bean.com/bob/simplejson/tags/simplejson-1.7/docs/index.html
+
+.. _topics-serialization-natural-keys:
+
+Natural keys
+------------
+
+.. versionadded:: 1.2
+
+ The ability to use natural keys when serializing/deserializing data was
+ added in the 1.2 release.
+
+The default serialization strategy for foreign keys and many-to-many
+relations is to serialize the value of the primary key(s) of the
+objects in the relation. This strategy works well for most types of
+object, but it can cause difficulty in some circumstances.
+
+Consider the case of a list of objects that have foreign key on
+:class:`ContentType`. If you're going to serialize an object that
+refers to a content type, you need to have a way to refer to that
+content type. Content Types are automatically created by Django as
+part of the database synchronization process, so you don't need to
+include content types in a fixture or other serialized data. As a
+result, the primary key of any given content type isn't easy to
+predict - it will depend on how and when :djadmin:`syncdb` was
+executed to create the content types.
+
+There is also the matter of convenience. An integer id isn't always
+the most convenient way to refer to an object; sometimes, a
+more natural reference would be helpful.
+
+It is for these reasons that Django provides *natural keys*. A natural
+key is a tuple of values that can be used to uniquely identify an
+object instance without using the primary key value.
+
+Deserialization of natural keys
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Consider the following two models::
+
+ from django.db import models
+
+ class Person(models.Model):
+ first_name = models.CharField(max_length=100)
+ last_name = models.CharField(max_length=100)
+
+ birthdate = models.DateField()
+
+ class Meta:
+ unique_together = (('first_name', 'last_name'),)
+
+ class Book(models.Model):
+ name = models.CharField(max_length=100)
+ author = models.ForeignKey(Person)
+
+Ordinarily, serialized data for ``Book`` would use an integer to refer to
+the author. For example, in JSON, a Book might be serialized as::
+
+ ...
+ {
+ "pk": 1,
+ "model": "store.book",
+ "fields": {
+ "name": "Mostly Harmless",
+ "author": 42
+ }
+ }
+ ...
+
+This isn't a particularly natural way to refer to an author. It
+requires that you know the primary key value for the author; it also
+requires that this primary key value is stable and predictable.
+
+However, if we add natural key handling to Person, the fixture becomes
+much more humane. To add natural key handling, you define a default
+Manager for Person with a ``get_by_natural_key()`` method. In the case
+of a Person, a good natural key might be the pair of first and last
+name::
+
+ from django.db import models
+
+ class PersonManager(models.Manager):
+ def get_by_natural_key(self, first_name, last_name):
+ return self.get(first_name=first_name, last_name=last_name)
+
+ class Person(models.Model):
+ objects = PersonManager()
+
+ first_name = models.CharField(max_length=100)
+ last_name = models.CharField(max_length=100)
+
+ birthdate = models.DateField()
+
+ class Meta:
+ unique_together = (('first_name', 'last_name'),)
+
+Now books can use that natural key to refer to ``Person`` objects::
+
+ ...
+ {
+ "pk": 1,
+ "model": "store.book",
+ "fields": {
+ "name": "Mostly Harmless",
+ "author": ["Douglas", "Adams"]
+ }
+ }
+ ...
+
+When you try to load this serialized data, Django will use the
+``get_by_natural_key()`` method to resolve ``["Douglas", "Adams"]``
+into the primary key of an actual ``Person`` object.
+
+.. note::
+
+ Whatever fields you use for a natural key must be able to uniquely
+ identify an object. This will usually mean that your model will
+ have a uniqueness clause (either unique=True on a single field, or
+ ``unique_together`` over multiple fields) for the field or fields
+ in your natural key. However, uniqueness doesn't need to be
+ enforced at the database level. If you are certain that a set of
+ fields will be effectively unique, you can still use those fields
+ as a natural key.
+
+Serialization of natural keys
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+So how do you get Django to emit a natural key when serializing an object?
+Firstly, you need to add another method -- this time to the model itself::
+
+ class Person(models.Model):
+ objects = PersonManager()
+
+ first_name = models.CharField(max_length=100)
+ last_name = models.CharField(max_length=100)
+
+ birthdate = models.DateField()
+
+ def natural_key(self):
+ return (self.first_name, self.last_name)
+
+ class Meta:
+ unique_together = (('first_name', 'last_name'),)
+
+That method should always return a natural key tuple -- in this
+example, ``(first name, last name)``. Then, when you call
+``serializers.serialize()``, you provide a ``use_natural_keys=True``
+argument::
+
+ >>> serializers.serialize('json', [book1, book2], indent=2, use_natural_keys=True)
+
+When ``use_natural_keys=True`` is specified, Django will use the
+``natural_key()`` method to serialize any reference to objects of the
+type that defines the method.
+
+If you are using :djadmin:`dumpdata` to generate serialized data, you
+use the `--natural` command line flag to generate natural keys.
+
+.. note::
+
+ You don't need to define both ``natural_key()`` and
+ ``get_by_natural_key()``. If you don't want Django to output
+ natural keys during serialization, but you want to retain the
+ ability to load natural keys, then you can opt to not implement
+ the ``natural_key()`` method.
+
+ Conversely, if (for some strange reason) you want Django to output
+ natural keys during serialization, but *not* be able to load those
+ key values, just don't define the ``get_by_natural_key()`` method.
+
+Dependencies during serialization
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Since natural keys rely on database lookups to resolve references, it
+is important that data exists before it is referenced. You can't make
+a `forward reference` with natural keys - the data you are referencing
+must exist before you include a natural key reference to that data.
+
+To accommodate this limitation, calls to :djadmin:`dumpdata` that use
+the :djadminopt:`--natural` option will serialize any model with a
+``natural_key()`` method before it serializes normal key objects.
+
+However, this may not always be enough. If your natural key refers to
+another object (by using a foreign key or natural key to another object
+as part of a natural key), then you need to be able to ensure that
+the objects on which a natural key depends occur in the serialized data
+before the natural key requires them.
+
+To control this ordering, you can define dependencies on your
+``natural_key()`` methods. You do this by setting a ``dependencies``
+attribute on the ``natural_key()`` method itself.
+
+For example, consider the ``Permission`` model in ``contrib.auth``.
+The following is a simplified version of the ``Permission`` model::
+
+ class Permission(models.Model):
+ name = models.CharField(max_length=50)
+ content_type = models.ForeignKey(ContentType)
+ codename = models.CharField(max_length=100)
+ # ...
+ def natural_key(self):
+ return (self.codename,) + self.content_type.natural_key()
+
+The natural key for a ``Permission`` is a combination of the codename for the
+``Permission``, and the ``ContentType`` to which the ``Permission`` applies. This means
+that ``ContentType`` must be serialized before ``Permission``. To define this
+dependency, we add one extra line::
+
+ class Permission(models.Model):
+ # ...
+ def natural_key(self):
+ return (self.codename,) + self.content_type.natural_key()
+ natural_key.dependencies = ['contenttypes.contenttype']
+
+This definition ensures that ``ContentType`` models are serialized before
+``Permission`` models. In turn, any object referencing ``Permission`` will
+be serialized after both ``ContentType`` and ``Permission``.
diff --git a/parts/django/docs/topics/settings.txt b/parts/django/docs/topics/settings.txt
new file mode 100644
index 0000000..59c02c3
--- /dev/null
+++ b/parts/django/docs/topics/settings.txt
@@ -0,0 +1,255 @@
+===============
+Django settings
+===============
+
+A Django settings file contains all the configuration of your Django
+installation. This document explains how settings work and which settings are
+available.
+
+The basics
+==========
+
+A settings file is just a Python module with module-level variables.
+
+Here are a couple of example settings::
+
+ DEBUG = False
+ DEFAULT_FROM_EMAIL = 'webmaster@example.com'
+ TEMPLATE_DIRS = ('/home/templates/mike', '/home/templates/john')
+
+Because a settings file is a Python module, the following apply:
+
+ * It doesn't allow for Python syntax errors.
+ * It can assign settings dynamically using normal Python syntax.
+ For example::
+
+ MY_SETTING = [str(i) for i in range(30)]
+
+ * It can import values from other settings files.
+
+.. _django-settings-module:
+
+Designating the settings
+========================
+
+When you use Django, you have to tell it which settings you're using. Do this
+by using an environment variable, ``DJANGO_SETTINGS_MODULE``.
+
+The value of ``DJANGO_SETTINGS_MODULE`` should be in Python path syntax, e.g.
+``mysite.settings``. Note that the settings module should be on the
+Python `import search path`_.
+
+.. _import search path: http://diveintopython.org/getting_to_know_python/everything_is_an_object.html
+
+The django-admin.py utility
+---------------------------
+
+When using :doc:`django-admin.py </ref/django-admin>`, you can either set the
+environment variable once, or explicitly pass in the settings module each time
+you run the utility.
+
+Example (Unix Bash shell)::
+
+ export DJANGO_SETTINGS_MODULE=mysite.settings
+ django-admin.py runserver
+
+Example (Windows shell)::
+
+ set DJANGO_SETTINGS_MODULE=mysite.settings
+ django-admin.py runserver
+
+Use the ``--settings`` command-line argument to specify the settings manually::
+
+ django-admin.py runserver --settings=mysite.settings
+
+.. _django-admin.py: ../django-admin/
+
+On the server (mod_python)
+--------------------------
+
+In your live server environment, you'll need to tell Apache/mod_python which
+settings file to use. Do that with ``SetEnv``::
+
+ <Location "/mysite/">
+ SetHandler python-program
+ PythonHandler django.core.handlers.modpython
+ SetEnv DJANGO_SETTINGS_MODULE mysite.settings
+ </Location>
+
+Read the :doc:`Django mod_python documentation </howto/deployment/modpython>` for
+more information.
+
+Default settings
+================
+
+A Django settings file doesn't have to define any settings if it doesn't need
+to. Each setting has a sensible default value. These defaults live in the
+module :file:`django/conf/global_settings.py`.
+
+Here's the algorithm Django uses in compiling settings:
+
+ * Load settings from ``global_settings.py``.
+ * Load settings from the specified settings file, overriding the global
+ settings as necessary.
+
+Note that a settings file should *not* import from ``global_settings``, because
+that's redundant.
+
+Seeing which settings you've changed
+------------------------------------
+
+There's an easy way to view which of your settings deviate from the default
+settings. The command ``python manage.py diffsettings`` displays differences
+between the current settings file and Django's default settings.
+
+For more, see the :djadmin:`diffsettings` documentation.
+
+Using settings in Python code
+=============================
+
+In your Django apps, use settings by importing the object
+``django.conf.settings``. Example::
+
+ from django.conf import settings
+
+ if settings.DEBUG:
+ # Do something
+
+Note that ``django.conf.settings`` isn't a module -- it's an object. So
+importing individual settings is not possible::
+
+ from django.conf.settings import DEBUG # This won't work.
+
+Also note that your code should *not* import from either ``global_settings`` or
+your own settings file. ``django.conf.settings`` abstracts the concepts of
+default settings and site-specific settings; it presents a single interface.
+It also decouples the code that uses settings from the location of your
+settings.
+
+Altering settings at runtime
+============================
+
+You shouldn't alter settings in your applications at runtime. For example,
+don't do this in a view::
+
+ from django.conf import settings
+
+ settings.DEBUG = True # Don't do this!
+
+The only place you should assign to settings is in a settings file.
+
+Security
+========
+
+Because a settings file contains sensitive information, such as the database
+password, you should make every attempt to limit access to it. For example,
+change its file permissions so that only you and your Web server's user can
+read it. This is especially important in a shared-hosting environment.
+
+Available settings
+==================
+
+For a full list of available settings, see the :doc:`settings reference </ref/settings>`.
+
+Creating your own settings
+==========================
+
+There's nothing stopping you from creating your own settings, for your own
+Django apps. Just follow these conventions:
+
+ * Setting names are in all uppercase.
+ * Don't reinvent an already-existing setting.
+
+For settings that are sequences, Django itself uses tuples, rather than lists,
+but this is only a convention.
+
+.. _settings-without-django-settings-module:
+
+Using settings without setting DJANGO_SETTINGS_MODULE
+=====================================================
+
+In some cases, you might want to bypass the ``DJANGO_SETTINGS_MODULE``
+environment variable. For example, if you're using the template system by
+itself, you likely don't want to have to set up an environment variable
+pointing to a settings module.
+
+In these cases, you can configure Django's settings manually. Do this by
+calling:
+
+.. function:: django.conf.settings.configure(default_settings, **settings)
+
+Example::
+
+ from django.conf import settings
+
+ settings.configure(DEBUG=True, TEMPLATE_DEBUG=True,
+ TEMPLATE_DIRS=('/home/web-apps/myapp', '/home/web-apps/base'))
+
+Pass ``configure()`` as many keyword arguments as you'd like, with each keyword
+argument representing a setting and its value. Each argument name should be all
+uppercase, with the same name as the settings described above. If a particular
+setting is not passed to ``configure()`` and is needed at some later point,
+Django will use the default setting value.
+
+Configuring Django in this fashion is mostly necessary -- and, indeed,
+recommended -- when you're using a piece of the framework inside a larger
+application.
+
+Consequently, when configured via ``settings.configure()``, Django will not
+make any modifications to the process environment variables (see the
+documentation of :setting:`TIME_ZONE` for why this would normally occur). It's
+assumed that you're already in full control of your environment in these
+cases.
+
+Custom default settings
+-----------------------
+
+If you'd like default values to come from somewhere other than
+``django.conf.global_settings``, you can pass in a module or class that
+provides the default settings as the ``default_settings`` argument (or as the
+first positional argument) in the call to ``configure()``.
+
+In this example, default settings are taken from ``myapp_defaults``, and the
+``DEBUG`` setting is set to ``True``, regardless of its value in
+``myapp_defaults``::
+
+ from django.conf import settings
+ from myapp import myapp_defaults
+
+ settings.configure(default_settings=myapp_defaults, DEBUG=True)
+
+The following example, which uses ``myapp_defaults`` as a positional argument,
+is equivalent::
+
+ settings.configure(myapp_defaults, DEBUG = True)
+
+Normally, you will not need to override the defaults in this fashion. The
+Django defaults are sufficiently tame that you can safely use them. Be aware
+that if you do pass in a new default module, it entirely *replaces* the Django
+defaults, so you must specify a value for every possible setting that might be
+used in that code you are importing. Check in
+``django.conf.settings.global_settings`` for the full list.
+
+Either configure() or DJANGO_SETTINGS_MODULE is required
+--------------------------------------------------------
+
+If you're not setting the ``DJANGO_SETTINGS_MODULE`` environment variable, you
+*must* call ``configure()`` at some point before using any code that reads
+settings.
+
+If you don't set ``DJANGO_SETTINGS_MODULE`` and don't call ``configure()``,
+Django will raise an ``ImportError`` exception the first time a setting
+is accessed.
+
+If you set ``DJANGO_SETTINGS_MODULE``, access settings values somehow, *then*
+call ``configure()``, Django will raise a ``RuntimeError`` indicating
+that settings have already been configured.
+
+Also, it's an error to call ``configure()`` more than once, or to call
+``configure()`` after any setting has been accessed.
+
+It boils down to this: Use exactly one of either ``configure()`` or
+``DJANGO_SETTINGS_MODULE``. Not both, and not neither.
+
+.. _@login_required: ../authentication/#the-login-required-decorator
+
diff --git a/parts/django/docs/topics/signals.txt b/parts/django/docs/topics/signals.txt
new file mode 100644
index 0000000..35e111d
--- /dev/null
+++ b/parts/django/docs/topics/signals.txt
@@ -0,0 +1,255 @@
+=======
+Signals
+=======
+
+.. module:: django.dispatch
+ :synopsis: Signal dispatch
+
+Django includes a "signal dispatcher" which helps allow decoupled applications
+get notified when actions occur elsewhere in the framework. In a nutshell,
+signals allow certain *senders* to notify a set of *receivers* that some action
+has taken place. They're especially useful when many pieces of code may be
+interested in the same events.
+
+Django provides a :doc:`set of built-in signals </ref/signals>` that let user
+code get notified by Django itself of certain actions. These include some useful
+notifications:
+
+ * :data:`django.db.models.signals.pre_save` &
+ :data:`django.db.models.signals.post_save`
+
+ Sent before or after a model's :meth:`~django.db.models.Model.save` method
+ is called.
+
+ * :data:`django.db.models.signals.pre_delete` &
+ :data:`django.db.models.signals.post_delete`
+
+ Sent before or after a model's :meth:`~django.db.models.Model.delete`
+ method is called.
+
+ * :data:`django.db.models.signals.m2m_changed`
+
+ Sent when a :class:`ManyToManyField` on a model is changed.
+
+ * :data:`django.core.signals.request_started` &
+ :data:`django.core.signals.request_finished`
+
+ Sent when Django starts or finishes an HTTP request.
+
+See the :doc:`built-in signal documentation </ref/signals>` for a complete list,
+and a complete explanation of each signal.
+
+You can also `define and send your own custom signals`_; see below.
+
+.. _define and send your own custom signals: `defining and sending signals`_
+
+Listening to signals
+====================
+
+To receive a signal, you need to register a *receiver* function that gets
+called when the signal is sent by using the
+:meth:`.Signal.connect` method:
+
+.. method:: Signal.connect(receiver, [sender=None, weak=True, dispatch_uid=None])
+
+ :param receiver: The callback function which will be connected to this
+ signal. See :ref:`receiver-functions` for more information.
+
+ :param sender: Specifies a particular sender to receive signals from. See
+ :ref:`connecting-to-specific-signals` for more information.
+
+ :param weak: Django stores signal handlers as weak references by
+ default. Thus, if your receiver is a local function, it may be
+ garbage collected. To prevent this, pass ``weak=False`` when you call
+ the signal's ``connect()`` method.
+
+ :param dispatch_uid: A unique identifier for a signal receiver in cases
+ where duplicate signals may be sent. See
+ :ref:`preventing-duplicate-signals` for more information.
+
+Let's see how this works by registering a signal that
+gets called after each HTTP request is finished. We'll be connecting to the
+:data:`~django.core.signals.request_finished` signal.
+
+.. _receiver-functions:
+
+Receiver functions
+------------------
+
+First, we need to define a receiver function. A receiver can be any Python
+function or method:
+
+.. code-block:: python
+
+ def my_callback(sender, **kwargs):
+ print "Request finished!"
+
+Notice that the function takes a ``sender`` argument, along with wildcard
+keyword arguments (``**kwargs``); all signal handlers must take these arguments.
+
+We'll look at senders `a bit later`_, but right now look at the ``**kwargs``
+argument. All signals send keyword arguments, and may change those keyword
+arguments at any time. In the case of
+:data:`~django.core.signals.request_finished`, it's documented as sending no
+arguments, which means we might be tempted to write our signal handling as
+``my_callback(sender)``.
+
+.. _a bit later: `connecting to signals sent by specific senders`_
+
+This would be wrong -- in fact, Django will throw an error if you do so. That's
+because at any point arguments could get added to the signal and your receiver
+must be able to handle those new arguments.
+
+.. _connecting-receiver-functions:
+
+Connecting receiver functions
+-----------------------------
+
+Next, we'll need to connect our receiver to the signal:
+
+.. code-block:: python
+
+ from django.core.signals import request_finished
+
+ request_finished.connect(my_callback)
+
+Now, our ``my_callback`` function will be called each time a request finishes.
+
+.. admonition:: Where should this code live?
+
+ You can put signal handling and registration code anywhere you like.
+ However, you'll need to make sure that the module it's in gets imported
+ early on so that the signal handling gets registered before any signals need
+ to be sent. This makes your app's ``models.py`` a good place to put
+ registration of signal handlers.
+
+.. _connecting-to-specific-signals:
+
+Connecting to signals sent by specific senders
+----------------------------------------------
+
+Some signals get sent many times, but you'll only be interested in receiving a
+certain subset of those signals. For example, consider the
+:data:`django.db.models.signals.pre_save` signal sent before a model gets saved.
+Most of the time, you don't need to know when *any* model gets saved -- just
+when one *specific* model is saved.
+
+In these cases, you can register to receive signals sent only by particular
+senders. In the case of :data:`django.db.models.signals.pre_save`, the sender
+will be the model class being saved, so you can indicate that you only want
+signals sent by some model:
+
+.. code-block:: python
+
+ from django.db.models.signals import pre_save
+ from myapp.models import MyModel
+
+ def my_handler(sender, **kwargs):
+ ...
+
+ pre_save.connect(my_handler, sender=MyModel)
+
+The ``my_handler`` function will only be called when an instance of ``MyModel``
+is saved.
+
+Different signals use different objects as their senders; you'll need to consult
+the :doc:`built-in signal documentation </ref/signals>` for details of each
+particular signal.
+
+.. _preventing-duplicate-signals:
+
+Preventing duplicate signals
+----------------------------
+
+In some circumstances, the module in which you are connecting signals may be
+imported multiple times. This can cause your receiver function to be
+registered more than once, and thus called multiples times for a single signal
+event.
+
+If this behavior is problematic (such as when using signals to
+send an e-mail whenever a model is saved), pass a unique identifier as
+the ``dispatch_uid`` argument to identify your receiver function. This
+identifier will usually be a string, although any hashable object will
+suffice. The end result is that your receiver function will only be
+bound to the signal once for each unique ``dispatch_uid`` value.
+
+.. code-block:: python
+
+ from django.core.signals import request_finished
+
+ request_finished.connect(my_callback, dispatch_uid="my_unique_identifier")
+
+Defining and sending signals
+============================
+
+Your applications can take advantage of the signal infrastructure and provide
+its own signals.
+
+Defining signals
+----------------
+
+.. class:: Signal([providing_args=list])
+
+All signals are :class:`django.dispatch.Signal` instances. The
+``providing_args`` is a list of the names of arguments the signal will provide
+to listeners.
+
+For example:
+
+.. code-block:: python
+
+ import django.dispatch
+
+ pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])
+
+This declares a ``pizza_done`` signal that will provide receivers with
+``toppings`` and ``size`` arguments.
+
+Remember that you're allowed to change this list of arguments at any time, so getting the API right on the first try isn't necessary.
+
+Sending signals
+---------------
+
+There are two ways to send send signals in Django.
+
+.. method:: Signal.send(sender, **kwargs)
+.. method:: Signal.send_robust(sender, **kwargs)
+
+To send a signal, call either :meth:`Signal.send` or :meth:`Signal.send_robust`.
+You must provide the ``sender`` argument, and may provide as many other keyword
+arguments as you like.
+
+For example, here's how sending our ``pizza_done`` signal might look:
+
+.. code-block:: python
+
+ class PizzaStore(object):
+ ...
+
+ def send_pizza(self, toppings, size):
+ pizza_done.send(sender=self, toppings=toppings, size=size)
+ ...
+
+Both ``send()`` and ``send_robust()`` return a list of tuple pairs
+``[(receiver, response), ... ]``, representing the list of called receiver
+functions and their response values.
+
+``send()`` differs from ``send_robust()`` in how exceptions raised by receiver
+functions are handled. ``send()`` does *not* catch any exceptions raised by
+receivers; it simply allows errors to propagate. Thus not all receivers may
+be notified of a signal in the face of an error.
+
+``send_robust()`` catches all errors derived from Python's ``Exception`` class,
+and ensures all receivers are notified of the signal. If an error occurs, the
+error instance is returned in the tuple pair for the receiver that raised the error.
+
+Disconnecting signals
+=====================
+
+.. method:: Signal.disconnect([receiver=None, sender=None, weak=True, dispatch_uid=None])
+
+To disconnect a receiver from a signal, call :meth:`Signal.disconnect`. The
+arguments are as described in :meth:`.Signal.connect`.
+
+The *receiver* argument indicates the registered receiver to disconnect. It may
+be ``None`` if ``dispatch_uid`` is used to identify the receiver.
diff --git a/parts/django/docs/topics/templates.txt b/parts/django/docs/topics/templates.txt
new file mode 100644
index 0000000..d249bd3
--- /dev/null
+++ b/parts/django/docs/topics/templates.txt
@@ -0,0 +1,617 @@
+============================
+The Django template language
+============================
+
+.. admonition:: About this document
+
+ This document explains the language syntax of the Django template system. If
+ you're looking for a more technical perspective on how it works and how to
+ extend it, see :doc:`/ref/templates/api`.
+
+Django's template language is designed to strike a balance between power and
+ease. It's designed to feel comfortable to those used to working with HTML. If
+you have any exposure to other text-based template languages, such as Smarty_
+or CheetahTemplate_, you should feel right at home with Django's templates.
+
+.. admonition:: Philosophy
+
+ If you have a background in programming, or if you're used to languages
+ like PHP which mix programming code directly into HTML, you'll want to
+ bear in mind that the Django template system is not simply Python embedded
+ into HTML. This is by design: the template system is meant to express
+ presentation, not program logic.
+
+ The Django template system provides tags which function similarly to some
+ programming constructs -- an :ttag:`if` tag for boolean tests, a :ttag:`for`
+ tag for looping, etc. -- but these are not simply executed as the
+ corresponding Python code, and the template system will not execute
+ arbitrary Python expressions. Only the tags, filters and syntax listed below
+ are supported by default (although you can add :doc:`your own extensions
+ </howto/custom-template-tags>` to the template language as needed).
+
+.. _`The Django template language: For Python programmers`: ../templates_python/
+.. _Smarty: http://smarty.php.net/
+.. _CheetahTemplate: http://www.cheetahtemplate.org/
+
+Templates
+=========
+
+.. highlightlang:: html+django
+
+A template is simply a text file. It can generate any text-based format (HTML,
+XML, CSV, etc.).
+
+A template contains **variables**, which get replaced with values when the
+template is evaluated, and **tags**, which control the logic of the template.
+
+Below is a minimal template that illustrates a few basics. Each element will be
+explained later in this document.::
+
+ {% extends "base_generic.html" %}
+
+ {% block title %}{{ section.title }}{% endblock %}
+
+ {% block content %}
+ <h1>{{ section.title }}</h1>
+
+ {% for story in story_list %}
+ <h2>
+ <a href="{{ story.get_absolute_url }}">
+ {{ story.headline|upper }}
+ </a>
+ </h2>
+ <p>{{ story.tease|truncatewords:"100" }}</p>
+ {% endfor %}
+ {% endblock %}
+
+.. admonition:: Philosophy
+
+ Why use a text-based template instead of an XML-based one (like Zope's
+ TAL)? We wanted Django's template language to be usable for more than
+ just XML/HTML templates. At World Online, we use it for e-mails,
+ JavaScript and CSV. You can use the template language for any text-based
+ format.
+
+ Oh, and one more thing: Making humans edit XML is sadistic!
+
+Variables
+=========
+
+Variables look like this: ``{{ variable }}``. When the template engine
+encounters a variable, it evaluates that variable and replaces it with the
+result.
+
+Use a dot (``.``) to access attributes of a variable.
+
+.. admonition:: Behind the scenes
+
+ Technically, when the template system encounters a dot, it tries the
+ following lookups, in this order:
+
+ * Dictionary lookup
+ * Attribute lookup
+ * Method call
+ * List-index lookup
+
+In the above example, ``{{ section.title }}`` will be replaced with the
+``title`` attribute of the ``section`` object.
+
+If you use a variable that doesn't exist, the template system will insert
+the value of the ``TEMPLATE_STRING_IF_INVALID`` setting, which is set to ``''``
+(the empty string) by default.
+
+Filters
+=======
+
+You can modify variables for display by using **filters**.
+
+Filters look like this: ``{{ name|lower }}``. This displays the value of the
+``{{ name }}`` variable after being filtered through the ``lower`` filter,
+which converts text to lowercase. Use a pipe (``|``) to apply a filter.
+
+Filters can be "chained." The output of one filter is applied to the next.
+``{{ text|escape|linebreaks }}`` is a common idiom for escaping text contents,
+then converting line breaks to ``<p>`` tags.
+
+Some filters take arguments. A filter argument looks like this: ``{{
+bio|truncatewords:30 }}``. This will display the first 30 words of the ``bio``
+variable.
+
+Filter arguments that contain spaces must be quoted; for example, to join a list
+with commas and spaced you'd use ``{{ list|join:", " }}``.
+
+Django provides about thirty built-in template filters. You can read all about
+them in the :ref:`built-in filter reference <ref-templates-builtins-filters>`.
+To give you a taste of what's available, here are some of the more commonly used
+template filters:
+
+ :tfilter:`default`
+ If a variable is false or empty, use given default. Otherwise, use the
+ value of the variable
+
+ For example::
+
+ {{ value|default:"nothing" }}
+
+ If ``value`` isn't provided or is empty, the above will display
+ "``nothing``".
+
+ :tfilter:`length`
+ Returns the length of the value. This works for both strings and lists;
+ for example::
+
+ {{ value|length }}
+
+ If ``value`` is ``['a', 'b', 'c', 'd']``, the output will be ``4``.
+
+ :tfilter:`striptags`
+ Strips all [X]HTML tags. For example::
+
+ {{ value|striptags }}
+
+ If ``value`` is ``"<b>Joel</b> <button>is</button> a
+ <span>slug</span>"``, the output will be ``"Joel is a slug"``.
+
+Again, these are just a few examples; see the :ref:`built-in filter reference
+<ref-templates-builtins-filters>` for the complete list.
+
+You can also create your own custom template filters; see
+:doc:`/howto/custom-template-tags`.
+
+.. seealso::
+
+ Django's admin interface can include a complete reference of all template
+ tags and filters available for a given site. See
+ :doc:`/ref/contrib/admin/admindocs`.
+
+Tags
+====
+
+Tags look like this: ``{% tag %}``. Tags are more complex than variables: Some
+create text in the output, some control flow by performing loops or logic, and
+some load external information into the template to be used by later variables.
+
+Some tags require beginning and ending tags (i.e. ``{% tag %} ... tag contents
+... {% endtag %}``).
+
+Django ships with about two dozen built-in template tags. You can read all about
+them in the :ref:`built-in tag reference <ref-templates-builtins-tags>`. To give
+you a taste of what's available, here are some of the more commonly used
+tags:
+
+ :ttag:`for`
+ Loop over each item in an array. For example, to display a list of athletes
+ provided in ``athlete_list``::
+
+ <ul>
+ {% for athlete in athlete_list %}
+ <li>{{ athlete.name }}</li>
+ {% endfor %}
+ </ul>
+
+ :ttag:`if` and ``else``
+ Evaluates a variable, and if that variable is "true" the contents of the
+ block are displayed::
+
+ {% if athlete_list %}
+ Number of athletes: {{ athlete_list|length }}
+ {% else %}
+ No athletes.
+ {% endif %}
+
+ In the above, if ``athlete_list`` is not empty, the number of athletes
+ will be displayed by the ``{{ athlete_list|length }}`` variable.
+
+ You can also use filters and various operators in the ``if`` tag::
+
+ {% if athlete_list|length > 1 %}
+ Team: {% for athlete in athlete_list %} ... {% endfor %}
+ {% else %}
+ Athlete: {{ athlete_list.0.name }}
+ {% endif %}
+
+ :ttag:`block` and :ttag:`extends`
+ Set up `template inheritance`_ (see below), a powerful way
+ of cutting down on "boilerplate" in templates.
+
+Again, the above is only a selection of the whole list; see the :ref:`built-in
+tag reference <ref-templates-builtins-tags>` for the complete list.
+
+You can also create your own custom template tags; see
+:doc:`/howto/custom-template-tags`.
+
+.. seealso::
+
+ Django's admin interface can include a complete reference of all template
+ tags and filters available for a given site. See
+ :doc:`/ref/contrib/admin/admindocs`.
+
+Comments
+========
+
+To comment-out part of a line in a template, use the comment syntax: ``{# #}``.
+
+For example, this template would render as ``'hello'``::
+
+ {# greeting #}hello
+
+A comment can contain any template code, invalid or not. For example::
+
+ {# {% if foo %}bar{% else %} #}
+
+This syntax can only be used for single-line comments (no newlines are permitted
+between the ``{#`` and ``#}`` delimiters). If you need to comment out a
+multiline portion of the template, see the :ttag:`comment` tag.
+
+.. _template-inheritance:
+
+Template inheritance
+====================
+
+The most powerful -- and thus the most complex -- part of Django's template
+engine is template inheritance. Template inheritance allows you to build a base
+"skeleton" template that contains all the common elements of your site and
+defines **blocks** that child templates can override.
+
+It's easiest to understand template inheritance by starting with an example::
+
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <link rel="stylesheet" href="style.css" />
+ <title>{% block title %}My amazing site{% endblock %}</title>
+ </head>
+
+ <body>
+ <div id="sidebar">
+ {% block sidebar %}
+ <ul>
+ <li><a href="/">Home</a></li>
+ <li><a href="/blog/">Blog</a></li>
+ </ul>
+ {% endblock %}
+ </div>
+
+ <div id="content">
+ {% block content %}{% endblock %}
+ </div>
+ </body>
+ </html>
+
+This template, which we'll call ``base.html``, defines a simple HTML skeleton
+document that you might use for a simple two-column page. It's the job of
+"child" templates to fill the empty blocks with content.
+
+In this example, the ``{% block %}`` tag defines three blocks that child
+templates can fill in. All the ``block`` tag does is to tell the template
+engine that a child template may override those portions of the template.
+
+A child template might look like this::
+
+ {% extends "base.html" %}
+
+ {% block title %}My amazing blog{% endblock %}
+
+ {% block content %}
+ {% for entry in blog_entries %}
+ <h2>{{ entry.title }}</h2>
+ <p>{{ entry.body }}</p>
+ {% endfor %}
+ {% endblock %}
+
+The ``{% extends %}`` tag is the key here. It tells the template engine that
+this template "extends" another template. When the template system evaluates
+this template, first it locates the parent -- in this case, "base.html".
+
+At that point, the template engine will notice the three ``{% block %}`` tags
+in ``base.html`` and replace those blocks with the contents of the child
+template. Depending on the value of ``blog_entries``, the output might look
+like::
+
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+ <head>
+ <link rel="stylesheet" href="style.css" />
+ <title>My amazing blog</title>
+ </head>
+
+ <body>
+ <div id="sidebar">
+ <ul>
+ <li><a href="/">Home</a></li>
+ <li><a href="/blog/">Blog</a></li>
+ </ul>
+ </div>
+
+ <div id="content">
+ <h2>Entry one</h2>
+ <p>This is my first entry.</p>
+
+ <h2>Entry two</h2>
+ <p>This is my second entry.</p>
+ </div>
+ </body>
+ </html>
+
+Note that since the child template didn't define the ``sidebar`` block, the
+value from the parent template is used instead. Content within a ``{% block %}``
+tag in a parent template is always used as a fallback.
+
+You can use as many levels of inheritance as needed. One common way of using
+inheritance is the following three-level approach:
+
+ * Create a ``base.html`` template that holds the main look-and-feel of your
+ site.
+ * Create a ``base_SECTIONNAME.html`` template for each "section" of your
+ site. For example, ``base_news.html``, ``base_sports.html``. These
+ templates all extend ``base.html`` and include section-specific
+ styles/design.
+ * Create individual templates for each type of page, such as a news
+ article or blog entry. These templates extend the appropriate section
+ template.
+
+This approach maximizes code reuse and makes it easy to add items to shared
+content areas, such as section-wide navigation.
+
+Here are some tips for working with inheritance:
+
+ * If you use ``{% extends %}`` in a template, it must be the first template
+ tag in that template. Template inheritance won't work, otherwise.
+
+ * More ``{% block %}`` tags in your base templates are better. Remember,
+ child templates don't have to define all parent blocks, so you can fill
+ in reasonable defaults in a number of blocks, then only define the ones
+ you need later. It's better to have more hooks than fewer hooks.
+
+ * If you find yourself duplicating content in a number of templates, it
+ probably means you should move that content to a ``{% block %}`` in a
+ parent template.
+
+ * If you need to get the content of the block from the parent template,
+ the ``{{ block.super }}`` variable will do the trick. This is useful
+ if you want to add to the contents of a parent block instead of
+ completely overriding it. Data inserted using ``{{ block.super }}`` will
+ not be automatically escaped (see the `next section`_), since it was
+ already escaped, if necessary, in the parent template.
+
+ * For extra readability, you can optionally give a *name* to your
+ ``{% endblock %}`` tag. For example::
+
+ {% block content %}
+ ...
+ {% endblock content %}
+
+ In larger templates, this technique helps you see which ``{% block %}``
+ tags are being closed.
+
+Finally, note that you can't define multiple ``{% block %}`` tags with the same
+name in the same template. This limitation exists because a block tag works in
+"both" directions. That is, a block tag doesn't just provide a hole to fill --
+it also defines the content that fills the hole in the *parent*. If there were
+two similarly-named ``{% block %}`` tags in a template, that template's parent
+wouldn't know which one of the blocks' content to use.
+
+.. _next section: #automatic-html-escaping
+.. _automatic-html-escaping:
+
+Automatic HTML escaping
+=======================
+
+.. versionadded:: 1.0
+
+When generating HTML from templates, there's always a risk that a variable will
+include characters that affect the resulting HTML. For example, consider this
+template fragment::
+
+ Hello, {{ name }}.
+
+At first, this seems like a harmless way to display a user's name, but consider
+what would happen if the user entered his name as this::
+
+ <script>alert('hello')</script>
+
+With this name value, the template would be rendered as::
+
+ Hello, <script>alert('hello')</script>
+
+...which means the browser would pop-up a JavaScript alert box!
+
+Similarly, what if the name contained a ``'<'`` symbol, like this?
+
+ <b>username
+
+That would result in a rendered template like this::
+
+ Hello, <b>username
+
+...which, in turn, would result in the remainder of the Web page being bolded!
+
+Clearly, user-submitted data shouldn't be trusted blindly and inserted directly
+into your Web pages, because a malicious user could use this kind of hole to
+do potentially bad things. This type of security exploit is called a
+`Cross Site Scripting`_ (XSS) attack.
+
+To avoid this problem, you have two options:
+
+ * One, you can make sure to run each untrusted variable through the
+ ``escape`` filter (documented below), which converts potentially harmful
+ HTML characters to unharmful ones. This was the default solution
+ in Django for its first few years, but the problem is that it puts the
+ onus on *you*, the developer / template author, to ensure you're escaping
+ everything. It's easy to forget to escape data.
+
+ * Two, you can take advantage of Django's automatic HTML escaping. The
+ remainder of this section describes how auto-escaping works.
+
+By default in Django, every template automatically escapes the output
+of every variable tag. Specifically, these five characters are
+escaped:
+
+ * ``<`` is converted to ``&lt;``
+ * ``>`` is converted to ``&gt;``
+ * ``'`` (single quote) is converted to ``&#39;``
+ * ``"`` (double quote) is converted to ``&quot;``
+ * ``&`` is converted to ``&amp;``
+
+Again, we stress that this behavior is on by default. If you're using Django's
+template system, you're protected.
+
+.. _Cross Site Scripting: http://en.wikipedia.org/wiki/Cross-site_scripting
+
+How to turn it off
+------------------
+
+If you don't want data to be auto-escaped, on a per-site, per-template level or
+per-variable level, you can turn it off in several ways.
+
+Why would you want to turn it off? Because sometimes, template variables
+contain data that you *intend* to be rendered as raw HTML, in which case you
+don't want their contents to be escaped. For example, you might store a blob of
+HTML in your database and want to embed that directly into your template. Or,
+you might be using Django's template system to produce text that is *not* HTML
+-- like an e-mail message, for instance.
+
+For individual variables
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+To disable auto-escaping for an individual variable, use the ``safe`` filter::
+
+ This will be escaped: {{ data }}
+ This will not be escaped: {{ data|safe }}
+
+Think of *safe* as shorthand for *safe from further escaping* or *can be
+safely interpreted as HTML*. In this example, if ``data`` contains ``'<b>'``,
+the output will be::
+
+ This will be escaped: &lt;b&gt;
+ This will not be escaped: <b>
+
+For template blocks
+~~~~~~~~~~~~~~~~~~~
+
+To control auto-escaping for a template, wrap the template (or just a
+particular section of the template) in the ``autoescape`` tag, like so::
+
+ {% autoescape off %}
+ Hello {{ name }}
+ {% endautoescape %}
+
+The ``autoescape`` tag takes either ``on`` or ``off`` as its argument. At
+times, you might want to force auto-escaping when it would otherwise be
+disabled. Here is an example template::
+
+ Auto-escaping is on by default. Hello {{ name }}
+
+ {% autoescape off %}
+ This will not be auto-escaped: {{ data }}.
+
+ Nor this: {{ other_data }}
+ {% autoescape on %}
+ Auto-escaping applies again: {{ name }}
+ {% endautoescape %}
+ {% endautoescape %}
+
+The auto-escaping tag passes its effect onto templates that extend the
+current one as well as templates included via the ``include`` tag, just like
+all block tags. For example::
+
+ # base.html
+
+ {% autoescape off %}
+ <h1>{% block title %}{% endblock %}</h1>
+ {% block content %}
+ {% endblock %}
+ {% endautoescape %}
+
+
+ # child.html
+
+ {% extends "base.html" %}
+ {% block title %}This & that{% endblock %}
+ {% block content %}{{ greeting }}{% endblock %}
+
+Because auto-escaping is turned off in the base template, it will also be
+turned off in the child template, resulting in the following rendered
+HTML when the ``greeting`` variable contains the string ``<b>Hello!</b>``::
+
+ <h1>This & that</h1>
+ <b>Hello!</b>
+
+Notes
+-----
+
+Generally, template authors don't need to worry about auto-escaping very much.
+Developers on the Python side (people writing views and custom filters) need to
+think about the cases in which data shouldn't be escaped, and mark data
+appropriately, so things Just Work in the template.
+
+If you're creating a template that might be used in situations where you're
+not sure whether auto-escaping is enabled, then add an ``escape`` filter to any
+variable that needs escaping. When auto-escaping is on, there's no danger of
+the ``escape`` filter *double-escaping* data -- the ``escape`` filter does not
+affect auto-escaped variables.
+
+String literals and automatic escaping
+--------------------------------------
+
+As we mentioned earlier, filter arguments can be strings::
+
+ {{ data|default:"This is a string literal." }}
+
+All string literals are inserted **without** any automatic escaping into the
+template -- they act as if they were all passed through the ``safe`` filter.
+The reasoning behind this is that the template author is in control of what
+goes into the string literal, so they can make sure the text is correctly
+escaped when the template is written.
+
+This means you would write ::
+
+ {{ data|default:"3 &lt; 2" }}
+
+...rather than ::
+
+ {{ data|default:"3 < 2" }} <-- Bad! Don't do this.
+
+This doesn't affect what happens to data coming from the variable itself.
+The variable's contents are still automatically escaped, if necessary, because
+they're beyond the control of the template author.
+
+.. _loading-custom-template-libraries:
+
+Custom tag and filter libraries
+===============================
+
+Certain applications provide custom tag and filter libraries. To access them in
+a template, use the ``{% load %}`` tag::
+
+ {% load comments %}
+
+ {% comment_form for blogs.entries entry.id with is_public yes %}
+
+In the above, the ``load`` tag loads the ``comments`` tag library, which then
+makes the ``comment_form`` tag available for use. Consult the documentation
+area in your admin to find the list of custom libraries in your installation.
+
+The ``{% load %}`` tag can take multiple library names, separated by spaces.
+Example::
+
+ {% load comments i18n %}
+
+See :doc:`/howto/custom-template-tags` for information on writing your own custom
+template libraries.
+
+Custom libraries and template inheritance
+-----------------------------------------
+
+When you load a custom tag or filter library, the tags/filters are only made
+available to the current template -- not any parent or child templates along
+the template-inheritance path.
+
+For example, if a template ``foo.html`` has ``{% load comments %}``, a child
+template (e.g., one that has ``{% extends "foo.html" %}``) will *not* have
+access to the comments template tags and filters. The child template is
+responsible for its own ``{% load comments %}``.
+
+This is a feature for the sake of maintainability and sanity.
diff --git a/parts/django/docs/topics/testing.txt b/parts/django/docs/topics/testing.txt
new file mode 100644
index 0000000..155f758
--- /dev/null
+++ b/parts/django/docs/topics/testing.txt
@@ -0,0 +1,1613 @@
+===========================
+Testing Django applications
+===========================
+
+.. module:: django.test
+ :synopsis: Testing tools for Django applications.
+
+Automated testing is an extremely useful bug-killing tool for the modern
+Web developer. You can use a collection of tests -- a **test suite** -- to
+solve, or avoid, a number of problems:
+
+ * When you're writing new code, you can use tests to validate your code
+ works as expected.
+
+ * When you're refactoring or modifying old code, you can use tests to
+ ensure your changes haven't affected your application's behavior
+ unexpectedly.
+
+Testing a Web application is a complex task, because a Web application is made
+of several layers of logic -- from HTTP-level request handling, to form
+validation and processing, to template rendering. With Django's test-execution
+framework and assorted utilities, you can simulate requests, insert test data,
+inspect your application's output and generally verify your code is doing what
+it should be doing.
+
+The best part is, it's really easy.
+
+This document is split into two primary sections. First, we explain how to
+write tests with Django. Then, we explain how to run them.
+
+Writing tests
+=============
+
+There are two primary ways to write tests with Django, corresponding to the
+two test frameworks that ship in the Python standard library. The two
+frameworks are:
+
+ * **Doctests** -- tests that are embedded in your functions' docstrings and
+ are written in a way that emulates a session of the Python interactive
+ interpreter. For example::
+
+ def my_func(a_list, idx):
+ """
+ >>> a = ['larry', 'curly', 'moe']
+ >>> my_func(a, 0)
+ 'larry'
+ >>> my_func(a, 1)
+ 'curly'
+ """
+ return a_list[idx]
+
+ * **Unit tests** -- tests that are expressed as methods on a Python class
+ that subclasses ``unittest.TestCase``. For example::
+
+ import unittest
+
+ class MyFuncTestCase(unittest.TestCase):
+ def testBasic(self):
+ a = ['larry', 'curly', 'moe']
+ self.assertEquals(my_func(a, 0), 'larry')
+ self.assertEquals(my_func(a, 1), 'curly')
+
+You can choose the test framework you like, depending on which syntax you
+prefer, or you can mix and match, using one framework for some of your code and
+the other framework for other code. You can also use any *other* Python test
+frameworks, as we'll explain in a bit.
+
+Writing doctests
+----------------
+
+Doctests use Python's standard doctest_ module, which searches your docstrings
+for statements that resemble a session of the Python interactive interpreter.
+A full explanation of how doctest works is out of the scope of this document;
+read Python's official documentation for the details.
+
+.. admonition:: What's a **docstring**?
+
+ A good explanation of docstrings (and some guidelines for using them
+ effectively) can be found in :pep:`257`:
+
+ A docstring is a string literal that occurs as the first statement in
+ a module, function, class, or method definition. Such a docstring
+ becomes the ``__doc__`` special attribute of that object.
+
+ For example, this function has a docstring that describes what it does::
+
+ def add_two(num):
+ "Return the result of adding two to the provided number."
+ return num + 2
+
+ Because tests often make great documentation, putting tests directly in
+ your docstrings is an effective way to document *and* test your code.
+
+For a given Django application, the test runner looks for doctests in two
+places:
+
+ * The ``models.py`` file. You can define module-level doctests and/or a
+ doctest for individual models. It's common practice to put
+ application-level doctests in the module docstring and model-level
+ doctests in the model docstrings.
+
+ * A file called ``tests.py`` in the application directory -- i.e., the
+ directory that holds ``models.py``. This file is a hook for any and all
+ doctests you want to write that aren't necessarily related to models.
+
+Here is an example model doctest::
+
+ # models.py
+
+ from django.db import models
+
+ class Animal(models.Model):
+ """
+ An animal that knows how to make noise
+
+ # Create some animals
+ >>> lion = Animal.objects.create(name="lion", sound="roar")
+ >>> cat = Animal.objects.create(name="cat", sound="meow")
+
+ # Make 'em speak
+ >>> lion.speak()
+ 'The lion says "roar"'
+ >>> cat.speak()
+ 'The cat says "meow"'
+ """
+ name = models.CharField(max_length=20)
+ sound = models.CharField(max_length=20)
+
+ def speak(self):
+ return 'The %s says "%s"' % (self.name, self.sound)
+
+When you :ref:`run your tests <running-tests>`, the test runner will find this
+docstring, notice that portions of it look like an interactive Python session,
+and execute those lines while checking that the results match.
+
+In the case of model tests, note that the test runner takes care of creating
+its own test database. That is, any test that accesses a database -- by
+creating and saving model instances, for example -- will not affect your
+production database. However, the database is not refreshed between doctests,
+so if your doctest requires a certain state you should consider flushing the
+database or loading a fixture. (See the section on fixtures, below, for more
+on this.) Note that to use this feature, the database user Django is connecting
+as must have ``CREATE DATABASE`` rights.
+
+For more details about how doctest works, see the `standard library
+documentation for doctest`_.
+
+.. _doctest: http://docs.python.org/library/doctest.html
+.. _standard library documentation for doctest: doctest_
+
+Writing unit tests
+------------------
+
+Like doctests, Django's unit tests use a standard library module: unittest_.
+This module uses a different way of defining tests, taking a class-based
+approach.
+
+As with doctests, for a given Django application, the test runner looks for
+unit tests in two places:
+
+ * The ``models.py`` file. The test runner looks for any subclass of
+ ``unittest.TestCase`` in this module.
+
+ * A file called ``tests.py`` in the application directory -- i.e., the
+ directory that holds ``models.py``. Again, the test runner looks for any
+ subclass of ``unittest.TestCase`` in this module.
+
+This example ``unittest.TestCase`` subclass is equivalent to the example given
+in the doctest section above::
+
+ import unittest
+ from myapp.models import Animal
+
+ class AnimalTestCase(unittest.TestCase):
+ def setUp(self):
+ self.lion = Animal.objects.create(name="lion", sound="roar")
+ self.cat = Animal.objects.create(name="cat", sound="meow")
+
+ def testSpeaking(self):
+ self.assertEquals(self.lion.speak(), 'The lion says "roar"')
+ self.assertEquals(self.cat.speak(), 'The cat says "meow"')
+
+When you :ref:`run your tests <running-tests>`, the default behavior of the
+test utility is to find all the test cases (that is, subclasses of
+``unittest.TestCase``) in ``models.py`` and ``tests.py``, automatically build a
+test suite out of those test cases, and run that suite.
+
+There is a second way to define the test suite for a module: if you define a
+function called ``suite()`` in either ``models.py`` or ``tests.py``, the
+Django test runner will use that function to construct the test suite for that
+module. This follows the `suggested organization`_ for unit tests. See the
+Python documentation for more details on how to construct a complex test
+suite.
+
+For more details about ``unittest``, see the `standard library unittest
+documentation`_.
+
+.. _unittest: http://docs.python.org/library/unittest.html
+.. _standard library unittest documentation: unittest_
+.. _suggested organization: http://docs.python.org/library/unittest.html#organizing-tests
+
+Which should I use?
+-------------------
+
+Because Django supports both of the standard Python test frameworks, it's up to
+you and your tastes to decide which one to use. You can even decide to use
+*both*.
+
+For developers new to testing, however, this choice can seem confusing. Here,
+then, are a few key differences to help you decide which approach is right for
+you:
+
+ * If you've been using Python for a while, ``doctest`` will probably feel
+ more "pythonic". It's designed to make writing tests as easy as possible,
+ so it requires no overhead of writing classes or methods. You simply put
+ tests in docstrings. This has the added advantage of serving as
+ documentation (and correct documentation, at that!).
+
+ If you're just getting started with testing, using doctests will probably
+ get you started faster.
+
+ * The ``unittest`` framework will probably feel very familiar to developers
+ coming from Java. ``unittest`` is inspired by Java's JUnit, so you'll
+ feel at home with this method if you've used JUnit or any test framework
+ inspired by JUnit.
+
+ * If you need to write a bunch of tests that share similar code, then
+ you'll appreciate the ``unittest`` framework's organization around
+ classes and methods. This makes it easy to abstract common tasks into
+ common methods. The framework also supports explicit setup and/or cleanup
+ routines, which give you a high level of control over the environment
+ in which your test cases are run.
+
+Again, remember that you can use both systems side-by-side (even in the same
+app). In the end, most projects will eventually end up using both. Each shines
+in different circumstances.
+
+.. _running-tests:
+
+Running tests
+=============
+
+Once you've written tests, run them using the :djadmin:`test` command of
+your project's ``manage.py`` utility::
+
+ $ ./manage.py test
+
+By default, this will run every test in every application in
+:setting:`INSTALLED_APPS`. If you only want to run tests for a particular
+application, add the application name to the command line. For example, if your
+:setting:`INSTALLED_APPS` contains ``'myproject.polls'`` and
+``'myproject.animals'``, you can run the ``myproject.animals`` unit tests alone
+with this command::
+
+ $ ./manage.py test animals
+
+Note that we used ``animals``, not ``myproject.animals``.
+
+.. versionadded:: 1.0
+ You can now choose which test to run.
+
+You can be even *more* specific by naming an individual test case. To
+run a single test case in an application (for example, the
+``AnimalTestCase`` described in the "Writing unit tests" section), add
+the name of the test case to the label on the command line::
+
+ $ ./manage.py test animals.AnimalTestCase
+
+And it gets even more granular than that! To run a *single* test
+method inside a test case, add the name of the test method to the
+label::
+
+ $ ./manage.py test animals.AnimalTestCase.testFluffyAnimals
+
+.. versionadded:: 1.2
+ The ability to select individual doctests was added.
+
+You can use the same rules if you're using doctests. Django will use the
+test label as a path to the test method or class that you want to run.
+If your ``models.py`` or ``tests.py`` has a function with a doctest, or
+class with a class-level doctest, you can invoke that test by appending the
+name of the test method or class to the label::
+
+ $ ./manage.py test animals.classify
+
+If you want to run the doctest for a specific method in a class, add the
+name of the method to the label::
+
+ $ ./manage.py test animals.Classifier.run
+
+If you're using a ``__test__`` dictionary to specify doctests for a
+module, Django will use the label as a key in the ``__test__`` dictionary
+for defined in ``models.py`` and ``tests.py``.
+
+.. versionadded:: 1.2
+ You can now trigger a graceful exit from a test run by pressing ``Ctrl-C``.
+
+If you press ``Ctrl-C`` while the tests are running, the test runner will
+wait for the currently running test to complete and then exit gracefully.
+During a graceful exit the test runner will output details of any test
+failures, report on how many tests were run and how many errors and failures
+were encountered, and destroy any test databases as usual. Thus pressing
+``Ctrl-C`` can be very useful if you forget to pass the :djadminopt:`--failfast`
+option, notice that some tests are unexpectedly failing, and want to get details
+on the failures without waiting for the full test run to complete.
+
+If you do not want to wait for the currently running test to finish, you
+can press ``Ctrl-C`` a second time and the test run will halt immediately,
+but not gracefully. No details of the tests run before the interruption will
+be reported, and any test databases created by the run will not be destroyed.
+
+.. admonition:: Test with warnings enabled
+
+ It is a good idea to run your tests with ``python -Wall manage.py
+ test``. This will allow you to catch any deprecation warnings that
+ might be in your code. Django (as well as many other libraries) use
+ warnings to flag when features are deprecated. It can also flag
+ areas in your code that are not strictly wrong, but may benefit
+ from a better implementation.
+
+Running tests outside the test runner
+-------------------------------------
+
+If you want to run tests outside of ``./manage.py test`` -- for example,
+from a shell prompt -- you will need to set up the test
+environment first. Django provides a convenience method to do this::
+
+ >>> from django.test.utils import setup_test_environment
+ >>> setup_test_environment()
+
+This convenience method sets up the test database, and puts other
+Django features into modes that allow for repeatable testing.
+
+The call to :meth:`~django.test.utils.setup_test_environment` is made
+automatically as part of the setup of `./manage.py test`. You only
+need to manually invoke this method if you're not using running your
+tests via Django's test runner.
+
+The test database
+-----------------
+
+Tests that require a database (namely, model tests) will not use your "real"
+(production) database. Separate, blank databases are created for the tests.
+
+Regardless of whether the tests pass or fail, the test databases are destroyed
+when all the tests have been executed.
+
+By default the test databases get their names by prepending ``test_``
+to the value of the :setting:`NAME` settings for the databases
+defined in :setting:`DATABASES`. When using the SQLite database engine
+the tests will by default use an in-memory database (i.e., the
+database will be created in memory, bypassing the filesystem
+entirely!). If you want to use a different database name, specify
+:setting:`TEST_NAME` in the dictionary for any given database in
+:setting:`DATABASES`.
+
+Aside from using a separate database, the test runner will otherwise
+use all of the same database settings you have in your settings file:
+:setting:`ENGINE`, :setting:`USER`, :setting:`HOST`, etc. The test
+database is created by the user specified by ``USER``, so you'll need
+to make sure that the given user account has sufficient privileges to
+create a new database on the system.
+
+.. versionadded:: 1.0
+
+For fine-grained control over the character encoding of your test
+database, use the :setting:`TEST_CHARSET` option. If you're using
+MySQL, you can also use the :setting:`TEST_COLLATION` option to
+control the particular collation used by the test database. See the
+:doc:`settings documentation </ref/settings>` for details of these
+advanced settings.
+
+.. _topics-testing-masterslave:
+
+Testing master/slave configurations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.2
+
+If you're testing a multiple database configuration with master/slave
+replication, this strategy of creating test databases poses a problem.
+When the test databases are created, there won't be any replication,
+and as a result, data created on the master won't be seen on the
+slave.
+
+To compensate for this, Django allows you to define that a database is
+a *test mirror*. Consider the following (simplified) example database
+configuration::
+
+ DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.mysql',
+ 'NAME': 'myproject',
+ 'HOST': 'dbmaster',
+ # ... plus some other settings
+ },
+ 'slave': {
+ 'ENGINE': 'django.db.backends.mysql',
+ 'NAME': 'myproject',
+ 'HOST': 'dbslave',
+ 'TEST_MIRROR': 'default'
+ # ... plus some other settings
+ }
+ }
+
+In this setup, we have two database servers: ``dbmaster``, described
+by the database alias ``default``, and ``dbslave`` described by the
+alias ``slave``. As you might expect, ``dbslave`` has been configured
+by the database administrator as a read slave of ``dbmaster``, so in
+normal activity, any write to ``default`` will appear on ``slave``.
+
+If Django created two independent test databases, this would break any
+tests that expected replication to occur. However, the ``slave``
+database has been configured as a test mirror (using the
+:setting:`TEST_MIRROR` setting), indicating that under testing,
+``slave`` should be treated as a mirror of ``default``.
+
+When the test environment is configured, a test version of ``slave``
+will *not* be created. Instead the connection to ``slave``
+will be redirected to point at ``default``. As a result, writes to
+``default`` will appear on ``slave`` -- but because they are actually
+the same database, not because there is data replication between the
+two databases.
+
+.. _topics-testing-creation-dependencies:
+
+Controlling creation order for test databases
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.2.4
+
+By default, Django will always create the ``default`` database first.
+However, no guarantees are made on the creation order of any other
+databases in your test setup.
+
+If your database configuration requires a specific creation order, you
+can specify the dependencies that exist using the
+:setting:`TEST_DEPENDENCIES` setting. Consider the following
+(simplified) example database configuration::
+
+ DATABASES = {
+ 'default': {
+ # ... db settings
+ 'TEST_DEPENDENCIES': ['diamonds']
+ },
+ 'diamonds': {
+ # ... db settings
+ },
+ 'clubs': {
+ # ... db settings
+ 'TEST_DEPENDENCIES': ['diamonds']
+ },
+ 'spades': {
+ # ... db settings
+ 'TEST_DEPENDENCIES': ['diamonds','hearts']
+ },
+ 'hearts': {
+ # ... db settings
+ 'TEST_DEPENDENCIES': ['diamonds','clubs']
+ }
+ }
+
+Under this configuration, the ``diamonds`` database will be created first,
+as it is the only database alias without dependencies. The ``default``` and
+``clubs`` alias will be created next (although the order of creation of this
+pair is not guaranteed); then ``hearts``; and finally ``spades``.
+
+If there are any circular dependencies in the
+:setting:`TEST_DEPENDENCIES` definition, an ``ImproperlyConfigured``
+exception will be raised.
+
+Other test conditions
+---------------------
+
+Regardless of the value of the :setting:`DEBUG` setting in your configuration
+file, all Django tests run with :setting:`DEBUG`\=False. This is to ensure that
+the observed output of your code matches what will be seen in a production
+setting.
+
+Understanding the test output
+-----------------------------
+
+When you run your tests, you'll see a number of messages as the test runner
+prepares itself. You can control the level of detail of these messages with the
+``verbosity`` option on the command line::
+
+ Creating test database...
+ Creating table myapp_animal
+ Creating table myapp_mineral
+ Loading 'initial_data' fixtures...
+ No fixtures found.
+
+This tells you that the test runner is creating a test database, as described
+in the previous section.
+
+Once the test database has been created, Django will run your tests.
+If everything goes well, you'll see something like this::
+
+ ----------------------------------------------------------------------
+ Ran 22 tests in 0.221s
+
+ OK
+
+If there are test failures, however, you'll see full details about which tests
+failed::
+
+ ======================================================================
+ FAIL: Doctest: ellington.core.throttle.models
+ ----------------------------------------------------------------------
+ Traceback (most recent call last):
+ File "/dev/django/test/doctest.py", line 2153, in runTest
+ raise self.failureException(self.format_failure(new.getvalue()))
+ AssertionError: Failed doctest test for myapp.models
+ File "/dev/myapp/models.py", line 0, in models
+
+ ----------------------------------------------------------------------
+ File "/dev/myapp/models.py", line 14, in myapp.models
+ Failed example:
+ throttle.check("actor A", "action one", limit=2, hours=1)
+ Expected:
+ True
+ Got:
+ False
+
+ ----------------------------------------------------------------------
+ Ran 2 tests in 0.048s
+
+ FAILED (failures=1)
+
+A full explanation of this error output is beyond the scope of this document,
+but it's pretty intuitive. You can consult the documentation of Python's
+``unittest`` library for details.
+
+Note that the return code for the test-runner script is the total number of
+failed and erroneous tests. If all the tests pass, the return code is 0. This
+feature is useful if you're using the test-runner script in a shell script and
+need to test for success or failure at that level.
+
+Testing tools
+=============
+
+Django provides a small set of tools that come in handy when writing tests.
+
+The test client
+---------------
+
+.. module:: django.test.client
+ :synopsis: Django's test client.
+
+The test client is a Python class that acts as a dummy Web browser, allowing
+you to test your views and interact with your Django-powered application
+programmatically.
+
+Some of the things you can do with the test client are:
+
+ * Simulate GET and POST requests on a URL and observe the response --
+ everything from low-level HTTP (result headers and status codes) to
+ page content.
+
+ * Test that the correct view is executed for a given URL.
+
+ * Test that a given request is rendered by a given Django template, with
+ a template context that contains certain values.
+
+Note that the test client is not intended to be a replacement for Twill_,
+Selenium_, or other "in-browser" frameworks. Django's test client has
+a different focus. In short:
+
+ * Use Django's test client to establish that the correct view is being
+ called and that the view is collecting the correct context data.
+
+ * Use in-browser frameworks such as Twill and Selenium to test *rendered*
+ HTML and the *behavior* of Web pages, namely JavaScript functionality.
+
+A comprehensive test suite should use a combination of both test types.
+
+.. _Twill: http://twill.idyll.org/
+.. _Selenium: http://seleniumhq.org/
+
+Overview and a quick example
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To use the test client, instantiate ``django.test.client.Client`` and retrieve
+Web pages::
+
+ >>> from django.test.client import Client
+ >>> c = Client()
+ >>> response = c.post('/login/', {'username': 'john', 'password': 'smith'})
+ >>> response.status_code
+ 200
+ >>> response = c.get('/customer/details/')
+ >>> response.content
+ '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 ...'
+
+As this example suggests, you can instantiate ``Client`` from within a session
+of the Python interactive interpreter.
+
+Note a few important things about how the test client works:
+
+ * The test client does *not* require the Web server to be running. In fact,
+ it will run just fine with no Web server running at all! That's because
+ it avoids the overhead of HTTP and deals directly with the Django
+ framework. This helps make the unit tests run quickly.
+
+ * When retrieving pages, remember to specify the *path* of the URL, not the
+ whole domain. For example, this is correct::
+
+ >>> c.get('/login/')
+
+ This is incorrect::
+
+ >>> c.get('http://www.example.com/login/')
+
+ The test client is not capable of retrieving Web pages that are not
+ powered by your Django project. If you need to retrieve other Web pages,
+ use a Python standard library module such as urllib_ or urllib2_.
+
+ * To resolve URLs, the test client uses whatever URLconf is pointed-to by
+ your :setting:`ROOT_URLCONF` setting.
+
+ * Although the above example would work in the Python interactive
+ interpreter, some of the test client's functionality, notably the
+ template-related functionality, is only available *while tests are
+ running*.
+
+ The reason for this is that Django's test runner performs a bit of black
+ magic in order to determine which template was loaded by a given view.
+ This black magic (essentially a patching of Django's template system in
+ memory) only happens during test running.
+
+ * By default, the test client will disable any CSRF checks
+ performed by your site.
+
+ .. versionadded:: 1.2.2
+
+ If, for some reason, you *want* the test client to perform CSRF
+ checks, you can create an instance of the test client that
+ enforces CSRF checks. To do this, pass in the
+ ``enforce_csrf_checks`` argument when you construct your
+ client::
+
+ >>> from django.test import Client
+ >>> csrf_client = Client(enforce_csrf_checks=True)
+
+
+.. _urllib: http://docs.python.org/library/urllib.html
+.. _urllib2: http://docs.python.org/library/urllib2.html
+
+Making requests
+~~~~~~~~~~~~~~~
+
+Use the ``django.test.client.Client`` class to make requests. It requires no
+arguments at time of construction:
+
+.. class:: Client()
+
+ Once you have a ``Client`` instance, you can call any of the following
+ methods:
+
+ .. method:: Client.get(path, data={}, follow=False, **extra)
+
+
+ Makes a GET request on the provided ``path`` and returns a ``Response``
+ object, which is documented below.
+
+ The key-value pairs in the ``data`` dictionary are used to create a GET
+ data payload. For example::
+
+ >>> c = Client()
+ >>> c.get('/customers/details/', {'name': 'fred', 'age': 7})
+
+ ...will result in the evaluation of a GET request equivalent to::
+
+ /customers/details/?name=fred&age=7
+
+ The ``extra`` keyword arguments parameter can be used to specify
+ headers to be sent in the request. For example::
+
+ >>> c = Client()
+ >>> c.get('/customers/details/', {'name': 'fred', 'age': 7},
+ ... HTTP_X_REQUESTED_WITH='XMLHttpRequest')
+
+ ...will send the HTTP header ``HTTP_X_REQUESTED_WITH`` to the
+ details view, which is a good way to test code paths that use the
+ :meth:`django.http.HttpRequest.is_ajax()` method.
+
+ .. versionadded:: 1.1
+
+ If you already have the GET arguments in URL-encoded form, you can
+ use that encoding instead of using the data argument. For example,
+ the previous GET request could also be posed as::
+
+ >>> c = Client()
+ >>> c.get('/customers/details/?name=fred&age=7')
+
+ If you provide a URL with both an encoded GET data and a data argument,
+ the data argument will take precedence.
+
+ If you set ``follow`` to ``True`` the client will follow any redirects
+ and a ``redirect_chain`` attribute will be set in the response object
+ containing tuples of the intermediate urls and status codes.
+
+ If you had an url ``/redirect_me/`` that redirected to ``/next/``, that
+ redirected to ``/final/``, this is what you'd see::
+
+ >>> response = c.get('/redirect_me/', follow=True)
+ >>> response.redirect_chain
+ [(u'http://testserver/next/', 302), (u'http://testserver/final/', 302)]
+
+ .. method:: Client.post(path, data={}, content_type=MULTIPART_CONTENT, follow=False, **extra)
+
+ Makes a POST request on the provided ``path`` and returns a
+ ``Response`` object, which is documented below.
+
+ The key-value pairs in the ``data`` dictionary are used to submit POST
+ data. For example::
+
+ >>> c = Client()
+ >>> c.post('/login/', {'name': 'fred', 'passwd': 'secret'})
+
+ ...will result in the evaluation of a POST request to this URL::
+
+ /login/
+
+ ...with this POST data::
+
+ name=fred&passwd=secret
+
+ If you provide ``content_type`` (e.g., ``text/xml`` for an XML
+ payload), the contents of ``data`` will be sent as-is in the POST
+ request, using ``content_type`` in the HTTP ``Content-Type`` header.
+
+ If you don't provide a value for ``content_type``, the values in
+ ``data`` will be transmitted with a content type of
+ ``multipart/form-data``. In this case, the key-value pairs in ``data``
+ will be encoded as a multipart message and used to create the POST data
+ payload.
+
+ To submit multiple values for a given key -- for example, to specify
+ the selections for a ``<select multiple>`` -- provide the values as a
+ list or tuple for the required key. For example, this value of ``data``
+ would submit three selected values for the field named ``choices``::
+
+ {'choices': ('a', 'b', 'd')}
+
+ Submitting files is a special case. To POST a file, you need only
+ provide the file field name as a key, and a file handle to the file you
+ wish to upload as a value. For example::
+
+ >>> c = Client()
+ >>> f = open('wishlist.doc')
+ >>> c.post('/customers/wishes/', {'name': 'fred', 'attachment': f})
+ >>> f.close()
+
+ (The name ``attachment`` here is not relevant; use whatever name your
+ file-processing code expects.)
+
+ Note that if you wish to use the same file handle for multiple
+ ``post()`` calls then you will need to manually reset the file
+ pointer between posts. The easiest way to do this is to
+ manually close the file after it has been provided to
+ ``post()``, as demonstrated above.
+
+ You should also ensure that the file is opened in a way that
+ allows the data to be read. If your file contains binary data
+ such as an image, this means you will need to open the file in
+ ``rb`` (read binary) mode.
+
+ The ``extra`` argument acts the same as for :meth:`Client.get`.
+
+ .. versionchanged:: 1.1
+
+ If the URL you request with a POST contains encoded parameters, these
+ parameters will be made available in the request.GET data. For example,
+ if you were to make the request::
+
+ >>> c.post('/login/?visitor=true', {'name': 'fred', 'passwd': 'secret'})
+
+ ... the view handling this request could interrogate request.POST
+ to retrieve the username and password, and could interrogate request.GET
+ to determine if the user was a visitor.
+
+ If you set ``follow`` to ``True`` the client will follow any redirects
+ and a ``redirect_chain`` attribute will be set in the response object
+ containing tuples of the intermediate urls and status codes.
+
+ .. method:: Client.head(path, data={}, follow=False, **extra)
+
+ .. versionadded:: 1.1
+
+ Makes a HEAD request on the provided ``path`` and returns a ``Response``
+ object. Useful for testing RESTful interfaces. Acts just like
+ :meth:`Client.get` except it does not return a message body.
+
+ If you set ``follow`` to ``True`` the client will follow any redirects
+ and a ``redirect_chain`` attribute will be set in the response object
+ containing tuples of the intermediate urls and status codes.
+
+ .. method:: Client.options(path, data={}, follow=False, **extra)
+
+ .. versionadded:: 1.1
+
+ Makes an OPTIONS request on the provided ``path`` and returns a
+ ``Response`` object. Useful for testing RESTful interfaces.
+
+ If you set ``follow`` to ``True`` the client will follow any redirects
+ and a ``redirect_chain`` attribute will be set in the response object
+ containing tuples of the intermediate urls and status codes.
+
+ The ``extra`` argument acts the same as for :meth:`Client.get`.
+
+ .. method:: Client.put(path, data={}, content_type=MULTIPART_CONTENT, follow=False, **extra)
+
+ .. versionadded:: 1.1
+
+ Makes a PUT request on the provided ``path`` and returns a
+ ``Response`` object. Useful for testing RESTful interfaces. Acts just
+ like :meth:`Client.post` except with the PUT request method.
+
+ If you set ``follow`` to ``True`` the client will follow any redirects
+ and a ``redirect_chain`` attribute will be set in the response object
+ containing tuples of the intermediate urls and status codes.
+
+ .. method:: Client.delete(path, follow=False, **extra)
+
+ .. versionadded:: 1.1
+
+ Makes an DELETE request on the provided ``path`` and returns a
+ ``Response`` object. Useful for testing RESTful interfaces.
+
+ If you set ``follow`` to ``True`` the client will follow any redirects
+ and a ``redirect_chain`` attribute will be set in the response object
+ containing tuples of the intermediate urls and status codes.
+
+ The ``extra`` argument acts the same as for :meth:`Client.get`.
+
+ .. method:: Client.login(**credentials)
+
+ .. versionadded:: 1.0
+
+ If your site uses Django's :doc:`authentication system</topics/auth>`
+ and you deal with logging in users, you can use the test client's
+ ``login()`` method to simulate the effect of a user logging into the
+ site.
+
+ After you call this method, the test client will have all the cookies
+ and session data required to pass any login-based tests that may form
+ part of a view.
+
+ The format of the ``credentials`` argument depends on which
+ :ref:`authentication backend <authentication-backends>` you're using
+ (which is configured by your :setting:`AUTHENTICATION_BACKENDS`
+ setting). If you're using the standard authentication backend provided
+ by Django (``ModelBackend``), ``credentials`` should be the user's
+ username and password, provided as keyword arguments::
+
+ >>> c = Client()
+ >>> c.login(username='fred', password='secret')
+
+ # Now you can access a view that's only available to logged-in users.
+
+ If you're using a different authentication backend, this method may
+ require different credentials. It requires whichever credentials are
+ required by your backend's ``authenticate()`` method.
+
+ ``login()`` returns ``True`` if it the credentials were accepted and
+ login was successful.
+
+ Finally, you'll need to remember to create user accounts before you can
+ use this method. As we explained above, the test runner is executed
+ using a test database, which contains no users by default. As a result,
+ user accounts that are valid on your production site will not work
+ under test conditions. You'll need to create users as part of the test
+ suite -- either manually (using the Django model API) or with a test
+ fixture. Remember that if you want your test user to have a password,
+ you can't set the user's password by setting the password attribute
+ directly -- you must use the
+ :meth:`~django.contrib.auth.models.User.set_password()` function to
+ store a correctly hashed password. Alternatively, you can use the
+ :meth:`~django.contrib.auth.models.UserManager.create_user` helper
+ method to create a new user with a correctly hashed password.
+
+ .. method:: Client.logout()
+
+ .. versionadded:: 1.0
+
+ If your site uses Django's :doc:`authentication system</topics/auth>`,
+ the ``logout()`` method can be used to simulate the effect of a user
+ logging out of your site.
+
+ After you call this method, the test client will have all the cookies
+ and session data cleared to defaults. Subsequent requests will appear
+ to come from an AnonymousUser.
+
+Testing responses
+~~~~~~~~~~~~~~~~~
+
+The ``get()`` and ``post()`` methods both return a ``Response`` object. This
+``Response`` object is *not* the same as the ``HttpResponse`` object returned
+Django views; the test response object has some additional data useful for
+test code to verify.
+
+Specifically, a ``Response`` object has the following attributes:
+
+.. class:: Response()
+
+ .. attribute:: client
+
+ The test client that was used to make the request that resulted in the
+ response.
+
+ .. attribute:: content
+
+ The body of the response, as a string. This is the final page content as
+ rendered by the view, or any error message.
+
+ .. attribute:: context
+
+ The template ``Context`` instance that was used to render the template that
+ produced the response content.
+
+ If the rendered page used multiple templates, then ``context`` will be a
+ list of ``Context`` objects, in the order in which they were rendered.
+
+ .. versionadded:: 1.1
+
+ Regardless of the number of templates used during rendering, you can
+ retrieve context values using the ``[]`` operator. For example, the
+ context variable ``name`` could be retrieved using::
+
+ >>> response = client.get('/foo/')
+ >>> response.context['name']
+ 'Arthur'
+
+ .. attribute:: request
+
+ The request data that stimulated the response.
+
+ .. attribute:: status_code
+
+ The HTTP status of the response, as an integer. See RFC2616_ for a full
+ list of HTTP status codes.
+
+ .. attribute:: template
+
+ The ``Template`` instance that was used to render the final content. Use
+ ``template.name`` to get the template's file name, if the template was
+ loaded from a file. (The name is a string such as ``'admin/index.html'``.)
+
+ If the rendered page used multiple templates -- e.g., using :ref:`template
+ inheritance<template-inheritance>` -- then ``template`` will be a list of
+ ``Template`` instances, in the order in which they were rendered.
+
+You can also use dictionary syntax on the response object to query the value
+of any settings in the HTTP headers. For example, you could determine the
+content type of a response using ``response['Content-Type']``.
+
+.. _RFC2616: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
+
+Exceptions
+~~~~~~~~~~
+
+If you point the test client at a view that raises an exception, that exception
+will be visible in the test case. You can then use a standard ``try...except``
+block or ``unittest.TestCase.assertRaises()`` to test for exceptions.
+
+The only exceptions that are not visible to the test client are ``Http404``,
+``PermissionDenied`` and ``SystemExit``. Django catches these exceptions
+internally and converts them into the appropriate HTTP response codes. In these
+cases, you can check ``response.status_code`` in your test.
+
+Persistent state
+~~~~~~~~~~~~~~~~
+
+The test client is stateful. If a response returns a cookie, then that cookie
+will be stored in the test client and sent with all subsequent ``get()`` and
+``post()`` requests.
+
+Expiration policies for these cookies are not followed. If you want a cookie
+to expire, either delete it manually or create a new ``Client`` instance (which
+will effectively delete all cookies).
+
+A test client has two attributes that store persistent state information. You
+can access these properties as part of a test condition.
+
+.. attribute:: Client.cookies
+
+ A Python ``SimpleCookie`` object, containing the current values of all the
+ client cookies. See the `Cookie module documentation`_ for more.
+
+.. attribute:: Client.session
+
+ A dictionary-like object containing session information. See the
+ :doc:`session documentation</topics/http/sessions>` for full details.
+
+ To modify the session and then save it, it must be stored in a variable
+ first (because a new ``SessionStore`` is created every time this property
+ is accessed)::
+
+ def test_something(self):
+ session = self.client.session
+ session['somekey'] = 'test'
+ session.save()
+
+.. _Cookie module documentation: http://docs.python.org/library/cookie.html
+
+Example
+~~~~~~~
+
+The following is a simple unit test using the test client::
+
+ import unittest
+ from django.test.client import Client
+
+ class SimpleTest(unittest.TestCase):
+ def setUp(self):
+ # Every test needs a client.
+ self.client = Client()
+
+ def test_details(self):
+ # Issue a GET request.
+ response = self.client.get('/customer/details/')
+
+ # Check that the response is 200 OK.
+ self.failUnlessEqual(response.status_code, 200)
+
+ # Check that the rendered context contains 5 customers.
+ self.failUnlessEqual(len(response.context['customers']), 5)
+
+TestCase
+--------
+
+.. currentmodule:: django.test
+
+Normal Python unit test classes extend a base class of ``unittest.TestCase``.
+Django provides an extension of this base class:
+
+.. class:: TestCase()
+
+This class provides some additional capabilities that can be useful for testing
+Web sites.
+
+Converting a normal ``unittest.TestCase`` to a Django ``TestCase`` is easy:
+just change the base class of your test from ``unittest.TestCase`` to
+``django.test.TestCase``. All of the standard Python unit test functionality
+will continue to be available, but it will be augmented with some useful
+additions.
+
+.. versionadded:: 1.1
+
+.. class:: TransactionTestCase()
+
+Django ``TestCase`` classes make use of database transaction facilities, if
+available, to speed up the process of resetting the database to a known state
+at the beginning of each test. A consequence of this, however, is that the
+effects of transaction commit and rollback cannot be tested by a Django
+``TestCase`` class. If your test requires testing of such transactional
+behavior, you should use a Django ``TransactionTestCase``.
+
+``TransactionTestCase`` and ``TestCase`` are identical except for the manner
+in which the database is reset to a known state and the ability for test code
+to test the effects of commit and rollback. A ``TransactionTestCase`` resets
+the database before the test runs by truncating all tables and reloading
+initial data. A ``TransactionTestCase`` may call commit and rollback and
+observe the effects of these calls on the database.
+
+A ``TestCase``, on the other hand, does not truncate tables and reload initial
+data at the beginning of a test. Instead, it encloses the test code in a
+database transaction that is rolled back at the end of the test. It also
+prevents the code under test from issuing any commit or rollback operations
+on the database, to ensure that the rollback at the end of the test restores
+the database to its initial state. In order to guarantee that all ``TestCase``
+code starts with a clean database, the Django test runner runs all ``TestCase``
+tests first, before any other tests (e.g. doctests) that may alter the
+database without restoring it to its original state.
+
+When running on a database that does not support rollback (e.g. MySQL with the
+MyISAM storage engine), ``TestCase`` falls back to initializing the database
+by truncating tables and reloading initial data.
+
+
+.. note::
+ The ``TestCase`` use of rollback to un-do the effects of the test code
+ may reveal previously-undetected errors in test code. For example,
+ test code that assumes primary keys values will be assigned starting at
+ one may find that assumption no longer holds true when rollbacks instead
+ of table truncation are being used to reset the database. Similarly,
+ the reordering of tests so that all ``TestCase`` classes run first may
+ reveal unexpected dependencies on test case ordering. In such cases a
+ quick fix is to switch the ``TestCase`` to a ``TransactionTestCase``.
+ A better long-term fix, that allows the test to take advantage of the
+ speed benefit of ``TestCase``, is to fix the underlying test problem.
+
+
+Default test client
+~~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.0
+
+.. attribute:: TestCase.client
+
+Every test case in a ``django.test.TestCase`` instance has access to an
+instance of a Django test client. This client can be accessed as
+``self.client``. This client is recreated for each test, so you don't have to
+worry about state (such as cookies) carrying over from one test to another.
+
+This means, instead of instantiating a ``Client`` in each test::
+
+ import unittest
+ from django.test.client import Client
+
+ class SimpleTest(unittest.TestCase):
+ def test_details(self):
+ client = Client()
+ response = client.get('/customer/details/')
+ self.failUnlessEqual(response.status_code, 200)
+
+ def test_index(self):
+ client = Client()
+ response = client.get('/customer/index/')
+ self.failUnlessEqual(response.status_code, 200)
+
+...you can just refer to ``self.client``, like so::
+
+ from django.test import TestCase
+
+ class SimpleTest(TestCase):
+ def test_details(self):
+ response = self.client.get('/customer/details/')
+ self.failUnlessEqual(response.status_code, 200)
+
+ def test_index(self):
+ response = self.client.get('/customer/index/')
+ self.failUnlessEqual(response.status_code, 200)
+
+.. _topics-testing-fixtures:
+
+Fixture loading
+~~~~~~~~~~~~~~~
+
+.. attribute:: TestCase.fixtures
+
+A test case for a database-backed Web site isn't much use if there isn't any
+data in the database. To make it easy to put test data into the database,
+Django's custom ``TestCase`` class provides a way of loading **fixtures**.
+
+A fixture is a collection of data that Django knows how to import into a
+database. For example, if your site has user accounts, you might set up a
+fixture of fake user accounts in order to populate your database during tests.
+
+The most straightforward way of creating a fixture is to use the
+:djadmin:`manage.py dumpdata <dumpdata>` command. This assumes you
+already have some data in your database. See the :djadmin:`dumpdata
+documentation<dumpdata>` for more details.
+
+.. note::
+ If you've ever run :djadmin:`manage.py syncdb<syncdb>`, you've
+ already used a fixture without even knowing it! When you call
+ :djadmin:`syncdb` in the database for the first time, Django
+ installs a fixture called ``initial_data``. This gives you a way
+ of populating a new database with any initial data, such as a
+ default set of categories.
+
+ Fixtures with other names can always be installed manually using
+ the :djadmin:`manage.py loaddata<loaddata>` command.
+
+Once you've created a fixture and placed it in a ``fixtures`` directory in one
+of your :setting:`INSTALLED_APPS`, you can use it in your unit tests by
+specifying a ``fixtures`` class attribute on your :class:`django.test.TestCase`
+subclass::
+
+ from django.test import TestCase
+ from myapp.models import Animal
+
+ class AnimalTestCase(TestCase):
+ fixtures = ['mammals.json', 'birds']
+
+ def setUp(self):
+ # Test definitions as before.
+ call_setup_methods()
+
+ def testFluffyAnimals(self):
+ # A test that uses the fixtures.
+ call_some_test_code()
+
+Here's specifically what will happen:
+
+ * At the start of each test case, before ``setUp()`` is run, Django will
+ flush the database, returning the database to the state it was in
+ directly after :djadmin:`syncdb` was called.
+
+ * Then, all the named fixtures are installed. In this example, Django will
+ install any JSON fixture named ``mammals``, followed by any fixture named
+ ``birds``. See the :djadmin:`loaddata` documentation for more
+ details on defining and installing fixtures.
+
+This flush/load procedure is repeated for each test in the test case, so you
+can be certain that the outcome of a test will not be affected by another test,
+or by the order of test execution.
+
+URLconf configuration
+~~~~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.0
+
+.. attribute:: TestCase.urls
+
+If your application provides views, you may want to include tests that use the
+test client to exercise those views. However, an end user is free to deploy the
+views in your application at any URL of their choosing. This means that your
+tests can't rely upon the fact that your views will be available at a
+particular URL.
+
+In order to provide a reliable URL space for your test,
+``django.test.TestCase`` provides the ability to customize the URLconf
+configuration for the duration of the execution of a test suite. If your
+``TestCase`` instance defines an ``urls`` attribute, the ``TestCase`` will use
+the value of that attribute as the ``ROOT_URLCONF`` for the duration of that
+test.
+
+For example::
+
+ from django.test import TestCase
+
+ class TestMyViews(TestCase):
+ urls = 'myapp.test_urls'
+
+ def testIndexPageView(self):
+ # Here you'd test your view using ``Client``.
+ call_some_test_code()
+
+This test case will use the contents of ``myapp.test_urls`` as the
+URLconf for the duration of the test case.
+
+.. _emptying-test-outbox:
+
+Multi-database support
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. attribute:: TestCase.multi_db
+
+.. versionadded:: 1.2
+
+Django sets up a test database corresponding to every database that is
+defined in the :setting:`DATABASES` definition in your settings
+file. However, a big part of the time taken to run a Django TestCase
+is consumed by the call to ``flush`` that ensures that you have a
+clean database at the start of each test run. If you have multiple
+databases, multiple flushes are required (one for each database),
+which can be a time consuming activity -- especially if your tests
+don't need to test multi-database activity.
+
+As an optimization, Django only flushes the ``default`` database at
+the start of each test run. If your setup contains multiple databases,
+and you have a test that requires every database to be clean, you can
+use the ``multi_db`` attribute on the test suite to request a full
+flush.
+
+For example::
+
+ class TestMyViews(TestCase):
+ multi_db = True
+
+ def testIndexPageView(self):
+ call_some_test_code()
+
+This test case will flush *all* the test databases before running
+``testIndexPageView``.
+
+Emptying the test outbox
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.0
+
+If you use Django's custom ``TestCase`` class, the test runner will clear the
+contents of the test e-mail outbox at the start of each test case.
+
+For more detail on e-mail services during tests, see `E-mail services`_.
+
+Assertions
+~~~~~~~~~~
+
+.. versionadded:: 1.0
+
+.. versionchanged:: 1.2
+ Addded ``msg_prefix`` argument.
+
+As Python's normal ``unittest.TestCase`` class implements assertion methods
+such as ``assertTrue`` and ``assertEquals``, Django's custom ``TestCase`` class
+provides a number of custom assertion methods that are useful for testing Web
+applications:
+
+The failure messages given by the assertion methods can be customized
+with the ``msg_prefix`` argument. This string will be prefixed to any
+failure message generated by the assertion. This allows you to provide
+additional details that may help you to identify the location and
+cause of an failure in your test suite.
+
+.. method:: TestCase.assertContains(response, text, count=None, status_code=200, msg_prefix='')
+
+ Asserts that a ``Response`` instance produced the given ``status_code`` and
+ that ``text`` appears in the content of the response. If ``count`` is
+ provided, ``text`` must occur exactly ``count`` times in the response.
+
+.. method:: TestCase.assertNotContains(response, text, status_code=200, msg_prefix='')
+
+ Asserts that a ``Response`` instance produced the given ``status_code`` and
+ that ``text`` does not appears in the content of the response.
+
+.. method:: TestCase.assertFormError(response, form, field, errors, msg_prefix='')
+
+ Asserts that a field on a form raises the provided list of errors when
+ rendered on the form.
+
+ ``form`` is the name the ``Form`` instance was given in the template
+ context.
+
+ ``field`` is the name of the field on the form to check. If ``field``
+ has a value of ``None``, non-field errors (errors you can access via
+ ``form.non_field_errors()``) will be checked.
+
+ ``errors`` is an error string, or a list of error strings, that are
+ expected as a result of form validation.
+
+.. method:: TestCase.assertTemplateUsed(response, template_name, msg_prefix='')
+
+ Asserts that the template with the given name was used in rendering the
+ response.
+
+ The name is a string such as ``'admin/index.html'``.
+
+.. method:: TestCase.assertTemplateNotUsed(response, template_name, msg_prefix='')
+
+ Asserts that the template with the given name was *not* used in rendering
+ the response.
+
+.. method:: TestCase.assertRedirects(response, expected_url, status_code=302, target_status_code=200, msg_prefix='')
+
+ Asserts that the response return a ``status_code`` redirect status, it
+ redirected to ``expected_url`` (including any GET data), and the final
+ page was received with ``target_status_code``.
+
+ .. versionadded:: 1.1
+
+ If your request used the ``follow`` argument, the ``expected_url`` and
+ ``target_status_code`` will be the url and status code for the final
+ point of the redirect chain.
+
+.. _topics-testing-email:
+
+E-mail services
+---------------
+
+.. versionadded:: 1.0
+
+If any of your Django views send e-mail using :doc:`Django's e-mail
+functionality </topics/email>`, you probably don't want to send e-mail each time
+you run a test using that view. For this reason, Django's test runner
+automatically redirects all Django-sent e-mail to a dummy outbox. This lets you
+test every aspect of sending e-mail -- from the number of messages sent to the
+contents of each message -- without actually sending the messages.
+
+The test runner accomplishes this by transparently replacing the normal
+email backend with a testing backend.
+(Don't worry -- this has no effect on any other e-mail senders outside of
+Django, such as your machine's mail server, if you're running one.)
+
+.. currentmodule:: django.core.mail
+
+.. data:: django.core.mail.outbox
+
+During test running, each outgoing e-mail is saved in
+``django.core.mail.outbox``. This is a simple list of all
+:class:`~django.core.mail.EmailMessage` instances that have been sent.
+The ``outbox`` attribute is a special attribute that is created *only* when
+the ``locmem`` e-mail backend is used. It doesn't normally exist as part of the
+:mod:`django.core.mail` module and you can't import it directly. The code
+below shows how to access this attribute correctly.
+
+Here's an example test that examines ``django.core.mail.outbox`` for length
+and contents::
+
+ from django.core import mail
+ from django.test import TestCase
+
+ class EmailTest(TestCase):
+ def test_send_email(self):
+ # Send message.
+ mail.send_mail('Subject here', 'Here is the message.',
+ 'from@example.com', ['to@example.com'],
+ fail_silently=False)
+
+ # Test that one message has been sent.
+ self.assertEquals(len(mail.outbox), 1)
+
+ # Verify that the subject of the first message is correct.
+ self.assertEquals(mail.outbox[0].subject, 'Subject here')
+
+As noted :ref:`previously <emptying-test-outbox>`, the test outbox is emptied
+at the start of every test in a Django ``TestCase``. To empty the outbox
+manually, assign the empty list to ``mail.outbox``::
+
+ from django.core import mail
+
+ # Empty the test outbox
+ mail.outbox = []
+
+Using different testing frameworks
+==================================
+
+Clearly, ``doctest`` and ``unittest`` are not the only Python testing
+frameworks. While Django doesn't provide explicit support for alternative
+frameworks, it does provide a way to invoke tests constructed for an
+alternative framework as if they were normal Django tests.
+
+When you run ``./manage.py test``, Django looks at the :setting:`TEST_RUNNER`
+setting to determine what to do. By default, :setting:`TEST_RUNNER` points to
+``'django.test.simple.DjangoTestSuiteRunner'``. This class defines the default Django
+testing behavior. This behavior involves:
+
+ #. Performing global pre-test setup.
+
+ #. Looking for unit tests and doctests in the ``models.py`` and
+ ``tests.py`` files in each installed application.
+
+ #. Creating the test databases.
+
+ #. Running ``syncdb`` to install models and initial data into the test
+ databases.
+
+ #. Running the unit tests and doctests that are found.
+
+ #. Destroying the test databases.
+
+ #. Performing global post-test teardown.
+
+If you define your own test runner class and point :setting:`TEST_RUNNER` at
+that class, Django will execute your test runner whenever you run
+``./manage.py test``. In this way, it is possible to use any test framework
+that can be executed from Python code, or to modify the Django test execution
+process to satisfy whatever testing requirements you may have.
+
+.. _topics-testing-test_runner:
+
+Defining a test runner
+----------------------
+
+.. versionchanged:: 1.2
+ Prior to 1.2, test runners were a single function, not a class.
+
+.. currentmodule:: django.test.simple
+
+A test runner is a class defining a ``run_tests()`` method. Django ships
+with a ``DjangoTestSuiteRunner`` class that defines the default Django
+testing behavior. This class defines the ``run_tests()`` entry point,
+plus a selection of other methods that are used to by ``run_tests()`` to
+set up, execute and tear down the test suite.
+
+.. class:: DjangoTestSuiteRunner(verbosity=1, interactive=True, failfast=True, **kwargs)
+
+ ``verbosity`` determines the amount of notification and debug information
+ that will be printed to the console; ``0`` is no output, ``1`` is normal
+ output, and ``2`` is verbose output.
+
+ If ``interactive`` is ``True``, the test suite has permission to ask the
+ user for instructions when the test suite is executed. An example of this
+ behavior would be asking for permission to delete an existing test
+ database. If ``interactive`` is ``False``, the test suite must be able to
+ run without any manual intervention.
+
+ If ``failfast`` is ``True``, the test suite will stop running after the
+ first test failure is detected.
+
+ Django will, from time to time, extend the capabilities of
+ the test runner by adding new arguments. The ``**kwargs`` declaration
+ allows for this expansion. If you subclass ``DjangoTestSuiteRunner`` or
+ write your own test runner, ensure accept and handle the ``**kwargs``
+ parameter.
+
+.. method:: DjangoTestSuiteRunner.run_tests(test_labels, extra_tests=None, **kwargs)
+
+ Run the test suite.
+
+ ``test_labels`` is a list of strings describing the tests to be run. A test
+ label can take one of three forms:
+
+ * ``app.TestCase.test_method`` -- Run a single test method in a test
+ case.
+ * ``app.TestCase`` -- Run all the test methods in a test case.
+ * ``app`` -- Search for and run all tests in the named application.
+
+ If ``test_labels`` has a value of ``None``, the test runner should run
+ search for tests in all the applications in :setting:`INSTALLED_APPS`.
+
+ ``extra_tests`` is a list of extra ``TestCase`` instances to add to the
+ suite that is executed by the test runner. These extra tests are run
+ in addition to those discovered in the modules listed in ``test_labels``.
+
+ This method should return the number of tests that failed.
+
+.. method:: DjangoTestSuiteRunner.setup_test_environment(**kwargs)
+
+ Sets up the test environment ready for testing.
+
+.. method:: DjangoTestSuiteRunner.build_suite(test_labels, extra_tests=None, **kwargs)
+
+ Constructs a test suite that matches the test labels provided.
+
+ ``test_labels`` is a list of strings describing the tests to be run. A test
+ label can take one of three forms:
+
+ * ``app.TestCase.test_method`` -- Run a single test method in a test
+ case.
+ * ``app.TestCase`` -- Run all the test methods in a test case.
+ * ``app`` -- Search for and run all tests in the named application.
+
+ If ``test_labels`` has a value of ``None``, the test runner should run
+ search for tests in all the applications in :setting:`INSTALLED_APPS`.
+
+ ``extra_tests`` is a list of extra ``TestCase`` instances to add to the
+ suite that is executed by the test runner. These extra tests are run
+ in addition to those discovered in the modules listed in ``test_labels``.
+
+ Returns a ``TestSuite`` instance ready to be run.
+
+.. method:: DjangoTestSuiteRunner.setup_databases(**kwargs)
+
+ Creates the test databases.
+
+ Returns a data structure that provides enough detail to undo the changes
+ that have been made. This data will be provided to the ``teardown_databases()``
+ function at the conclusion of testing.
+
+.. method:: DjangoTestSuiteRunner.run_suite(suite, **kwargs)
+
+ Runs the test suite.
+
+ Returns the result produced by the running the test suite.
+
+.. method:: DjangoTestSuiteRunner.teardown_databases(old_config, **kwargs)
+
+ Destroys the test databases, restoring pre-test conditions.
+
+ ``old_config`` is a data structure defining the changes in the
+ database configuration that need to be reversed. It is the return
+ value of the ``setup_databases()`` method.
+
+.. method:: DjangoTestSuiteRunner.teardown_test_environment(**kwargs)
+
+ Restores the pre-test environment.
+
+.. method:: DjangoTestSuiteRunner.suite_result(suite, result, **kwargs)
+
+ Computes and returns a return code based on a test suite, and the result
+ from that test suite.
+
+
+Testing utilities
+-----------------
+
+.. module:: django.test.utils
+ :synopsis: Helpers to write custom test runners.
+
+To assist in the creation of your own test runner, Django provides a number of
+utility methods in the ``django.test.utils`` module.
+
+.. function:: setup_test_environment()
+
+ Performs any global pre-test setup, such as the installing the
+ instrumentation of the template rendering system and setting up
+ the dummy ``SMTPConnection``.
+
+.. function:: teardown_test_environment()
+
+ Performs any global post-test teardown, such as removing the black
+ magic hooks into the template system and restoring normal e-mail
+ services.
+
+The creation module of the database backend (``connection.creation``)
+also provides some utilities that can be useful during testing.
+
+.. function:: create_test_db(verbosity=1, autoclobber=False)
+
+ Creates a new test database and runs ``syncdb`` against it.
+
+ ``verbosity`` has the same behavior as in ``run_tests()``.
+
+ ``autoclobber`` describes the behavior that will occur if a
+ database with the same name as the test database is discovered:
+
+ * If ``autoclobber`` is ``False``, the user will be asked to
+ approve destroying the existing database. ``sys.exit`` is
+ called if the user does not approve.
+
+ * If autoclobber is ``True``, the database will be destroyed
+ without consulting the user.
+
+ Returns the name of the test database that it created.
+
+ ``create_test_db()`` has the side effect of modifying the value of
+ :setting:`NAME` in :setting:`DATABASES` to match the name of the test
+ database.
+
+ .. versionchanged:: 1.0
+ ``create_test_db()`` now returns the name of the test database.
+
+.. function:: destroy_test_db(old_database_name, verbosity=1)
+
+ Destroys the database whose name is in stored in :setting:`NAME` in the
+ :setting:`DATABASES`, and sets :setting:`NAME` to use the
+ provided name.
+
+ ``verbosity`` has the same behavior as in ``run_tests()``.