summaryrefslogtreecommitdiff
path: root/parts/django/docs/howto
diff options
context:
space:
mode:
authorNishanth Amuluru2011-01-08 11:20:57 +0530
committerNishanth Amuluru2011-01-08 11:20:57 +0530
commit65411d01d448ff0cd4abd14eee14cf60b5f8fc20 (patch)
treeb4c404363c4c63a61d6e2f8bd26c5b057c1fb09d /parts/django/docs/howto
parent2e35094d43b4cc6974172e1febf76abb50f086ec (diff)
downloadpytask-65411d01d448ff0cd4abd14eee14cf60b5f8fc20.tar.gz
pytask-65411d01d448ff0cd4abd14eee14cf60b5f8fc20.tar.bz2
pytask-65411d01d448ff0cd4abd14eee14cf60b5f8fc20.zip
Added buildout stuff and made changes accordingly
--HG-- rename : profile/management/__init__.py => eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/dependency_links.txt rename : profile/management/__init__.py => eggs/djangorecipe-0.20-py2.6.egg/EGG-INFO/not-zip-safe rename : profile/management/__init__.py => eggs/infrae.subversion-1.4.5-py2.6.egg/EGG-INFO/dependency_links.txt rename : profile/management/__init__.py => eggs/infrae.subversion-1.4.5-py2.6.egg/EGG-INFO/not-zip-safe rename : profile/management/__init__.py => eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/EGG-INFO/dependency_links.txt rename : profile/management/__init__.py => eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/EGG-INFO/not-zip-safe rename : profile/management/__init__.py => eggs/py-1.4.0-py2.6.egg/EGG-INFO/dependency_links.txt rename : profile/management/__init__.py => eggs/py-1.4.0-py2.6.egg/EGG-INFO/not-zip-safe rename : profile/management/__init__.py => eggs/zc.buildout-1.5.2-py2.6.egg/EGG-INFO/dependency_links.txt rename : profile/management/__init__.py => eggs/zc.buildout-1.5.2-py2.6.egg/EGG-INFO/not-zip-safe rename : profile/management/__init__.py => eggs/zc.recipe.egg-1.3.2-py2.6.egg/EGG-INFO/dependency_links.txt rename : profile/management/__init__.py => eggs/zc.recipe.egg-1.3.2-py2.6.egg/EGG-INFO/not-zip-safe rename : profile/management/__init__.py => parts/django/Django.egg-info/dependency_links.txt rename : taskapp/models.py => parts/django/django/conf/app_template/models.py rename : taskapp/tests.py => parts/django/django/conf/app_template/tests.py rename : taskapp/views.py => parts/django/django/conf/app_template/views.py rename : taskapp/views.py => parts/django/django/contrib/gis/tests/geo3d/views.py rename : profile/management/__init__.py => parts/django/tests/modeltests/delete/__init__.py rename : profile/management/__init__.py => parts/django/tests/modeltests/files/__init__.py rename : profile/management/__init__.py => parts/django/tests/modeltests/invalid_models/__init__.py rename : profile/management/__init__.py => parts/django/tests/modeltests/m2m_signals/__init__.py rename : profile/management/__init__.py => parts/django/tests/modeltests/model_package/__init__.py rename : profile/management/__init__.py => parts/django/tests/regressiontests/bash_completion/__init__.py rename : profile/management/__init__.py => parts/django/tests/regressiontests/bash_completion/management/__init__.py rename : profile/management/__init__.py => parts/django/tests/regressiontests/bash_completion/management/commands/__init__.py rename : profile/management/__init__.py => parts/django/tests/regressiontests/bash_completion/models.py rename : profile/management/__init__.py => parts/django/tests/regressiontests/delete_regress/__init__.py rename : profile/management/__init__.py => parts/django/tests/regressiontests/file_storage/__init__.py rename : profile/management/__init__.py => parts/django/tests/regressiontests/max_lengths/__init__.py rename : profile/forms.py => pytask/profile/forms.py rename : profile/management/__init__.py => pytask/profile/management/__init__.py rename : profile/management/commands/seed_db.py => pytask/profile/management/commands/seed_db.py rename : profile/models.py => pytask/profile/models.py rename : profile/templatetags/user_tags.py => pytask/profile/templatetags/user_tags.py rename : taskapp/tests.py => pytask/profile/tests.py rename : profile/urls.py => pytask/profile/urls.py rename : profile/utils.py => pytask/profile/utils.py rename : profile/views.py => pytask/profile/views.py rename : static/css/base.css => pytask/static/css/base.css rename : taskapp/tests.py => pytask/taskapp/tests.py rename : taskapp/views.py => pytask/taskapp/views.py rename : templates/base.html => pytask/templates/base.html rename : templates/profile/browse_notifications.html => pytask/templates/profile/browse_notifications.html rename : templates/profile/edit.html => pytask/templates/profile/edit.html rename : templates/profile/view.html => pytask/templates/profile/view.html rename : templates/profile/view_notification.html => pytask/templates/profile/view_notification.html rename : templates/registration/activate.html => pytask/templates/registration/activate.html rename : templates/registration/activation_email.txt => pytask/templates/registration/activation_email.txt rename : templates/registration/activation_email_subject.txt => pytask/templates/registration/activation_email_subject.txt rename : templates/registration/logged_out.html => pytask/templates/registration/logged_out.html rename : templates/registration/login.html => pytask/templates/registration/login.html rename : templates/registration/logout.html => pytask/templates/registration/logout.html rename : templates/registration/password_change_done.html => pytask/templates/registration/password_change_done.html rename : templates/registration/password_change_form.html => pytask/templates/registration/password_change_form.html rename : templates/registration/password_reset_complete.html => pytask/templates/registration/password_reset_complete.html rename : templates/registration/password_reset_confirm.html => pytask/templates/registration/password_reset_confirm.html rename : templates/registration/password_reset_done.html => pytask/templates/registration/password_reset_done.html rename : templates/registration/password_reset_email.html => pytask/templates/registration/password_reset_email.html rename : templates/registration/password_reset_form.html => pytask/templates/registration/password_reset_form.html rename : templates/registration/registration_complete.html => pytask/templates/registration/registration_complete.html rename : templates/registration/registration_form.html => pytask/templates/registration/registration_form.html rename : utils.py => pytask/utils.py
Diffstat (limited to 'parts/django/docs/howto')
-rw-r--r--parts/django/docs/howto/apache-auth.txt120
-rw-r--r--parts/django/docs/howto/auth-remote-user.txt100
-rw-r--r--parts/django/docs/howto/custom-file-storage.txt90
-rw-r--r--parts/django/docs/howto/custom-management-commands.txt253
-rw-r--r--parts/django/docs/howto/custom-model-fields.txt745
-rw-r--r--parts/django/docs/howto/custom-template-tags.txt939
-rw-r--r--parts/django/docs/howto/deployment/fastcgi.txt400
-rw-r--r--parts/django/docs/howto/deployment/index.txt25
-rw-r--r--parts/django/docs/howto/deployment/modpython.txt418
-rw-r--r--parts/django/docs/howto/deployment/modwsgi.txt118
-rw-r--r--parts/django/docs/howto/error-reporting.txt78
-rw-r--r--parts/django/docs/howto/i18n.txt103
-rw-r--r--parts/django/docs/howto/index.txt34
-rw-r--r--parts/django/docs/howto/initial-data.txt142
-rw-r--r--parts/django/docs/howto/jython.txt73
-rw-r--r--parts/django/docs/howto/legacy-databases.txt66
-rw-r--r--parts/django/docs/howto/outputting-csv.txt137
-rw-r--r--parts/django/docs/howto/outputting-pdf.txt160
-rw-r--r--parts/django/docs/howto/static-files.txt162
19 files changed, 4163 insertions, 0 deletions
diff --git a/parts/django/docs/howto/apache-auth.txt b/parts/django/docs/howto/apache-auth.txt
new file mode 100644
index 0000000..2ebae0b
--- /dev/null
+++ b/parts/django/docs/howto/apache-auth.txt
@@ -0,0 +1,120 @@
+=========================================================
+Authenticating against Django's user database from Apache
+=========================================================
+
+Since keeping multiple authentication databases in sync is a common problem when
+dealing with Apache, you can configuring Apache to authenticate against Django's
+:doc:`authentication system </topics/auth>` directly. For example, you
+could:
+
+ * Serve static/media files directly from Apache only to authenticated users.
+
+ * Authenticate access to a Subversion_ repository against Django users with
+ a certain permission.
+
+ * Allow certain users to connect to a WebDAV share created with mod_dav_.
+
+.. _Subversion: http://subversion.tigris.org/
+.. _mod_dav: http://httpd.apache.org/docs/2.0/mod/mod_dav.html
+
+Configuring Apache
+==================
+
+To check against Django's authorization database from a Apache configuration
+file, you'll need to use mod_python's ``PythonAuthenHandler`` directive along
+with the standard ``Auth*`` and ``Require`` directives:
+
+.. code-block:: apache
+
+ <Location /example/>
+ AuthType Basic
+ AuthName "example.com"
+ Require valid-user
+
+ SetEnv DJANGO_SETTINGS_MODULE mysite.settings
+ PythonAuthenHandler django.contrib.auth.handlers.modpython
+ </Location>
+
+.. admonition:: Using the authentication handler with Apache 2.2
+
+ If you're using Apache 2.2, you'll need to take a couple extra steps.
+
+ You'll need to ensure that ``mod_auth_basic`` and ``mod_authz_user``
+ are loaded. These might be compiled statically into Apache, or you might
+ need to use ``LoadModule`` to load them dynamically (as shown in the
+ example at the bottom of this note).
+
+ You'll also need to insert configuration directives that prevent Apache
+ from trying to use other authentication modules, as well as specifying
+ the ``AuthUserFile`` directive and pointing it to ``/dev/null``. Depending
+ on which other authentication modules you have loaded, you might need one
+ or more of the following directives:
+
+ .. code-block:: apache
+
+ AuthBasicAuthoritative Off
+ AuthDefaultAuthoritative Off
+ AuthzLDAPAuthoritative Off
+ AuthzDBMAuthoritative Off
+ AuthzDefaultAuthoritative Off
+ AuthzGroupFileAuthoritative Off
+ AuthzOwnerAuthoritative Off
+ AuthzUserAuthoritative Off
+
+ A complete configuration, with differences between Apache 2.0 and
+ Apache 2.2 marked in bold, would look something like:
+
+ .. parsed-literal::
+
+ **LoadModule auth_basic_module modules/mod_auth_basic.so**
+ **LoadModule authz_user_module modules/mod_authz_user.so**
+
+ ...
+
+ <Location /example/>
+ AuthType Basic
+ AuthName "example.com"
+ **AuthUserFile /dev/null**
+ **AuthBasicAuthoritative Off**
+ Require valid-user
+
+ SetEnv DJANGO_SETTINGS_MODULE mysite.settings
+ PythonAuthenHandler django.contrib.auth.handlers.modpython
+ </Location>
+
+By default, the authentication handler will limit access to the ``/example/``
+location to users marked as staff members. You can use a set of
+``PythonOption`` directives to modify this behavior:
+
+ ================================ =========================================
+ ``PythonOption`` Explanation
+ ================================ =========================================
+ ``DjangoRequireStaffStatus`` If set to ``on`` only "staff" users (i.e.
+ those with the ``is_staff`` flag set)
+ will be allowed.
+
+ Defaults to ``on``.
+
+ ``DjangoRequireSuperuserStatus`` If set to ``on`` only superusers (i.e.
+ those with the ``is_superuser`` flag set)
+ will be allowed.
+
+ Defaults to ``off``.
+
+ ``DjangoPermissionName`` The name of a permission to require for
+ access. See :ref:`custom permissions
+ <custom-permissions>` for more
+ information.
+
+ By default no specific permission will be
+ required.
+ ================================ =========================================
+
+Note that sometimes ``SetEnv`` doesn't play well in this mod_python
+configuration, for reasons unknown. If you're having problems getting
+mod_python to recognize your ``DJANGO_SETTINGS_MODULE``, you can set it using
+``PythonOption`` instead of ``SetEnv``. Therefore, these two Apache directives
+are equivalent::
+
+ SetEnv DJANGO_SETTINGS_MODULE mysite.settings
+ PythonOption DJANGO_SETTINGS_MODULE mysite.settings
diff --git a/parts/django/docs/howto/auth-remote-user.txt b/parts/django/docs/howto/auth-remote-user.txt
new file mode 100644
index 0000000..deab794
--- /dev/null
+++ b/parts/django/docs/howto/auth-remote-user.txt
@@ -0,0 +1,100 @@
+====================================
+Authentication using ``REMOTE_USER``
+====================================
+
+.. currentmodule:: django.contrib.auth.backends
+
+This document describes how to make use of external authentication sources
+(where the Web server sets the ``REMOTE_USER`` environment variable) in your
+Django applications. This type of authentication solution is typically seen on
+intranet sites, with single sign-on solutions such as IIS and Integrated
+Windows Authentication or Apache and `mod_authnz_ldap`_, `CAS`_, `Cosign`_,
+`WebAuth`_, `mod_auth_sspi`_, etc.
+
+.. _mod_authnz_ldap: http://httpd.apache.org/docs/2.2/mod/mod_authnz_ldap.html
+.. _CAS: http://www.jasig.org/cas
+.. _Cosign: http://weblogin.org
+.. _WebAuth: http://www.stanford.edu/services/webauth/
+.. _mod_auth_sspi: http://sourceforge.net/projects/mod-auth-sspi
+
+When the Web server takes care of authentication it typically sets the
+``REMOTE_USER`` environment variable for use in the underlying application. In
+Django, ``REMOTE_USER`` is made available in the :attr:`request.META
+<django.http.HttpRequest.META>` attribute. Django can be configured to make
+use of the ``REMOTE_USER`` value using the ``RemoteUserMiddleware`` and
+``RemoteUserBackend`` classes found in :mod:`django.contrib.auth`.
+
+Configuration
+=============
+
+First, you must add the
+:class:`django.contrib.auth.middleware.RemoteUserMiddleware` to the
+:setting:`MIDDLEWARE_CLASSES` setting **after** the
+:class:`django.contrib.auth.middleware.AuthenticationMiddleware`::
+
+ MIDDLEWARE_CLASSES = (
+ ...
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.auth.middleware.RemoteUserMiddleware',
+ ...
+ )
+
+Next, you must replace the :class:`~django.contrib.auth.backends.ModelBackend`
+with ``RemoteUserBackend`` in the :setting:`AUTHENTICATION_BACKENDS` setting::
+
+ AUTHENTICATION_BACKENDS = (
+ 'django.contrib.auth.backends.RemoteUserBackend',
+ )
+
+With this setup, ``RemoteUserMiddleware`` will detect the username in
+``request.META['REMOTE_USER']`` and will authenticate and auto-login that user
+using the ``RemoteUserBackend``.
+
+.. note::
+ Since the ``RemoteUserBackend`` inherits from ``ModelBackend``, you will
+ still have all of the same permissions checking that is implemented in
+ ``ModelBackend``.
+
+If your authentication mechanism uses a custom HTTP header and not
+``REMOTE_USER``, you can subclass ``RemoteUserMiddleware`` and set the
+``header`` attribute to the desired ``request.META`` key. For example::
+
+ from django.contrib.auth.middleware import RemoteUserMiddleware
+
+ class CustomHeaderMiddleware(RemoteUserMiddleware):
+ header = 'HTTP_AUTHUSER'
+
+
+``RemoteUserBackend``
+=====================
+
+.. class:: django.contrib.auth.backends.RemoteUserBackend
+
+If you need more control, you can create your own authentication backend
+that inherits from ``RemoteUserBackend`` and overrides certain parts:
+
+Attributes
+~~~~~~~~~~
+
+.. attribute:: RemoteUserBackend.create_unknown_user
+
+ ``True`` or ``False``. Determines whether or not a
+ :class:`~django.contrib.auth.models.User` object is created if not already
+ in the database. Defaults to ``True``.
+
+Methods
+~~~~~~~
+
+.. method:: RemoteUserBackend.clean_username(username)
+
+ Performs any cleaning on the ``username`` (e.g. stripping LDAP DN
+ information) prior to using it to get or create a
+ :class:`~django.contrib.auth.models.User` object. Returns the cleaned
+ username.
+
+.. method:: RemoteUserBackend.configure_user(user)
+
+ Configures a newly created user. This method is called immediately after a
+ new user is created, and can be used to perform custom setup actions, such
+ as setting the user's groups based on attributes in an LDAP directory.
+ Returns the user object.
diff --git a/parts/django/docs/howto/custom-file-storage.txt b/parts/django/docs/howto/custom-file-storage.txt
new file mode 100644
index 0000000..1b0f32f
--- /dev/null
+++ b/parts/django/docs/howto/custom-file-storage.txt
@@ -0,0 +1,90 @@
+Writing a custom storage system
+===============================
+
+.. currentmodule:: django.core.files.storage
+
+If you need to provide custom file storage -- a common example is storing files
+on some remote system -- you can do so by defining a custom storage class.
+You'll need to follow these steps:
+
+#. Your custom storage system must be a subclass of
+ ``django.core.files.storage.Storage``::
+
+ from django.core.files.storage import Storage
+
+ class MyStorage(Storage):
+ ...
+
+#. Django must be able to instantiate your storage system without any arguments.
+ This means that any settings should be taken from ``django.conf.settings``::
+
+ from django.conf import settings
+ from django.core.files.storage import Storage
+
+ class MyStorage(Storage):
+ def __init__(self, option=None):
+ if not option:
+ option = settings.CUSTOM_STORAGE_OPTIONS
+ ...
+
+#. Your storage class must implement the ``_open()`` and ``_save()`` methods,
+ along with any other methods appropriate to your storage class. See below for
+ more on these methods.
+
+ In addition, if your class provides local file storage, it must override
+ the ``path()`` method.
+
+Your custom storage system may override any of the storage methods explained in
+:doc:`/ref/files/storage`, but you **must** implement the following methods:
+
+ * :meth:`Storage.delete`
+ * :meth:`Storage.exists`
+ * :meth:`Storage.listdir`
+ * :meth:`Storage.size`
+ * :meth:`Storage.url`
+
+You'll also usually want to use hooks specifically designed for custom storage
+objects. These are:
+
+``_open(name, mode='rb')``
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**Required**.
+
+Called by ``Storage.open()``, this is the actual mechanism the storage class
+uses to open the file. This must return a ``File`` object, though in most cases,
+you'll want to return some subclass here that implements logic specific to the
+backend storage system.
+
+``_save(name, content)``
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Called by ``Storage.save()``. The ``name`` will already have gone through
+``get_valid_name()`` and ``get_available_name()``, and the ``content`` will be a
+``File`` object itself.
+
+Should return the actual name of name of the file saved (usually the ``name``
+passed in, but if the storage needs to change the file name return the new name
+instead).
+
+``get_valid_name(name)``
+------------------------
+
+Returns a filename suitable for use with the underlying storage system. The
+``name`` argument passed to this method is the original filename sent to the
+server, after having any path information removed. Override this to customize
+how non-standard characters are converted to safe filenames.
+
+The code provided on ``Storage`` retains only alpha-numeric characters, periods
+and underscores from the original filename, removing everything else.
+
+``get_available_name(name)``
+----------------------------
+
+Returns a filename that is available in the storage mechanism, possibly taking
+the provided filename into account. The ``name`` argument passed to this method
+will have already cleaned to a filename valid for the storage system, according
+to the ``get_valid_name()`` method described above.
+
+The code provided on ``Storage`` simply appends ``"_1"``, ``"_2"``, etc. to the
+filename until it finds one that's available in the destination directory.
diff --git a/parts/django/docs/howto/custom-management-commands.txt b/parts/django/docs/howto/custom-management-commands.txt
new file mode 100644
index 0000000..4a1747f
--- /dev/null
+++ b/parts/django/docs/howto/custom-management-commands.txt
@@ -0,0 +1,253 @@
+====================================
+Writing custom django-admin commands
+====================================
+
+.. versionadded:: 1.0
+
+Applications can register their own actions with ``manage.py``. For example,
+you might want to add a ``manage.py`` action for a Django app that you're
+distributing. In this document, we will be building a custom ``closepoll``
+command for the ``polls`` application from the
+:doc:`tutorial</intro/tutorial01>`.
+
+To do this, just add a ``management/commands`` directory to the application.
+Each Python module in that directory will be auto-discovered and registered as
+a command that can be executed as an action when you run ``manage.py``::
+
+ polls/
+ __init__.py
+ models.py
+ management/
+ __init__.py
+ commands/
+ __init__.py
+ closepoll.py
+ tests.py
+ views.py
+
+In this example, the ``closepoll`` command will be made available to any project
+that includes the ``polls`` application in :setting:`INSTALLED_APPS`.
+
+The ``closepoll.py`` module has only one requirement -- it must define a class
+``Command`` that extends :class:`BaseCommand` or one of its
+:ref:`subclasses<ref-basecommand-subclasses>`.
+
+.. admonition:: Standalone scripts
+
+ Custom management commands are especially useful for running standalone
+ scripts or for scripts that are periodically executed from the UNIX crontab
+ or from Windows scheduled tasks control panel.
+
+To implement the command, edit ``polls/management/commands/closepoll.py`` to
+look like this:
+
+.. code-block:: python
+
+ from django.core.management.base import BaseCommand, CommandError
+ from example.polls.models import Poll
+
+ class Command(BaseCommand):
+ args = '<poll_id poll_id ...>'
+ help = 'Closes the specified poll for voting'
+
+ def handle(self, *args, **options):
+ for poll_id in args:
+ try:
+ poll = Poll.objects.get(pk=int(poll_id))
+ except Poll.DoesNotExist:
+ raise CommandError('Poll "%s" does not exist' % poll_id)
+
+ poll.opened = False
+ poll.save()
+
+ print 'Successfully closed poll "%s"' % poll_id
+
+The new custom command can be called using ``python manage.py closepoll
+<poll_id>``.
+
+The ``handle()`` method takes zero or more ``poll_ids`` and sets ``poll.opened``
+to ``False`` for each one. If the user referenced any nonexistant polls, a
+:class:`CommandError` is raised. The ``poll.opened`` attribute does not exist
+in the :doc:`tutorial</intro/tutorial01>` and was added to
+``polls.models.Poll`` for this example.
+
+The same ``closepoll`` could be easily modified to delete a given poll instead
+of closing it by accepting additional command line options. These custom options
+must be added to :attr:`~BaseCommand.option_list` like this:
+
+.. code-block:: python
+
+ from optparse import make_option
+
+ class Command(BaseCommand):
+ option_list = BaseCommand.option_list + (
+ make_option('--delete',
+ action='store_true',
+ dest='delete',
+ default=False,
+ help='Delete poll instead of closing it'),
+ )
+ # ...
+
+In addition to being able to add custom command line options, all
+:doc:`management commands</ref/django-admin>` can accept some
+default options such as :djadminopt:`--verbosity` and :djadminopt:`--traceback`.
+
+Command objects
+===============
+
+.. class:: BaseCommand
+
+The base class from which all management commands ultimately derive.
+
+Use this class if you want access to all of the mechanisms which
+parse the command-line arguments and work out what code to call in
+response; if you don't need to change any of that behavior,
+consider using one of its :ref:`subclasses<ref-basecommand-subclasses>`.
+
+Subclassing the :class:`BaseCommand` class requires that you implement the
+:meth:`~BaseCommand.handle` method.
+
+Attributes
+----------
+
+All attributes can be set in your derived class and can be used in
+:class:`BaseCommand`'s :ref:`subclasses<ref-basecommand-subclasses>`.
+
+.. attribute:: BaseCommand.args
+
+ A string listing the arguments accepted by the command,
+ suitable for use in help messages; e.g., a command which takes
+ a list of application names might set this to '<appname
+ appname ...>'.
+
+.. attribute:: BaseCommand.can_import_settings
+
+ A boolean indicating whether the command needs to be able to
+ import Django settings; if ``True``, ``execute()`` will verify
+ that this is possible before proceeding. Default value is
+ ``True``.
+
+.. attribute:: BaseCommand.help
+
+ A short description of the command, which will be printed in the
+ help message when the user runs the command
+ ``python manage.py help <command>``.
+
+.. attribute:: BaseCommand.option_list
+
+ This is the list of ``optparse`` options which will be fed
+ into the command's ``OptionParser`` for parsing arguments.
+
+.. attribute:: BaseCommand.output_transaction
+
+ A boolean indicating whether the command outputs SQL
+ statements; if ``True``, the output will automatically be
+ wrapped with ``BEGIN;`` and ``COMMIT;``. Default value is
+ ``False``.
+
+.. attribute:: BaseCommand.requires_model_validation
+
+ A boolean; if ``True``, validation of installed models will be
+ performed prior to executing the command. Default value is
+ ``True``. To validate an individual application's models
+ rather than all applications' models, call
+ :meth:`~BaseCommand.validate` from :meth:`~BaseCommand.handle`.
+
+Methods
+-------
+
+:class:`BaseCommand` has a few methods that can be overridden but only
+the :meth:`~BaseCommand.handle` method must be implemented.
+
+.. admonition:: Implementing a constructor in a subclass
+
+ If you implement ``__init__`` in your subclass of :class:`BaseCommand`,
+ you must call :class:`BaseCommand`'s ``__init__``.
+
+ .. code-block:: python
+
+ class Command(BaseCommand):
+ def __init__(self, *args, **kwargs):
+ super(Command, self).__init__(*args, **kwargs)
+ # ...
+
+.. method:: BaseCommand.get_version()
+
+ Return the Django version, which should be correct for all
+ built-in Django commands. User-supplied commands can
+ override this method to return their own version.
+
+.. method:: BaseCommand.execute(*args, **options)
+
+ Try to execute this command, performing model validation if
+ needed (as controlled by the attribute
+ :attr:`requires_model_validation`). If the command raises a
+ :class:`CommandError`, intercept it and print it sensibly to
+ stderr.
+
+.. method:: BaseCommand.handle(*args, **options)
+
+ The actual logic of the command. Subclasses must implement this method.
+
+.. _ref-basecommand-subclasses:
+
+BaseCommand subclasses
+----------------------
+
+.. class:: AppCommand
+
+A management command which takes one or more installed application
+names as arguments, and does something with each of them.
+
+Rather than implementing :meth:`~BaseCommand.handle`, subclasses must implement
+:meth:`~AppCommand.handle_app`, which will be called once for each application.
+
+.. method:: AppCommand.handle_app(app, **options)
+
+ Perform the command's actions for ``app``, which will be the
+ Python module corresponding to an application name given on
+ the command line.
+
+.. class:: LabelCommand
+
+A management command which takes one or more arbitrary arguments
+(labels) on the command line, and does something with each of
+them.
+
+Rather than implementing :meth:`~BaseCommand.handle`, subclasses must implement
+:meth:`~LabelCommand.handle_label`, which will be called once for each label.
+
+.. method:: LabelCommand.handle_label(label, **options)
+
+ Perform the command's actions for ``label``, which will be the
+ string as given on the command line.
+
+.. class:: NoArgsCommand
+
+A command which takes no arguments on the command line.
+
+Rather than implementing :meth:`~BaseCommand.handle`, subclasses must implement
+:meth:`~NoArgsCommand.handle_noargs`; :meth:`~BaseCommand.handle` itself is
+overridden to ensure no arguments are passed to the command.
+
+.. method:: NoArgsCommand.handle_noargs(**options)
+
+ Perform this command's actions
+
+.. _ref-command-exceptions:
+
+Command exceptions
+------------------
+
+.. class:: CommandError
+
+Exception class indicating a problem while executing a management
+command.
+
+If this exception is raised during the execution of a management
+command, it will be caught and turned into a nicely-printed error
+message to the appropriate output stream (i.e., stderr); as a
+result, raising this exception (with a sensible description of the
+error) is the preferred way to indicate that something has gone
+wrong in the execution of a command.
diff --git a/parts/django/docs/howto/custom-model-fields.txt b/parts/django/docs/howto/custom-model-fields.txt
new file mode 100644
index 0000000..1840c5b
--- /dev/null
+++ b/parts/django/docs/howto/custom-model-fields.txt
@@ -0,0 +1,745 @@
+===========================
+Writing custom model fields
+===========================
+
+.. versionadded:: 1.0
+.. currentmodule:: django.db.models
+
+Introduction
+============
+
+The :doc:`model reference </topics/db/models>` documentation explains how to use
+Django's standard field classes -- :class:`~django.db.models.CharField`,
+:class:`~django.db.models.DateField`, etc. For many purposes, those classes are
+all you'll need. Sometimes, though, the Django version won't meet your precise
+requirements, or you'll want to use a field that is entirely different from
+those shipped with Django.
+
+Django's built-in field types don't cover every possible database column type --
+only the common types, such as ``VARCHAR`` and ``INTEGER``. For more obscure
+column types, such as geographic polygons or even user-created types such as
+`PostgreSQL custom types`_, you can define your own Django ``Field`` subclasses.
+
+.. _PostgreSQL custom types: http://www.postgresql.org/docs/8.2/interactive/sql-createtype.html
+
+Alternatively, you may have a complex Python object that can somehow be
+serialized to fit into a standard database column type. This is another case
+where a ``Field`` subclass will help you use your object with your models.
+
+Our example object
+------------------
+
+Creating custom fields requires a bit of attention to detail. To make things
+easier to follow, we'll use a consistent example throughout this document:
+wrapping a Python object representing the deal of cards in a hand of Bridge_.
+Don't worry, you don't have know how to play Bridge to follow this example.
+You only need to know that 52 cards are dealt out equally to four players, who
+are traditionally called *north*, *east*, *south* and *west*. Our class looks
+something like this::
+
+ class Hand(object):
+ """A hand of cards (bridge style)"""
+
+ def __init__(self, north, east, south, west):
+ # Input parameters are lists of cards ('Ah', '9s', etc)
+ self.north = north
+ self.east = east
+ self.south = south
+ self.west = west
+
+ # ... (other possibly useful methods omitted) ...
+
+.. _Bridge: http://en.wikipedia.org/wiki/Contract_bridge
+
+This is just an ordinary Python class, with nothing Django-specific about it.
+We'd like to be able to do things like this in our models (we assume the
+``hand`` attribute on the model is an instance of ``Hand``)::
+
+ example = MyModel.objects.get(pk=1)
+ print example.hand.north
+
+ new_hand = Hand(north, east, south, west)
+ example.hand = new_hand
+ example.save()
+
+We assign to and retrieve from the ``hand`` attribute in our model just like
+any other Python class. The trick is to tell Django how to handle saving and
+loading such an object.
+
+In order to use the ``Hand`` class in our models, we **do not** have to change
+this class at all. This is ideal, because it means you can easily write
+model support for existing classes where you cannot change the source code.
+
+.. note::
+ You might only be wanting to take advantage of custom database column
+ types and deal with the data as standard Python types in your models;
+ strings, or floats, for example. This case is similar to our ``Hand``
+ example and we'll note any differences as we go along.
+
+Background theory
+=================
+
+Database storage
+----------------
+
+The simplest way to think of a model field is that it provides a way to take a
+normal Python object -- string, boolean, ``datetime``, or something more
+complex like ``Hand`` -- and convert it to and from a format that is useful
+when dealing with the database (and serialization, but, as we'll see later,
+that falls out fairly naturally once you have the database side under control).
+
+Fields in a model must somehow be converted to fit into an existing database
+column type. Different databases provide different sets of valid column types,
+but the rule is still the same: those are the only types you have to work
+with. Anything you want to store in the database must fit into one of
+those types.
+
+Normally, you're either writing a Django field to match a particular database
+column type, or there's a fairly straightforward way to convert your data to,
+say, a string.
+
+For our ``Hand`` example, we could convert the card data to a string of 104
+characters by concatenating all the cards together in a pre-determined order --
+say, all the *north* cards first, then the *east*, *south* and *west* cards. So
+``Hand`` objects can be saved to text or character columns in the database.
+
+What does a field class do?
+---------------------------
+
+All of Django's fields (and when we say *fields* in this document, we always
+mean model fields and not :doc:`form fields </ref/forms/fields>`) are subclasses
+of :class:`django.db.models.Field`. Most of the information that Django records
+about a field is common to all fields -- name, help text, uniqueness and so
+forth. Storing all that information is handled by ``Field``. We'll get into the
+precise details of what ``Field`` can do later on; for now, suffice it to say
+that everything descends from ``Field`` and then customizes key pieces of the
+class behavior.
+
+It's important to realize that a Django field class is not what is stored in
+your model attributes. The model attributes contain normal Python objects. The
+field classes you define in a model are actually stored in the ``Meta`` class
+when the model class is created (the precise details of how this is done are
+unimportant here). This is because the field classes aren't necessary when
+you're just creating and modifying attributes. Instead, they provide the
+machinery for converting between the attribute value and what is stored in the
+database or sent to the :doc:`serializer </topics/serialization>`.
+
+Keep this in mind when creating your own custom fields. The Django ``Field``
+subclass you write provides the machinery for converting between your Python
+instances and the database/serializer values in various ways (there are
+differences between storing a value and using a value for lookups, for
+example). If this sounds a bit tricky, don't worry -- it will become clearer in
+the examples below. Just remember that you will often end up creating two
+classes when you want a custom field:
+
+ * The first class is the Python object that your users will manipulate.
+ They will assign it to the model attribute, they will read from it for
+ displaying purposes, things like that. This is the ``Hand`` class in our
+ example.
+
+ * The second class is the ``Field`` subclass. This is the class that knows
+ how to convert your first class back and forth between its permanent
+ storage form and the Python form.
+
+Writing a field subclass
+========================
+
+When planning your :class:`~django.db.models.Field` subclass, first give some
+thought to which existing :class:`~django.db.models.Field` class your new field
+is most similar to. Can you subclass an existing Django field and save yourself
+some work? If not, you should subclass the :class:`~django.db.models.Field`
+class, from which everything is descended.
+
+Initializing your new field is a matter of separating out any arguments that are
+specific to your case from the common arguments and passing the latter to the
+:meth:`~django.db.models.Field.__init__` method of
+:class:`~django.db.models.Field` (or your parent class).
+
+In our example, we'll call our field ``HandField``. (It's a good idea to call
+your :class:`~django.db.models.Field` subclass ``<Something>Field``, so it's
+easily identifiable as a :class:`~django.db.models.Field` subclass.) It doesn't
+behave like any existing field, so we'll subclass directly from
+:class:`~django.db.models.Field`::
+
+ from django.db import models
+
+ class HandField(models.Field):
+
+ description = "A hand of cards (bridge style)"
+
+ def __init__(self, *args, **kwargs):
+ kwargs['max_length'] = 104
+ super(HandField, self).__init__(*args, **kwargs)
+
+Our ``HandField`` accepts most of the standard field options (see the list
+below), but we ensure it has a fixed length, since it only needs to hold 52
+card values plus their suits; 104 characters in total.
+
+.. note::
+ Many of Django's model fields accept options that they don't do anything
+ with. For example, you can pass both
+ :attr:`~django.db.models.Field.editable` and
+ :attr:`~django.db.models.Field.auto_now` to a
+ :class:`django.db.models.DateField` and it will simply ignore the
+ :attr:`~django.db.models.Field.editable` parameter
+ (:attr:`~django.db.models.Field.auto_now` being set implies
+ ``editable=False``). No error is raised in this case.
+
+ This behavior simplifies the field classes, because they don't need to
+ check for options that aren't necessary. They just pass all the options to
+ the parent class and then don't use them later on. It's up to you whether
+ you want your fields to be more strict about the options they select, or
+ to use the simpler, more permissive behavior of the current fields.
+
+The :meth:`~django.db.models.Field.__init__` method takes the following
+parameters:
+
+ * :attr:`~django.db.models.Field.verbose_name`
+ * :attr:`~django.db.models.Field.name`
+ * :attr:`~django.db.models.Field.primary_key`
+ * :attr:`~django.db.models.Field.max_length`
+ * :attr:`~django.db.models.Field.unique`
+ * :attr:`~django.db.models.Field.blank`
+ * :attr:`~django.db.models.Field.null`
+ * :attr:`~django.db.models.Field.db_index`
+ * :attr:`~django.db.models.Field.rel`: Used for related fields (like
+ :class:`ForeignKey`). For advanced use only.
+ * :attr:`~django.db.models.Field.default`
+ * :attr:`~django.db.models.Field.editable`
+ * :attr:`~django.db.models.Field.serialize`: If ``False``, the field will
+ not be serialized when the model is passed to Django's :doc:`serializers
+ </topics/serialization>`. Defaults to ``True``.
+ * :attr:`~django.db.models.Field.unique_for_date`
+ * :attr:`~django.db.models.Field.unique_for_month`
+ * :attr:`~django.db.models.Field.unique_for_year`
+ * :attr:`~django.db.models.Field.choices`
+ * :attr:`~django.db.models.Field.help_text`
+ * :attr:`~django.db.models.Field.db_column`
+ * :attr:`~django.db.models.Field.db_tablespace`: Currently only used with
+ the Oracle backend and only for index creation. You can usually ignore
+ this option.
+ * :attr:`~django.db.models.Field.auto_created`: True if the field was
+ automatically created, as for the `OneToOneField` used by model
+ inheritance. For advanced use only.
+
+All of the options without an explanation in the above list have the same
+meaning they do for normal Django fields. See the :doc:`field documentation
+</ref/models/fields>` for examples and details.
+
+The ``SubfieldBase`` metaclass
+------------------------------
+
+As we indicated in the introduction_, field subclasses are often needed for
+two reasons: either to take advantage of a custom database column type, or to
+handle complex Python types. Obviously, a combination of the two is also
+possible. If you're only working with custom database column types and your
+model fields appear in Python as standard Python types direct from the
+database backend, you don't need to worry about this section.
+
+If you're handling custom Python types, such as our ``Hand`` class, we need to
+make sure that when Django initializes an instance of our model and assigns a
+database value to our custom field attribute, we convert that value into the
+appropriate Python object. The details of how this happens internally are a
+little complex, but the code you need to write in your ``Field`` class is
+simple: make sure your field subclass uses a special metaclass:
+
+.. class:: django.db.models.SubfieldBase
+
+For example::
+
+ class HandField(models.Field):
+
+ description = "A hand of cards (bridge style)"
+
+ __metaclass__ = models.SubfieldBase
+
+ def __init__(self, *args, **kwargs):
+ # ...
+
+This ensures that the :meth:`to_python` method, documented below, will always be
+called when the attribute is initialized.
+
+ModelForms and custom fields
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you use :class:`~django.db.models.SubfieldBase`, :meth:`to_python`
+will be called every time an instance of the field is assigned a
+value. This means that whenever a value may be assigned to the field,
+you need to ensure that it will be of the correct datatype, or that
+you handle any exceptions.
+
+This is especially important if you use :doc:`ModelForms
+</topics/forms/modelforms>`. When saving a ModelForm, Django will use
+form values to instantiate model instances. However, if the cleaned
+form data can't be used as valid input to the field, the normal form
+validation process will break.
+
+Therefore, you must ensure that the form field used to represent your
+custom field performs whatever input validation and data cleaning is
+necessary to convert user-provided form input into a
+`to_python()`-compatible model field value. This may require writing a
+custom form field, and/or implementing the :meth:`formfield` method on
+your field to return a form field class whose `to_python()` returns the
+correct datatype.
+
+Documenting your Custom Field
+-----------------------------
+
+.. class:: django.db.models.Field
+
+.. attribute:: description
+
+As always, you should document your field type, so users will know what it is.
+In addition to providing a docstring for it, which is useful for developers,
+you can also allow users of the admin app to see a short description of the
+field type via the :doc:`django.contrib.admindocs
+</ref/contrib/admin/admindocs>` application. To do this simply provide
+descriptive text in a ``description`` class attribute of your custom field. In
+the above example, the type description displayed by the ``admindocs``
+application for a ``HandField`` will be 'A hand of cards (bridge style)'.
+
+Useful methods
+--------------
+
+Once you've created your :class:`~django.db.models.Field` subclass and set up
+the ``__metaclass__``, you might consider overriding a few standard methods,
+depending on your field's behavior. The list of methods below is in
+approximately decreasing order of importance, so start from the top.
+
+Custom database types
+~~~~~~~~~~~~~~~~~~~~~
+
+.. method:: db_type(self, connection)
+
+.. versionadded:: 1.2
+ The ``connection`` argument was added to support multiple databases.
+
+Returns the database column data type for the :class:`~django.db.models.Field`,
+taking into account the connection object, and the settings associated with it.
+
+Say you've created a PostgreSQL custom type called ``mytype``. You can use this
+field with Django by subclassing ``Field`` and implementing the :meth:`db_type`
+method, like so::
+
+ from django.db import models
+
+ class MytypeField(models.Field):
+ def db_type(self, connection):
+ return 'mytype'
+
+Once you have ``MytypeField``, you can use it in any model, just like any other
+``Field`` type::
+
+ class Person(models.Model):
+ name = models.CharField(max_length=80)
+ gender = models.CharField(max_length=1)
+ something_else = MytypeField()
+
+If you aim to build a database-agnostic application, you should account for
+differences in database column types. For example, the date/time column type
+in PostgreSQL is called ``timestamp``, while the same column in MySQL is called
+``datetime``. The simplest way to handle this in a ``db_type()`` method is to
+check the ``connection.settings_dict['ENGINE']`` attribute.
+
+For example::
+
+ class MyDateField(models.Field):
+ def db_type(self, connection):
+ if connection.settings_dict['ENGINE'] == 'django.db.backends.mysql':
+ return 'datetime'
+ else:
+ return 'timestamp'
+
+The :meth:`db_type` method is only called by Django when the framework
+constructs the ``CREATE TABLE`` statements for your application -- that is, when
+you first create your tables. It's not called at any other time, so it can
+afford to execute slightly complex code, such as the ``connection.settings_dict``
+check in the above example.
+
+Some database column types accept parameters, such as ``CHAR(25)``, where the
+parameter ``25`` represents the maximum column length. In cases like these,
+it's more flexible if the parameter is specified in the model rather than being
+hard-coded in the ``db_type()`` method. For example, it wouldn't make much
+sense to have a ``CharMaxlength25Field``, shown here::
+
+ # This is a silly example of hard-coded parameters.
+ class CharMaxlength25Field(models.Field):
+ def db_type(self, connection):
+ return 'char(25)'
+
+ # In the model:
+ class MyModel(models.Model):
+ # ...
+ my_field = CharMaxlength25Field()
+
+The better way of doing this would be to make the parameter specifiable at run
+time -- i.e., when the class is instantiated. To do that, just implement
+:meth:`django.db.models.Field.__init__`, like so::
+
+ # This is a much more flexible example.
+ class BetterCharField(models.Field):
+ def __init__(self, max_length, *args, **kwargs):
+ self.max_length = max_length
+ super(BetterCharField, self).__init__(*args, **kwargs)
+
+ def db_type(self, connection):
+ return 'char(%s)' % self.max_length
+
+ # In the model:
+ class MyModel(models.Model):
+ # ...
+ my_field = BetterCharField(25)
+
+Finally, if your column requires truly complex SQL setup, return ``None`` from
+:meth:`db_type`. This will cause Django's SQL creation code to skip over this
+field. You are then responsible for creating the column in the right table in
+some other way, of course, but this gives you a way to tell Django to get out of
+the way.
+
+Converting database values to Python objects
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. method:: to_python(self, value)
+
+Converts a value as returned by your database (or a serializer) to a Python
+object.
+
+The default implementation simply returns ``value``, for the common case in
+which the database backend already returns data in the correct format (as a
+Python string, for example).
+
+If your custom :class:`~django.db.models.Field` class deals with data structures
+that are more complex than strings, dates, integers or floats, then you'll need
+to override this method. As a general rule, the method should deal gracefully
+with any of the following arguments:
+
+ * An instance of the correct type (e.g., ``Hand`` in our ongoing example).
+
+ * A string (e.g., from a deserializer).
+
+ * Whatever the database returns for the column type you're using.
+
+In our ``HandField`` class, we're storing the data as a VARCHAR field in the
+database, so we need to be able to process strings and ``Hand`` instances in
+:meth:`to_python`::
+
+ import re
+
+ class HandField(models.Field):
+ # ...
+
+ def to_python(self, value):
+ if isinstance(value, Hand):
+ return value
+
+ # The string case.
+ p1 = re.compile('.{26}')
+ p2 = re.compile('..')
+ args = [p2.findall(x) for x in p1.findall(value)]
+ return Hand(*args)
+
+Notice that we always return a ``Hand`` instance from this method. That's the
+Python object type we want to store in the model's attribute.
+
+**Remember:** If your custom field needs the :meth:`to_python` method to be
+called when it is created, you should be using `The SubfieldBase metaclass`_
+mentioned earlier. Otherwise :meth:`to_python` won't be called automatically.
+
+Converting Python objects to query values
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. method:: get_prep_value(self, value)
+
+.. versionadded:: 1.2
+ This method was factored out of ``get_db_prep_value()``
+
+This is the reverse of :meth:`to_python` when working with the
+database backends (as opposed to serialization). The ``value``
+parameter is the current value of the model's attribute (a field has
+no reference to its containing model, so it cannot retrieve the value
+itself), and the method should return data in a format that has been
+prepared for use as a parameter in a query.
+
+This conversion should *not* include any database-specific
+conversions. If database-specific conversions are required, they
+should be made in the call to :meth:`get_db_prep_value`.
+
+For example::
+
+ class HandField(models.Field):
+ # ...
+
+ def get_prep_value(self, value):
+ return ''.join([''.join(l) for l in (value.north,
+ value.east, value.south, value.west)])
+
+Converting query values to database values
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. method:: get_db_prep_value(self, value, connection, prepared=False)
+
+.. versionadded:: 1.2
+ The ``connection`` and ``prepared`` arguments were added to support multiple databases.
+
+Some data types (for example, dates) need to be in a specific format
+before they can be used by a database backend.
+:meth:`get_db_prep_value` is the method where those conversions should
+be made. The specific connection that will be used for the query is
+passed as the ``connection`` parameter. This allows you to use
+backend-specific conversion logic if it is required.
+
+The ``prepared`` argument describes whether or not the value has
+already been passed through :meth:`get_prep_value` conversions. When
+``prepared`` is False, the default implementation of
+:meth:`get_db_prep_value` will call :meth:`get_prep_value` to do
+initial data conversions before performing any database-specific
+processing.
+
+.. method:: get_db_prep_save(self, value, connection)
+
+.. versionadded:: 1.2
+ The ``connection`` argument was added to support multiple databases.
+
+Same as the above, but called when the Field value must be *saved* to
+the database. As the default implementation just calls
+``get_db_prep_value``, you shouldn't need to implement this method
+unless your custom field needs a special conversion when being saved
+that is not the same as the conversion used for normal query
+parameters (which is implemented by ``get_db_prep_value``).
+
+Preprocessing values before saving
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. method:: pre_save(self, model_instance, add)
+
+This method is called just prior to :meth:`get_db_prep_save` and should return
+the value of the appropriate attribute from ``model_instance`` for this field.
+The attribute name is in ``self.attname`` (this is set up by
+:class:`~django.db.models.Field`). If the model is being saved to the database
+for the first time, the ``add`` parameter will be ``True``, otherwise it will be
+``False``.
+
+You only need to override this method if you want to preprocess the value
+somehow, just before saving. For example, Django's
+:class:`~django.db.models.DateTimeField` uses this method to set the attribute
+correctly in the case of :attr:`~django.db.models.Field.auto_now` or
+:attr:`~django.db.models.Field.auto_now_add`.
+
+If you do override this method, you must return the value of the attribute at
+the end. You should also update the model's attribute if you make any changes
+to the value so that code holding references to the model will always see the
+correct value.
+
+Preparing values for use in database lookups
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+As with value conversions, preparing a value for database lookups is a
+two phase process.
+
+.. method:: get_prep_lookup(self, lookup_type, value)
+
+.. versionadded:: 1.2
+ This method was factored out of ``get_db_prep_lookup()``
+
+:meth:`get_prep_lookup` performs the first phase of lookup preparation,
+performing generic data validity checks
+
+Prepares the ``value`` for passing to the database when used in a lookup (a
+``WHERE`` constraint in SQL). The ``lookup_type`` will be one of the valid
+Django filter lookups: ``exact``, ``iexact``, ``contains``, ``icontains``,
+``gt``, ``gte``, ``lt``, ``lte``, ``in``, ``startswith``, ``istartswith``,
+``endswith``, ``iendswith``, ``range``, ``year``, ``month``, ``day``,
+``isnull``, ``search``, ``regex``, and ``iregex``.
+
+Your method must be prepared to handle all of these ``lookup_type`` values and
+should raise either a ``ValueError`` if the ``value`` is of the wrong sort (a
+list when you were expecting an object, for example) or a ``TypeError`` if
+your field does not support that type of lookup. For many fields, you can get
+by with handling the lookup types that need special handling for your field
+and pass the rest to the :meth:`get_db_prep_lookup` method of the parent class.
+
+If you needed to implement ``get_db_prep_save()``, you will usually need to
+implement ``get_prep_lookup()``. If you don't, ``get_prep_value`` will be
+called by the default implementation, to manage ``exact``, ``gt``, ``gte``,
+``lt``, ``lte``, ``in`` and ``range`` lookups.
+
+You may also want to implement this method to limit the lookup types that could
+be used with your custom field type.
+
+Note that, for ``range`` and ``in`` lookups, ``get_prep_lookup`` will receive
+a list of objects (presumably of the right type) and will need to convert them
+to a list of things of the right type for passing to the database. Most of the
+time, you can reuse ``get_prep_value()``, or at least factor out some common
+pieces.
+
+For example, the following code implements ``get_prep_lookup`` to limit the
+accepted lookup types to ``exact`` and ``in``::
+
+ class HandField(models.Field):
+ # ...
+
+ def get_prep_lookup(self, lookup_type, value):
+ # We only handle 'exact' and 'in'. All others are errors.
+ if lookup_type == 'exact':
+ return self.get_prep_value(value)
+ elif lookup_type == 'in':
+ return [self.get_prep_value(v) for v in value]
+ else:
+ raise TypeError('Lookup type %r not supported.' % lookup_type)
+
+.. method:: get_db_prep_lookup(self, lookup_type, value, connection, prepared=False)
+
+.. versionadded:: 1.2
+ The ``connection`` and ``prepared`` arguments were added to support multiple databases.
+
+Performs any database-specific data conversions required by a lookup.
+As with :meth:`get_db_prep_value`, the specific connection that will
+be used for the query is passed as the ``connection`` parameter.
+The ``prepared`` argument describes whether the value has already been
+prepared with :meth:`get_prep_lookup`.
+
+Specifying the form field for a model field
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. method:: formfield(self, form_class=forms.CharField, **kwargs)
+
+Returns the default form field to use when this field is displayed in a model.
+This method is called by the :class:`~django.forms.ModelForm` helper.
+
+All of the ``kwargs`` dictionary is passed directly to the form field's
+:meth:`~django.forms.Field__init__` method. Normally, all you need to do is
+set up a good default for the ``form_class`` argument and then delegate further
+handling to the parent class. This might require you to write a custom form
+field (and even a form widget). See the :doc:`forms documentation
+</topics/forms/index>` for information about this, and take a look at the code in
+:mod:`django.contrib.localflavor` for some examples of custom widgets.
+
+Continuing our ongoing example, we can write the :meth:`formfield` method as::
+
+ class HandField(models.Field):
+ # ...
+
+ def formfield(self, **kwargs):
+ # This is a fairly standard way to set up some defaults
+ # while letting the caller override them.
+ defaults = {'form_class': MyFormField}
+ defaults.update(kwargs)
+ return super(HandField, self).formfield(**defaults)
+
+This assumes we've imported a ``MyFormField`` field class (which has its own
+default widget). This document doesn't cover the details of writing custom form
+fields.
+
+.. _helper functions: ../forms/#generating-forms-for-models
+.. _forms documentation: ../forms/
+
+Emulating built-in field types
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. method:: get_internal_type(self)
+
+Returns a string giving the name of the :class:`~django.db.models.Field`
+subclass we are emulating at the database level. This is used to determine the
+type of database column for simple cases.
+
+If you have created a :meth:`db_type` method, you don't need to worry about
+:meth:`get_internal_type` -- it won't be used much. Sometimes, though, your
+database storage is similar in type to some other field, so you can use that
+other field's logic to create the right column.
+
+For example::
+
+ class HandField(models.Field):
+ # ...
+
+ def get_internal_type(self):
+ return 'CharField'
+
+No matter which database backend we are using, this will mean that ``syncdb``
+and other SQL commands create the right column type for storing a string.
+
+If :meth:`get_internal_type` returns a string that is not known to Django for
+the database backend you are using -- that is, it doesn't appear in
+``django.db.backends.<db_name>.creation.DATA_TYPES`` -- the string will still be
+used by the serializer, but the default :meth:`db_type` method will return
+``None``. See the documentation of :meth:`db_type` for reasons why this might be
+useful. Putting a descriptive string in as the type of the field for the
+serializer is a useful idea if you're ever going to be using the serializer
+output in some other place, outside of Django.
+
+Converting field data for serialization
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. method:: value_to_string(self, obj)
+
+This method is used by the serializers to convert the field into a string for
+output. Calling :meth:`Field._get_val_from_obj(obj)` is the best way to get the
+value to serialize. For example, since our ``HandField`` uses strings for its
+data storage anyway, we can reuse some existing conversion code::
+
+ class HandField(models.Field):
+ # ...
+
+ def value_to_string(self, obj):
+ value = self._get_val_from_obj(obj)
+ return self.get_db_prep_value(value)
+
+Some general advice
+--------------------
+
+Writing a custom field can be a tricky process, particularly if you're doing
+complex conversions between your Python types and your database and
+serialization formats. Here are a couple of tips to make things go more
+smoothly:
+
+ 1. Look at the existing Django fields (in
+ :file:`django/db/models/fields/__init__.py`) for inspiration. Try to find
+ a field that's similar to what you want and extend it a little bit,
+ instead of creating an entirely new field from scratch.
+
+ 2. Put a :meth:`__str__` or :meth:`__unicode__` method on the class you're
+ wrapping up as a field. There are a lot of places where the default
+ behavior of the field code is to call
+ :func:`~django.utils.encoding.force_unicode` on the value. (In our
+ examples in this document, ``value`` would be a ``Hand`` instance, not a
+ ``HandField``). So if your :meth:`__unicode__` method automatically
+ converts to the string form of your Python object, you can save yourself
+ a lot of work.
+
+
+Writing a ``FileField`` subclass
+=================================
+
+In addition to the above methods, fields that deal with files have a few other
+special requirements which must be taken into account. The majority of the
+mechanics provided by ``FileField``, such as controlling database storage and
+retrieval, can remain unchanged, leaving subclasses to deal with the challenge
+of supporting a particular type of file.
+
+Django provides a ``File`` class, which is used as a proxy to the file's
+contents and operations. This can be subclassed to customize how the file is
+accessed, and what methods are available. It lives at
+``django.db.models.fields.files``, and its default behavior is explained in the
+:doc:`file documentation </ref/files/file>`.
+
+Once a subclass of ``File`` is created, the new ``FileField`` subclass must be
+told to use it. To do so, simply assign the new ``File`` subclass to the special
+``attr_class`` attribute of the ``FileField`` subclass.
+
+A few suggestions
+------------------
+
+In addition to the above details, there are a few guidelines which can greatly
+improve the efficiency and readability of the field's code.
+
+ 1. The source for Django's own ``ImageField`` (in
+ ``django/db/models/fields/files.py``) is a great example of how to
+ subclass ``FileField`` to support a particular type of file, as it
+ incorporates all of the techniques described above.
+
+ 2. Cache file attributes wherever possible. Since files may be stored in
+ remote storage systems, retrieving them may cost extra time, or even
+ money, that isn't always necessary. Once a file is retrieved to obtain
+ some data about its content, cache as much of that data as possible to
+ reduce the number of times the file must be retrieved on subsequent
+ calls for that information.
diff --git a/parts/django/docs/howto/custom-template-tags.txt b/parts/django/docs/howto/custom-template-tags.txt
new file mode 100644
index 0000000..95ce274
--- /dev/null
+++ b/parts/django/docs/howto/custom-template-tags.txt
@@ -0,0 +1,939 @@
+================================
+Custom template tags and filters
+================================
+
+Introduction
+============
+
+Django's template system comes with a wide variety of :doc:`built-in
+tags and filters </ref/templates/builtins>` designed to address the
+presentation logic needs of your application. Nevertheless, you may
+find yourself needing functionality that is not covered by the core
+set of template primitives. You can extend the template engine by
+defining custom tags and filters using Python, and then make them
+available to your templates using the ``{% load %}`` tag.
+
+Code layout
+-----------
+
+Custom template tags and filters must live inside a Django app. If they relate
+to an existing app it makes sense to bundle them there; otherwise, you should
+create a new app to hold them.
+
+The app should contain a ``templatetags`` directory, at the same level as
+``models.py``, ``views.py``, etc. If this doesn't already exist, create it -
+don't forget the ``__init__.py`` file to ensure the directory is treated as a
+Python package.
+
+Your custom tags and filters will live in a module inside the ``templatetags``
+directory. The name of the module file is the name you'll use to load the tags
+later, so be careful to pick a name that won't clash with custom tags and
+filters in another app.
+
+For example, if your custom tags/filters are in a file called
+``poll_extras.py``, your app layout might look like this::
+
+ polls/
+ models.py
+ templatetags/
+ __init__.py
+ poll_extras.py
+ views.py
+
+And in your template you would use the following:
+
+.. code-block:: html+django
+
+ {% load poll_extras %}
+
+The app that contains the custom tags must be in :setting:`INSTALLED_APPS` in
+order for the ``{% load %}`` tag to work. This is a security feature: It allows
+you to host Python code for many template libraries on a single host machine
+without enabling access to all of them for every Django installation.
+
+There's no limit on how many modules you put in the ``templatetags`` package.
+Just keep in mind that a ``{% load %}`` statement will load tags/filters for
+the given Python module name, not the name of the app.
+
+To be a valid tag library, the module must contain a module-level variable
+named ``register`` that is a ``template.Library`` instance, in which all the
+tags and filters are registered. So, near the top of your module, put the
+following::
+
+ from django import template
+
+ register = template.Library()
+
+.. admonition:: Behind the scenes
+
+ For a ton of examples, read the source code for Django's default filters
+ and tags. They're in ``django/template/defaultfilters.py`` and
+ ``django/template/defaulttags.py``, respectively.
+
+Writing custom template filters
+-------------------------------
+
+Custom filters are just Python functions that take one or two arguments:
+
+ * The value of the variable (input) -- not necessarily a string.
+ * The value of the argument -- this can have a default value, or be left
+ out altogether.
+
+For example, in the filter ``{{ var|foo:"bar" }}``, the filter ``foo`` would be
+passed the variable ``var`` and the argument ``"bar"``.
+
+Filter functions should always return something. They shouldn't raise
+exceptions. They should fail silently. In case of error, they should return
+either the original input or an empty string -- whichever makes more sense.
+
+Here's an example filter definition::
+
+ def cut(value, arg):
+ "Removes all values of arg from the given string"
+ return value.replace(arg, '')
+
+And here's an example of how that filter would be used:
+
+.. code-block:: html+django
+
+ {{ somevariable|cut:"0" }}
+
+Most filters don't take arguments. In this case, just leave the argument out of
+your function. Example::
+
+ def lower(value): # Only one argument.
+ "Converts a string into all lowercase"
+ return value.lower()
+
+Template filters that expect strings
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you're writing a template filter that only expects a string as the first
+argument, you should use the decorator ``stringfilter``. This will
+convert an object to its string value before being passed to your function::
+
+ from django.template.defaultfilters import stringfilter
+
+ @stringfilter
+ def lower(value):
+ return value.lower()
+
+This way, you'll be able to pass, say, an integer to this filter, and it
+won't cause an ``AttributeError`` (because integers don't have ``lower()``
+methods).
+
+Registering custom filters
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Once you've written your filter definition, you need to register it with
+your ``Library`` instance, to make it available to Django's template language::
+
+ register.filter('cut', cut)
+ register.filter('lower', lower)
+
+The ``Library.filter()`` method takes two arguments:
+
+ 1. The name of the filter -- a string.
+ 2. The compilation function -- a Python function (not the name of the
+ function as a string).
+
+You can use ``register.filter()`` as a decorator instead::
+
+ @register.filter(name='cut')
+ @stringfilter
+ def cut(value, arg):
+ return value.replace(arg, '')
+
+ @register.filter
+ @stringfilter
+ def lower(value):
+ return value.lower()
+
+If you leave off the ``name`` argument, as in the second example above, Django
+will use the function's name as the filter name.
+
+Filters and auto-escaping
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.0
+
+When writing a custom filter, give some thought to how the filter will interact
+with Django's auto-escaping behavior. Note that three types of strings can be
+passed around inside the template code:
+
+ * **Raw strings** are the native Python ``str`` or ``unicode`` types. On
+ output, they're escaped if auto-escaping is in effect and presented
+ unchanged, otherwise.
+
+ * **Safe strings** are strings that have been marked safe from further
+ escaping at output time. Any necessary escaping has already been done.
+ They're commonly used for output that contains raw HTML that is intended
+ to be interpreted as-is on the client side.
+
+ Internally, these strings are of type ``SafeString`` or ``SafeUnicode``.
+ They share a common base class of ``SafeData``, so you can test
+ for them using code like::
+
+ if isinstance(value, SafeData):
+ # Do something with the "safe" string.
+
+ * **Strings marked as "needing escaping"** are *always* escaped on
+ output, regardless of whether they are in an ``autoescape`` block or not.
+ These strings are only escaped once, however, even if auto-escaping
+ applies.
+
+ Internally, these strings are of type ``EscapeString`` or
+ ``EscapeUnicode``. Generally you don't have to worry about these; they
+ exist for the implementation of the ``escape`` filter.
+
+Template filter code falls into one of two situations:
+
+ 1. Your filter does not introduce any HTML-unsafe characters (``<``, ``>``,
+ ``'``, ``"`` or ``&``) into the result that were not already present. In
+ this case, you can let Django take care of all the auto-escaping
+ handling for you. All you need to do is put the ``is_safe`` attribute on
+ your filter function and set it to ``True``, like so::
+
+ @register.filter
+ def myfilter(value):
+ return value
+ myfilter.is_safe = True
+
+ This attribute tells Django that if a "safe" string is passed into your
+ filter, the result will still be "safe" and if a non-safe string is
+ passed in, Django will automatically escape it, if necessary.
+
+ You can think of this as meaning "this filter is safe -- it doesn't
+ introduce any possibility of unsafe HTML."
+
+ The reason ``is_safe`` is necessary is because there are plenty of
+ normal string operations that will turn a ``SafeData`` object back into
+ a normal ``str`` or ``unicode`` object and, rather than try to catch
+ them all, which would be very difficult, Django repairs the damage after
+ the filter has completed.
+
+ For example, suppose you have a filter that adds the string ``xx`` to the
+ end of any input. Since this introduces no dangerous HTML characters to
+ the result (aside from any that were already present), you should mark
+ your filter with ``is_safe``::
+
+ @register.filter
+ def add_xx(value):
+ return '%sxx' % value
+ add_xx.is_safe = True
+
+ When this filter is used in a template where auto-escaping is enabled,
+ Django will escape the output whenever the input is not already marked as
+ "safe".
+
+ By default, ``is_safe`` defaults to ``False``, and you can omit it from
+ any filters where it isn't required.
+
+ Be careful when deciding if your filter really does leave safe strings
+ as safe. If you're *removing* characters, you might inadvertently leave
+ unbalanced HTML tags or entities in the result. For example, removing a
+ ``>`` from the input might turn ``<a>`` into ``<a``, which would need to
+ be escaped on output to avoid causing problems. Similarly, removing a
+ semicolon (``;``) can turn ``&amp;`` into ``&amp``, which is no longer a
+ valid entity and thus needs further escaping. Most cases won't be nearly
+ this tricky, but keep an eye out for any problems like that when
+ reviewing your code.
+
+ Marking a filter ``is_safe`` will coerce the filter's return value to
+ a string. If your filter should return a boolean or other non-string
+ value, marking it ``is_safe`` will probably have unintended
+ consequences (such as converting a boolean False to the string
+ 'False').
+
+ 2. Alternatively, your filter code can manually take care of any necessary
+ escaping. This is necessary when you're introducing new HTML markup into
+ the result. You want to mark the output as safe from further
+ escaping so that your HTML markup isn't escaped further, so you'll need
+ to handle the input yourself.
+
+ To mark the output as a safe string, use
+ :func:`django.utils.safestring.mark_safe`.
+
+ Be careful, though. You need to do more than just mark the output as
+ safe. You need to ensure it really *is* safe, and what you do depends on
+ whether auto-escaping is in effect. The idea is to write filters than
+ can operate in templates where auto-escaping is either on or off in
+ order to make things easier for your template authors.
+
+ In order for your filter to know the current auto-escaping state, set
+ the ``needs_autoescape`` attribute to ``True`` on your function. (If you
+ don't specify this attribute, it defaults to ``False``). This attribute
+ tells Django that your filter function wants to be passed an extra
+ keyword argument, called ``autoescape``, that is ``True`` if
+ auto-escaping is in effect and ``False`` otherwise.
+
+ For example, let's write a filter that emphasizes the first character of
+ a string::
+
+ from django.utils.html import conditional_escape
+ from django.utils.safestring import mark_safe
+
+ def initial_letter_filter(text, autoescape=None):
+ first, other = text[0], text[1:]
+ if autoescape:
+ esc = conditional_escape
+ else:
+ esc = lambda x: x
+ result = '<strong>%s</strong>%s' % (esc(first), esc(other))
+ return mark_safe(result)
+ initial_letter_filter.needs_autoescape = True
+
+ The ``needs_autoescape`` attribute on the filter function and the
+ ``autoescape`` keyword argument mean that our function will know whether
+ automatic escaping is in effect when the filter is called. We use
+ ``autoescape`` to decide whether the input data needs to be passed
+ through ``django.utils.html.conditional_escape`` or not. (In the latter
+ case, we just use the identity function as the "escape" function.) The
+ ``conditional_escape()`` function is like ``escape()`` except it only
+ escapes input that is **not** a ``SafeData`` instance. If a ``SafeData``
+ instance is passed to ``conditional_escape()``, the data is returned
+ unchanged.
+
+ Finally, in the above example, we remember to mark the result as safe
+ so that our HTML is inserted directly into the template without further
+ escaping.
+
+ There's no need to worry about the ``is_safe`` attribute in this case
+ (although including it wouldn't hurt anything). Whenever you manually
+ handle the auto-escaping issues and return a safe string, the
+ ``is_safe`` attribute won't change anything either way.
+
+Writing custom template tags
+----------------------------
+
+Tags are more complex than filters, because tags can do anything.
+
+A quick overview
+~~~~~~~~~~~~~~~~
+
+Above, this document explained that the template system works in a two-step
+process: compiling and rendering. To define a custom template tag, you specify
+how the compilation works and how the rendering works.
+
+When Django compiles a template, it splits the raw template text into
+''nodes''. Each node is an instance of ``django.template.Node`` and has
+a ``render()`` method. A compiled template is, simply, a list of ``Node``
+objects. When you call ``render()`` on a compiled template object, the template
+calls ``render()`` on each ``Node`` in its node list, with the given context.
+The results are all concatenated together to form the output of the template.
+
+Thus, to define a custom template tag, you specify how the raw template tag is
+converted into a ``Node`` (the compilation function), and what the node's
+``render()`` method does.
+
+Writing the compilation function
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+For each template tag the template parser encounters, it calls a Python
+function with the tag contents and the parser object itself. This function is
+responsible for returning a ``Node`` instance based on the contents of the tag.
+
+For example, let's write a template tag, ``{% current_time %}``, that displays
+the current date/time, formatted according to a parameter given in the tag, in
+`strftime syntax`_. It's a good idea to decide the tag syntax before anything
+else. In our case, let's say the tag should be used like this:
+
+.. code-block:: html+django
+
+ <p>The time is {% current_time "%Y-%m-%d %I:%M %p" %}.</p>
+
+.. _`strftime syntax`: http://docs.python.org/library/time.html#time.strftime
+
+The parser for this function should grab the parameter and create a ``Node``
+object::
+
+ from django import template
+ def do_current_time(parser, token):
+ try:
+ # split_contents() knows not to split quoted strings.
+ tag_name, format_string = token.split_contents()
+ except ValueError:
+ raise template.TemplateSyntaxError, "%r tag requires a single argument" % token.contents.split()[0]
+ if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")):
+ raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name
+ return CurrentTimeNode(format_string[1:-1])
+
+Notes:
+
+ * ``parser`` is the template parser object. We don't need it in this
+ example.
+
+ * ``token.contents`` is a string of the raw contents of the tag. In our
+ example, it's ``'current_time "%Y-%m-%d %I:%M %p"'``.
+
+ * The ``token.split_contents()`` method separates the arguments on spaces
+ while keeping quoted strings together. The more straightforward
+ ``token.contents.split()`` wouldn't be as robust, as it would naively
+ split on *all* spaces, including those within quoted strings. It's a good
+ idea to always use ``token.split_contents()``.
+
+ * This function is responsible for raising
+ ``django.template.TemplateSyntaxError``, with helpful messages, for
+ any syntax error.
+
+ * The ``TemplateSyntaxError`` exceptions use the ``tag_name`` variable.
+ Don't hard-code the tag's name in your error messages, because that
+ couples the tag's name to your function. ``token.contents.split()[0]``
+ will ''always'' be the name of your tag -- even when the tag has no
+ arguments.
+
+ * The function returns a ``CurrentTimeNode`` with everything the node needs
+ to know about this tag. In this case, it just passes the argument --
+ ``"%Y-%m-%d %I:%M %p"``. The leading and trailing quotes from the
+ template tag are removed in ``format_string[1:-1]``.
+
+ * The parsing is very low-level. The Django developers have experimented
+ with writing small frameworks on top of this parsing system, using
+ techniques such as EBNF grammars, but those experiments made the template
+ engine too slow. It's low-level because that's fastest.
+
+Writing the renderer
+~~~~~~~~~~~~~~~~~~~~
+
+The second step in writing custom tags is to define a ``Node`` subclass that
+has a ``render()`` method.
+
+Continuing the above example, we need to define ``CurrentTimeNode``::
+
+ from django import template
+ import datetime
+ class CurrentTimeNode(template.Node):
+ def __init__(self, format_string):
+ self.format_string = format_string
+ def render(self, context):
+ return datetime.datetime.now().strftime(self.format_string)
+
+Notes:
+
+ * ``__init__()`` gets the ``format_string`` from ``do_current_time()``.
+ Always pass any options/parameters/arguments to a ``Node`` via its
+ ``__init__()``.
+
+ * The ``render()`` method is where the work actually happens.
+
+ * ``render()`` should never raise ``TemplateSyntaxError`` or any other
+ exception. It should fail silently, just as template filters should.
+
+Ultimately, this decoupling of compilation and rendering results in an
+efficient template system, because a template can render multiple contexts
+without having to be parsed multiple times.
+
+Auto-escaping considerations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.0
+
+The output from template tags is **not** automatically run through the
+auto-escaping filters. However, there are still a couple of things you should
+keep in mind when writing a template tag.
+
+If the ``render()`` function of your template stores the result in a context
+variable (rather than returning the result in a string), it should take care
+to call ``mark_safe()`` if appropriate. When the variable is ultimately
+rendered, it will be affected by the auto-escape setting in effect at the
+time, so content that should be safe from further escaping needs to be marked
+as such.
+
+Also, if your template tag creates a new context for performing some
+sub-rendering, set the auto-escape attribute to the current context's value.
+The ``__init__`` method for the ``Context`` class takes a parameter called
+``autoescape`` that you can use for this purpose. For example::
+
+ def render(self, context):
+ # ...
+ new_context = Context({'var': obj}, autoescape=context.autoescape)
+ # ... Do something with new_context ...
+
+This is not a very common situation, but it's useful if you're rendering a
+template yourself. For example::
+
+ def render(self, context):
+ t = template.loader.get_template('small_fragment.html')
+ return t.render(Context({'var': obj}, autoescape=context.autoescape))
+
+If we had neglected to pass in the current ``context.autoescape`` value to our
+new ``Context`` in this example, the results would have *always* been
+automatically escaped, which may not be the desired behavior if the template
+tag is used inside a ``{% autoescape off %}`` block.
+
+.. _template_tag_thread_safety:
+
+Thread-safety considerations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. versionadded:: 1.2
+
+Once a node is parsed, its ``render`` method may be called any number of times.
+Since Django is sometimes run in multi-threaded environments, a single node may
+be simultaneously rendering with different contexts in response to two separate
+requests. Therefore, it's important to make sure your template tags are thread
+safe.
+
+To make sure your template tags are thread safe, you should never store state
+information on the node itself. For example, Django provides a builtin ``cycle``
+template tag that cycles among a list of given strings each time it's rendered::
+
+ {% for o in some_list %}
+ <tr class="{% cycle 'row1' 'row2' %}>
+ ...
+ </tr>
+ {% endfor %}
+
+A naive implementation of ``CycleNode`` might look something like this::
+
+ class CycleNode(Node):
+ def __init__(self, cyclevars):
+ self.cycle_iter = itertools.cycle(cyclevars)
+ def render(self, context):
+ return self.cycle_iter.next()
+
+But, suppose we have two templates rendering the template snippet from above at
+the same time:
+
+ 1. Thread 1 performs its first loop iteration, ``CycleNode.render()``
+ returns 'row1'
+ 2. Thread 2 performs its first loop iteration, ``CycleNode.render()``
+ returns 'row2'
+ 3. Thread 1 performs its second loop iteration, ``CycleNode.render()``
+ returns 'row1'
+ 4. Thread 2 performs its second loop iteration, ``CycleNode.render()``
+ returns 'row2'
+
+The CycleNode is iterating, but it's iterating globally. As far as Thread 1
+and Thread 2 are concerned, it's always returning the same value. This is
+obviously not what we want!
+
+To address this problem, Django provides a ``render_context`` that's associated
+with the ``context`` of the template that is currently being rendered. The
+``render_context`` behaves like a Python dictionary, and should be used to store
+``Node`` state between invocations of the ``render`` method.
+
+Let's refactor our ``CycleNode`` implementation to use the ``render_context``::
+
+ class CycleNode(Node):
+ def __init__(self, cyclevars):
+ self.cyclevars = cyclevars
+ def render(self, context):
+ if self not in context.render_context:
+ context.render_context[self] = itertools.cycle(self.cyclevars)
+ cycle_iter = context.render_context[self]
+ return cycle_iter.next()
+
+Note that it's perfectly safe to store global information that will not change
+throughout the life of the ``Node`` as an attribute. In the case of
+``CycleNode``, the ``cyclevars`` argument doesn't change after the ``Node`` is
+instantiated, so we don't need to put it in the ``render_context``. But state
+information that is specific to the template that is currently being rendered,
+like the current iteration of the ``CycleNode``, should be stored in the
+``render_context``.
+
+.. note::
+ Notice how we used ``self`` to scope the ``CycleNode`` specific information
+ within the ``render_context``. There may be multiple ``CycleNodes`` in a
+ given template, so we need to be careful not to clobber another node's state
+ information. The easiest way to do this is to always use ``self`` as the key
+ into ``render_context``. If you're keeping track of several state variables,
+ make ``render_context[self]`` a dictionary.
+
+Registering the tag
+~~~~~~~~~~~~~~~~~~~
+
+Finally, register the tag with your module's ``Library`` instance, as explained
+in "Writing custom template filters" above. Example::
+
+ register.tag('current_time', do_current_time)
+
+The ``tag()`` method takes two arguments:
+
+ 1. The name of the template tag -- a string. If this is left out, the
+ name of the compilation function will be used.
+ 2. The compilation function -- a Python function (not the name of the
+ function as a string).
+
+As with filter registration, it is also possible to use this as a decorator::
+
+ @register.tag(name="current_time")
+ def do_current_time(parser, token):
+ # ...
+
+ @register.tag
+ def shout(parser, token):
+ # ...
+
+If you leave off the ``name`` argument, as in the second example above, Django
+will use the function's name as the tag name.
+
+Passing template variables to the tag
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Although you can pass any number of arguments to a template tag using
+``token.split_contents()``, the arguments are all unpacked as
+string literals. A little more work is required in order to pass dynamic
+content (a template variable) to a template tag as an argument.
+
+While the previous examples have formatted the current time into a string and
+returned the string, suppose you wanted to pass in a ``DateTimeField`` from an
+object and have the template tag format that date-time:
+
+.. code-block:: html+django
+
+ <p>This post was last updated at {% format_time blog_entry.date_updated "%Y-%m-%d %I:%M %p" %}.</p>
+
+Initially, ``token.split_contents()`` will return three values:
+
+ 1. The tag name ``format_time``.
+ 2. The string "blog_entry.date_updated" (without the surrounding quotes).
+ 3. The formatting string "%Y-%m-%d %I:%M %p". The return value from
+ ``split_contents()`` will include the leading and trailing quotes for
+ string literals like this.
+
+Now your tag should begin to look like this::
+
+ from django import template
+ def do_format_time(parser, token):
+ try:
+ # split_contents() knows not to split quoted strings.
+ tag_name, date_to_be_formatted, format_string = token.split_contents()
+ except ValueError:
+ raise template.TemplateSyntaxError, "%r tag requires exactly two arguments" % token.contents.split()[0]
+ if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")):
+ raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name
+ return FormatTimeNode(date_to_be_formatted, format_string[1:-1])
+
+.. versionchanged:: 1.0
+ Variable resolution has changed in the 1.0 release of Django. ``template.resolve_variable()``
+ has been deprecated in favor of a new ``template.Variable`` class.
+
+You also have to change the renderer to retrieve the actual contents of the
+``date_updated`` property of the ``blog_entry`` object. This can be
+accomplished by using the ``Variable()`` class in ``django.template``.
+
+To use the ``Variable`` class, simply instantiate it with the name of the
+variable to be resolved, and then call ``variable.resolve(context)``. So,
+for example::
+
+ class FormatTimeNode(template.Node):
+ def __init__(self, date_to_be_formatted, format_string):
+ self.date_to_be_formatted = template.Variable(date_to_be_formatted)
+ self.format_string = format_string
+
+ def render(self, context):
+ try:
+ actual_date = self.date_to_be_formatted.resolve(context)
+ return actual_date.strftime(self.format_string)
+ except template.VariableDoesNotExist:
+ return ''
+
+Variable resolution will throw a ``VariableDoesNotExist`` exception if it cannot
+resolve the string passed to it in the current context of the page.
+
+Shortcut for simple tags
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Many template tags take a number of arguments -- strings or a template variables
+-- and return a string after doing some processing based solely on
+the input argument and some external information. For example, the
+``current_time`` tag we wrote above is of this variety: we give it a format
+string, it returns the time as a string.
+
+To ease the creation of the types of tags, Django provides a helper function,
+``simple_tag``. This function, which is a method of
+``django.template.Library``, takes a function that accepts any number of
+arguments, wraps it in a ``render`` function and the other necessary bits
+mentioned above and registers it with the template system.
+
+Our earlier ``current_time`` function could thus be written like this::
+
+ def current_time(format_string):
+ return datetime.datetime.now().strftime(format_string)
+
+ register.simple_tag(current_time)
+
+The decorator syntax also works::
+
+ @register.simple_tag
+ def current_time(format_string):
+ ...
+
+A couple of things to note about the ``simple_tag`` helper function:
+
+ * Checking for the required number of arguments, etc., has already been
+ done by the time our function is called, so we don't need to do that.
+ * The quotes around the argument (if any) have already been stripped away,
+ so we just receive a plain string.
+ * If the argument was a template variable, our function is passed the
+ current value of the variable, not the variable itself.
+
+When your template tag does not need access to the current context, writing a
+function to work with the input values and using the ``simple_tag`` helper is
+the easiest way to create a new tag.
+
+.. _howto-custom-template-tags-inclusion-tags:
+
+Inclusion tags
+~~~~~~~~~~~~~~
+
+Another common type of template tag is the type that displays some data by
+rendering *another* template. For example, Django's admin interface uses custom
+template tags to display the buttons along the bottom of the "add/change" form
+pages. Those buttons always look the same, but the link targets change depending
+on the object being edited -- so they're a perfect case for using a small
+template that is filled with details from the current object. (In the admin's
+case, this is the ``submit_row`` tag.)
+
+These sorts of tags are called "inclusion tags".
+
+Writing inclusion tags is probably best demonstrated by example. Let's write a
+tag that outputs a list of choices for a given ``Poll`` object, such as was
+created in the :ref:`tutorials <creating-models>`. We'll use the tag like this:
+
+.. code-block:: html+django
+
+ {% show_results poll %}
+
+...and the output will be something like this:
+
+.. code-block:: html
+
+ <ul>
+ <li>First choice</li>
+ <li>Second choice</li>
+ <li>Third choice</li>
+ </ul>
+
+First, define the function that takes the argument and produces a dictionary of
+data for the result. The important point here is we only need to return a
+dictionary, not anything more complex. This will be used as a template context
+for the template fragment. Example::
+
+ def show_results(poll):
+ choices = poll.choice_set.all()
+ return {'choices': choices}
+
+Next, create the template used to render the tag's output. This template is a
+fixed feature of the tag: the tag writer specifies it, not the template
+designer. Following our example, the template is very simple:
+
+.. code-block:: html+django
+
+ <ul>
+ {% for choice in choices %}
+ <li> {{ choice }} </li>
+ {% endfor %}
+ </ul>
+
+Now, create and register the inclusion tag by calling the ``inclusion_tag()``
+method on a ``Library`` object. Following our example, if the above template is
+in a file called ``results.html`` in a directory that's searched by the template
+loader, we'd register the tag like this::
+
+ # Here, register is a django.template.Library instance, as before
+ register.inclusion_tag('results.html')(show_results)
+
+As always, decorator syntax works as well, so we could have written::
+
+ @register.inclusion_tag('results.html')
+ def show_results(poll):
+ ...
+
+...when first creating the function.
+
+Sometimes, your inclusion tags might require a large number of arguments,
+making it a pain for template authors to pass in all the arguments and remember
+their order. To solve this, Django provides a ``takes_context`` option for
+inclusion tags. If you specify ``takes_context`` in creating a template tag,
+the tag will have no required arguments, and the underlying Python function
+will have one argument -- the template context as of when the tag was called.
+
+For example, say you're writing an inclusion tag that will always be used in a
+context that contains ``home_link`` and ``home_title`` variables that point
+back to the main page. Here's what the Python function would look like::
+
+ # The first argument *must* be called "context" here.
+ def jump_link(context):
+ return {
+ 'link': context['home_link'],
+ 'title': context['home_title'],
+ }
+ # Register the custom tag as an inclusion tag with takes_context=True.
+ register.inclusion_tag('link.html', takes_context=True)(jump_link)
+
+(Note that the first parameter to the function *must* be called ``context``.)
+
+In that ``register.inclusion_tag()`` line, we specified ``takes_context=True``
+and the name of the template. Here's what the template ``link.html`` might look
+like:
+
+.. code-block:: html+django
+
+ Jump directly to <a href="{{ link }}">{{ title }}</a>.
+
+Then, any time you want to use that custom tag, load its library and call it
+without any arguments, like so:
+
+.. code-block:: html+django
+
+ {% jump_link %}
+
+Note that when you're using ``takes_context=True``, there's no need to pass
+arguments to the template tag. It automatically gets access to the context.
+
+The ``takes_context`` parameter defaults to ``False``. When it's set to *True*,
+the tag is passed the context object, as in this example. That's the only
+difference between this case and the previous ``inclusion_tag`` example.
+
+Setting a variable in the context
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The above examples simply output a value. Generally, it's more flexible if your
+template tags set template variables instead of outputting values. That way,
+template authors can reuse the values that your template tags create.
+
+To set a variable in the context, just use dictionary assignment on the context
+object in the ``render()`` method. Here's an updated version of
+``CurrentTimeNode`` that sets a template variable ``current_time`` instead of
+outputting it::
+
+ class CurrentTimeNode2(template.Node):
+ def __init__(self, format_string):
+ self.format_string = format_string
+ def render(self, context):
+ context['current_time'] = datetime.datetime.now().strftime(self.format_string)
+ return ''
+
+Note that ``render()`` returns the empty string. ``render()`` should always
+return string output. If all the template tag does is set a variable,
+``render()`` should return the empty string.
+
+Here's how you'd use this new version of the tag:
+
+.. code-block:: html+django
+
+ {% current_time "%Y-%M-%d %I:%M %p" %}<p>The time is {{ current_time }}.</p>
+
+.. admonition:: Variable scope in context
+
+ Any variable set in the context will only be available in the same ``block``
+ of the template in which it was assigned. This behaviour is intentional;
+ it provides a scope for variables so that they don't conflict with
+ context in other blocks.
+
+But, there's a problem with ``CurrentTimeNode2``: The variable name
+``current_time`` is hard-coded. This means you'll need to make sure your
+template doesn't use ``{{ current_time }}`` anywhere else, because the
+``{% current_time %}`` will blindly overwrite that variable's value. A cleaner
+solution is to make the template tag specify the name of the output variable,
+like so:
+
+.. code-block:: html+django
+
+ {% current_time "%Y-%M-%d %I:%M %p" as my_current_time %}
+ <p>The current time is {{ my_current_time }}.</p>
+
+To do that, you'll need to refactor both the compilation function and ``Node``
+class, like so::
+
+ class CurrentTimeNode3(template.Node):
+ def __init__(self, format_string, var_name):
+ self.format_string = format_string
+ self.var_name = var_name
+ def render(self, context):
+ context[self.var_name] = datetime.datetime.now().strftime(self.format_string)
+ return ''
+
+ import re
+ def do_current_time(parser, token):
+ # This version uses a regular expression to parse tag contents.
+ try:
+ # Splitting by None == splitting by spaces.
+ tag_name, arg = token.contents.split(None, 1)
+ except ValueError:
+ raise template.TemplateSyntaxError, "%r tag requires arguments" % token.contents.split()[0]
+ m = re.search(r'(.*?) as (\w+)', arg)
+ if not m:
+ raise template.TemplateSyntaxError, "%r tag had invalid arguments" % tag_name
+ format_string, var_name = m.groups()
+ if not (format_string[0] == format_string[-1] and format_string[0] in ('"', "'")):
+ raise template.TemplateSyntaxError, "%r tag's argument should be in quotes" % tag_name
+ return CurrentTimeNode3(format_string[1:-1], var_name)
+
+The difference here is that ``do_current_time()`` grabs the format string and
+the variable name, passing both to ``CurrentTimeNode3``.
+
+Parsing until another block tag
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Template tags can work in tandem. For instance, the standard ``{% comment %}``
+tag hides everything until ``{% endcomment %}``. To create a template tag such
+as this, use ``parser.parse()`` in your compilation function.
+
+Here's how the standard ``{% comment %}`` tag is implemented::
+
+ def do_comment(parser, token):
+ nodelist = parser.parse(('endcomment',))
+ parser.delete_first_token()
+ return CommentNode()
+
+ class CommentNode(template.Node):
+ def render(self, context):
+ return ''
+
+``parser.parse()`` takes a tuple of names of block tags ''to parse until''. It
+returns an instance of ``django.template.NodeList``, which is a list of
+all ``Node`` objects that the parser encountered ''before'' it encountered
+any of the tags named in the tuple.
+
+In ``"nodelist = parser.parse(('endcomment',))"`` in the above example,
+``nodelist`` is a list of all nodes between the ``{% comment %}`` and
+``{% endcomment %}``, not counting ``{% comment %}`` and ``{% endcomment %}``
+themselves.
+
+After ``parser.parse()`` is called, the parser hasn't yet "consumed" the
+``{% endcomment %}`` tag, so the code needs to explicitly call
+``parser.delete_first_token()``.
+
+``CommentNode.render()`` simply returns an empty string. Anything between
+``{% comment %}`` and ``{% endcomment %}`` is ignored.
+
+Parsing until another block tag, and saving contents
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+In the previous example, ``do_comment()`` discarded everything between
+``{% comment %}`` and ``{% endcomment %}``. Instead of doing that, it's
+possible to do something with the code between block tags.
+
+For example, here's a custom template tag, ``{% upper %}``, that capitalizes
+everything between itself and ``{% endupper %}``.
+
+Usage:
+
+.. code-block:: html+django
+
+ {% upper %}This will appear in uppercase, {{ your_name }}.{% endupper %}
+
+As in the previous example, we'll use ``parser.parse()``. But this time, we
+pass the resulting ``nodelist`` to the ``Node``::
+
+ def do_upper(parser, token):
+ nodelist = parser.parse(('endupper',))
+ parser.delete_first_token()
+ return UpperNode(nodelist)
+
+ class UpperNode(template.Node):
+ def __init__(self, nodelist):
+ self.nodelist = nodelist
+ def render(self, context):
+ output = self.nodelist.render(context)
+ return output.upper()
+
+The only new concept here is the ``self.nodelist.render(context)`` in
+``UpperNode.render()``.
+
+For more examples of complex rendering, see the source code for ``{% if %}``,
+``{% for %}``, ``{% ifequal %}`` and ``{% ifchanged %}``. They live in
+``django/template/defaulttags.py``.
diff --git a/parts/django/docs/howto/deployment/fastcgi.txt b/parts/django/docs/howto/deployment/fastcgi.txt
new file mode 100644
index 0000000..ea14b97
--- /dev/null
+++ b/parts/django/docs/howto/deployment/fastcgi.txt
@@ -0,0 +1,400 @@
+============================================
+How to use Django with FastCGI, SCGI, or AJP
+============================================
+
+.. highlight:: bash
+
+Although the current preferred setup for running Django is :doc:`Apache with
+mod_wsgi </howto/deployment/modwsgi>`, many people use shared hosting, on
+which protocols such as FastCGI, SCGI or AJP are the only viable options. In
+some setups, these protocols may provide better performance than mod_wsgi_.
+
+.. admonition:: Note
+
+ This document primarily focuses on FastCGI. Other protocols, such as SCGI
+ and AJP, are also supported, through the ``flup`` Python package. See the
+ Protocols_ section below for specifics about SCGI and AJP.
+
+Essentially, FastCGI is an efficient way of letting an external application
+serve pages to a Web server. The Web server delegates the incoming Web requests
+(via a socket) to FastCGI, which executes the code and passes the response back
+to the Web server, which, in turn, passes it back to the client's Web browser.
+
+Like mod_python, FastCGI allows code to stay in memory, allowing requests to be
+served with no startup time. Unlike mod_python_ (or `mod_perl`_), a FastCGI
+process doesn't run inside the Web server process, but in a separate,
+persistent process.
+
+.. _mod_wsgi: http://code.google.com/p/modwsgi/
+.. _mod_perl: http://perl.apache.org/
+.. _mod_python: http://www.modpython.org/
+
+.. admonition:: Why run code in a separate process?
+
+ The traditional ``mod_*`` arrangements in Apache embed various scripting
+ languages (most notably PHP, Python and Perl) inside the process space of
+ your Web server. Although this lowers startup time -- because code doesn't
+ have to be read off disk for every request -- it comes at the cost of
+ memory use. For mod_python, for example, every Apache process gets its own
+ Python interpreter, which uses up a considerable amount of RAM.
+
+ Due to the nature of FastCGI, it's even possible to have processes that run
+ under a different user account than the Web server process. That's a nice
+ security benefit on shared systems, because it means you can secure your
+ code from other users.
+
+Prerequisite: flup
+==================
+
+Before you can start using FastCGI with Django, you'll need to install flup_, a
+Python library for dealing with FastCGI. Version 0.5 or newer should work fine.
+
+.. _flup: http://www.saddi.com/software/flup/
+
+Starting your FastCGI server
+============================
+
+FastCGI operates on a client-server model, and in most cases you'll be starting
+the FastCGI process on your own. Your Web server (be it Apache, lighttpd, or
+otherwise) only contacts your Django-FastCGI process when the server needs a
+dynamic page to be loaded. Because the daemon is already running with the code
+in memory, it's able to serve the response very quickly.
+
+.. admonition:: Note
+
+ If you're on a shared hosting system, you'll probably be forced to use
+ Web server-managed FastCGI processes. See the section below on running
+ Django with Web server-managed processes for more information.
+
+A Web server can connect to a FastCGI server in one of two ways: It can use
+either a Unix domain socket (a "named pipe" on Win32 systems), or it can use a
+TCP socket. What you choose is a manner of preference; a TCP socket is usually
+easier due to permissions issues.
+
+To start your server, first change into the directory of your project (wherever
+your :doc:`manage.py </ref/django-admin>` is), and then run the
+:djadmin:`runfcgi` command::
+
+ ./manage.py runfcgi [options]
+
+If you specify ``help`` as the only option after :djadmin:`runfcgi`, it'll
+display a list of all the available options.
+
+You'll need to specify either a :djadminopt:`socket`, a :djadminopt:`protocol`
+or both :djadminopt:`host` and :djadminopt:`port`. Then, when you set up your
+Web server, you'll just need to point it at the host/port or socket you
+specified when starting the FastCGI server. See the examples_, below.
+
+Protocols
+---------
+
+Django supports all the protocols that flup_ does, namely fastcgi_, `SCGI`_ and
+`AJP1.3`_ (the Apache JServ Protocol, version 1.3). Select your preferred
+protocol by using the :djadminopt:`protocol=\<protocol_name\> <protocol>` option
+with ``./manage.py runfcgi`` -- where ``<protocol_name>`` may be one of:
+``fcgi`` (the default), ``scgi`` or ``ajp``. For example::
+
+ ./manage.py runfcgi protocol=scgi
+
+.. _flup: http://www.saddi.com/software/flup/
+.. _fastcgi: http://www.fastcgi.com/
+.. _SCGI: http://python.ca/scgi/protocol.txt
+.. _AJP1.3: http://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html
+
+Examples
+--------
+
+Running a threaded server on a TCP port::
+
+ ./manage.py runfcgi method=threaded host=127.0.0.1 port=3033
+
+Running a preforked server on a Unix domain socket::
+
+ ./manage.py runfcgi method=prefork socket=/home/user/mysite.sock pidfile=django.pid
+
+.. admonition:: Socket security
+
+ Django's default umask requires that the webserver and the Django fastcgi
+ process be run with the same group **and** user. For increased security,
+ you can run them under the same group but as different users. If you do
+ this, you will need to set the umask to 0002 using the ``umask`` argument
+ to ``runfcgi``.
+
+Run without daemonizing (backgrounding) the process (good for debugging)::
+
+ ./manage.py runfcgi daemonize=false socket=/tmp/mysite.sock maxrequests=1
+
+Stopping the FastCGI daemon
+---------------------------
+
+If you have the process running in the foreground, it's easy enough to stop it:
+Simply hitting ``Ctrl-C`` will stop and quit the FastCGI server. However, when
+you're dealing with background processes, you'll need to resort to the Unix
+``kill`` command.
+
+If you specify the :djadminopt:`pidfile` option to :djadmin:`runfcgi`, you can
+kill the running FastCGI daemon like this::
+
+ kill `cat $PIDFILE`
+
+...where ``$PIDFILE`` is the ``pidfile`` you specified.
+
+To easily restart your FastCGI daemon on Unix, try this small shell script::
+
+ #!/bin/bash
+
+ # Replace these three settings.
+ PROJDIR="/home/user/myproject"
+ PIDFILE="$PROJDIR/mysite.pid"
+ SOCKET="$PROJDIR/mysite.sock"
+
+ cd $PROJDIR
+ if [ -f $PIDFILE ]; then
+ kill `cat -- $PIDFILE`
+ rm -f -- $PIDFILE
+ fi
+
+ exec /usr/bin/env - \
+ PYTHONPATH="../python:.." \
+ ./manage.py runfcgi socket=$SOCKET pidfile=$PIDFILE
+
+Apache setup
+============
+
+To use Django with Apache and FastCGI, you'll need Apache installed and
+configured, with `mod_fastcgi`_ installed and enabled. Consult the Apache
+documentation for instructions.
+
+Once you've got that set up, point Apache at your Django FastCGI instance by
+editing the ``httpd.conf`` (Apache configuration) file. You'll need to do two
+things:
+
+ * Use the ``FastCGIExternalServer`` directive to specify the location of
+ your FastCGI server.
+ * Use ``mod_rewrite`` to point URLs at FastCGI as appropriate.
+
+.. _mod_fastcgi: http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html
+
+Specifying the location of the FastCGI server
+---------------------------------------------
+
+The ``FastCGIExternalServer`` directive tells Apache how to find your FastCGI
+server. As the `FastCGIExternalServer docs`_ explain, you can specify either a
+``socket`` or a ``host``. Here are examples of both:
+
+.. code-block:: apache
+
+ # Connect to FastCGI via a socket / named pipe.
+ FastCGIExternalServer /home/user/public_html/mysite.fcgi -socket /home/user/mysite.sock
+
+ # Connect to FastCGI via a TCP host/port.
+ FastCGIExternalServer /home/user/public_html/mysite.fcgi -host 127.0.0.1:3033
+
+In either case, the file ``/home/user/public_html/mysite.fcgi`` doesn't
+actually have to exist. It's just a URL used by the Web server internally -- a
+hook for signifying which requests at a URL should be handled by FastCGI. (More
+on this in the next section.)
+
+.. _FastCGIExternalServer docs: http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html#FastCgiExternalServer
+
+Using mod_rewrite to point URLs at FastCGI
+------------------------------------------
+
+The second step is telling Apache to use FastCGI for URLs that match a certain
+pattern. To do this, use the `mod_rewrite`_ module and rewrite URLs to
+``mysite.fcgi`` (or whatever you specified in the ``FastCGIExternalServer``
+directive, as explained in the previous section).
+
+In this example, we tell Apache to use FastCGI to handle any request that
+doesn't represent a file on the filesystem and doesn't start with ``/media/``.
+This is probably the most common case, if you're using Django's admin site:
+
+.. code-block:: apache
+
+ <VirtualHost 12.34.56.78>
+ ServerName example.com
+ DocumentRoot /home/user/public_html
+ Alias /media /home/user/python/django/contrib/admin/media
+ RewriteEngine On
+ RewriteRule ^/(media.*)$ /$1 [QSA,L,PT]
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteRule ^/(.*)$ /mysite.fcgi/$1 [QSA,L]
+ </VirtualHost>
+
+.. _mod_rewrite: http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html
+
+Django will automatically use the pre-rewrite version of the URL when
+constructing URLs with the ``{% url %}`` template tag (and similar methods).
+
+lighttpd setup
+==============
+
+lighttpd_ is a lightweight Web server commonly used for serving static files. It
+supports FastCGI natively and, thus, is a good choice for serving both static
+and dynamic pages, if your site doesn't have any Apache-specific needs.
+
+.. _lighttpd: http://www.lighttpd.net/
+
+Make sure ``mod_fastcgi`` is in your modules list, somewhere after
+``mod_rewrite`` and ``mod_access``, but not after ``mod_accesslog``. You'll
+probably want ``mod_alias`` as well, for serving admin media.
+
+Add the following to your lighttpd config file:
+
+.. code-block:: lua
+
+ server.document-root = "/home/user/public_html"
+ fastcgi.server = (
+ "/mysite.fcgi" => (
+ "main" => (
+ # Use host / port instead of socket for TCP fastcgi
+ # "host" => "127.0.0.1",
+ # "port" => 3033,
+ "socket" => "/home/user/mysite.sock",
+ "check-local" => "disable",
+ )
+ ),
+ )
+ alias.url = (
+ "/media" => "/home/user/django/contrib/admin/media/",
+ )
+
+ url.rewrite-once = (
+ "^(/media.*)$" => "$1",
+ "^/favicon\.ico$" => "/media/favicon.ico",
+ "^(/.*)$" => "/mysite.fcgi$1",
+ )
+
+Running multiple Django sites on one lighttpd
+---------------------------------------------
+
+lighttpd lets you use "conditional configuration" to allow configuration to be
+customized per host. To specify multiple FastCGI sites, just add a conditional
+block around your FastCGI config for each site::
+
+ # If the hostname is 'www.example1.com'...
+ $HTTP["host"] == "www.example1.com" {
+ server.document-root = "/foo/site1"
+ fastcgi.server = (
+ ...
+ )
+ ...
+ }
+
+ # If the hostname is 'www.example2.com'...
+ $HTTP["host"] == "www.example2.com" {
+ server.document-root = "/foo/site2"
+ fastcgi.server = (
+ ...
+ )
+ ...
+ }
+
+You can also run multiple Django installations on the same site simply by
+specifying multiple entries in the ``fastcgi.server`` directive. Add one
+FastCGI host for each.
+
+Cherokee setup
+==============
+
+Cherokee is a very fast, flexible and easy to configure Web Server. It
+supports the widespread technologies nowadays: FastCGI, SCGI, PHP, CGI, SSI,
+TLS and SSL encrypted connections, Virtual hosts, Authentication, on the fly
+encoding, Load Balancing, Apache compatible log files, Data Base Balancer,
+Reverse HTTP Proxy and much more.
+
+The Cherokee project provides a documentation to `setting up Django`_ with Cherokee.
+
+.. _setting up Django: http://www.cherokee-project.com/doc/cookbook_django.html
+
+Running Django on a shared-hosting provider with Apache
+=======================================================
+
+Many shared-hosting providers don't allow you to run your own server daemons or
+edit the ``httpd.conf`` file. In these cases, it's still possible to run Django
+using Web server-spawned processes.
+
+.. admonition:: Note
+
+ If you're using Web server-spawned processes, as explained in this section,
+ there's no need for you to start the FastCGI server on your own. Apache
+ will spawn a number of processes, scaling as it needs to.
+
+In your Web root directory, add this to a file named ``.htaccess``:
+
+.. code-block:: apache
+
+ AddHandler fastcgi-script .fcgi
+ RewriteEngine On
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteRule ^(.*)$ mysite.fcgi/$1 [QSA,L]
+
+Then, create a small script that tells Apache how to spawn your FastCGI
+program. Create a file ``mysite.fcgi`` and place it in your Web directory, and
+be sure to make it executable:
+
+.. code-block:: python
+
+ #!/usr/bin/python
+ import sys, os
+
+ # Add a custom Python path.
+ sys.path.insert(0, "/home/user/python")
+
+ # Switch to the directory of your project. (Optional.)
+ # os.chdir("/home/user/myproject")
+
+ # Set the DJANGO_SETTINGS_MODULE environment variable.
+ os.environ['DJANGO_SETTINGS_MODULE'] = "myproject.settings"
+
+ from django.core.servers.fastcgi import runfastcgi
+ runfastcgi(method="threaded", daemonize="false")
+
+Restarting the spawned server
+-----------------------------
+
+If you change any Python code on your site, you'll need to tell FastCGI the
+code has changed. But there's no need to restart Apache in this case. Rather,
+just reupload ``mysite.fcgi``, or edit the file, so that the timestamp on the
+file will change. When Apache sees the file has been updated, it will restart
+your Django application for you.
+
+If you have access to a command shell on a Unix system, you can accomplish this
+easily by using the ``touch`` command::
+
+ touch mysite.fcgi
+
+Serving admin media files
+=========================
+
+Regardless of the server and configuration you eventually decide to use, you
+will also need to give some thought to how to serve the admin media files. The
+advice given in the :ref:`modpython <serving-the-admin-files>` documentation
+is also applicable in the setups detailed above.
+
+Forcing the URL prefix to a particular value
+============================================
+
+Because many of these fastcgi-based solutions require rewriting the URL at
+some point inside the Web server, the path information that Django sees may not
+resemble the original URL that was passed in. This is a problem if the Django
+application is being served from under a particular prefix and you want your
+URLs from the ``{% url %}`` tag to look like the prefix, rather than the
+rewritten version, which might contain, for example, ``mysite.fcgi``.
+
+Django makes a good attempt to work out what the real script name prefix
+should be. In particular, if the Web server sets the ``SCRIPT_URL`` (specific
+to Apache's mod_rewrite), or ``REDIRECT_URL`` (set by a few servers, including
+Apache + mod_rewrite in some situations), Django will work out the original
+prefix automatically.
+
+In the cases where Django cannot work out the prefix correctly and where you
+want the original value to be used in URLs, you can set the
+:setting:`FORCE_SCRIPT_NAME` setting in your main ``settings`` file. This sets the
+script name uniformly for every URL served via that settings file. Thus you'll
+need to use different settings files if you want different sets of URLs to
+have different script names in this case, but that is a rare situation.
+
+As an example of how to use it, if your Django configuration is serving all of
+the URLs under ``'/'`` and you wanted to use this setting, you would set
+``FORCE_SCRIPT_NAME = ''`` in your settings file.
diff --git a/parts/django/docs/howto/deployment/index.txt b/parts/django/docs/howto/deployment/index.txt
new file mode 100644
index 0000000..740f9bc
--- /dev/null
+++ b/parts/django/docs/howto/deployment/index.txt
@@ -0,0 +1,25 @@
+Deploying Django
+================
+
+Django's chock-full of shortcuts to make Web developer's lives easier, but all
+those tools are of no use if you can't easily deploy your sites. Since Django's
+inception, ease of deployment has been a major goal. There's a number of good
+ways to easily deploy Django:
+
+.. toctree::
+ :maxdepth: 1
+
+ modwsgi
+ modpython
+ fastcgi
+
+If you're new to deploying Django and/or Python, we'd recommend you try
+:doc:`mod_wsgi </howto/deployment/modwsgi>` first. In most cases it'll be the easiest,
+fastest, and most stable deployment choice.
+
+.. seealso::
+
+ * `Chapter 12 of The Django Book`_ discusses deployment and especially
+ scaling in more detail.
+
+.. _chapter 12 of the django book: http://djangobook.com/en/2.0/chapter12/
diff --git a/parts/django/docs/howto/deployment/modpython.txt b/parts/django/docs/howto/deployment/modpython.txt
new file mode 100644
index 0000000..ba55335
--- /dev/null
+++ b/parts/django/docs/howto/deployment/modpython.txt
@@ -0,0 +1,418 @@
+.. _howto-deployment-modpython:
+
+============================================
+How to use Django with Apache and mod_python
+============================================
+
+.. warning::
+
+ Support for mod_python will be deprecated in a future release of Django. If
+ you are configuring a new deployment, you are strongly encouraged to
+ consider using :doc:`mod_wsgi </howto/deployment/modwsgi>` or any of the
+ other :doc:`supported backends </howto/deployment/index>`.
+
+.. highlight:: apache
+
+The `mod_python`_ module for Apache_ can be used to deploy Django to a
+production server, although it has been mostly superseded by the simpler
+:doc:`mod_wsgi deployment option </howto/deployment/modwsgi>`.
+
+mod_python is similar to (and inspired by) `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.
+
+Django requires Apache 2.x and mod_python 3.x, and you should use Apache's
+`prefork MPM`_, as opposed to the `worker MPM`_.
+
+.. seealso::
+
+ * Apache is a big, complex animal, and this document only scratches the
+ surface of what Apache can do. If you need more advanced information about
+ Apache, there's no better source than `Apache's own official
+ documentation`_
+
+ * You may also be interested in :doc:`How to use Django with FastCGI, SCGI,
+ or AJP </howto/deployment/fastcgi>`.
+
+.. _Apache: http://httpd.apache.org/
+.. _mod_python: http://www.modpython.org/
+.. _mod_perl: http://perl.apache.org/
+.. _prefork MPM: http://httpd.apache.org/docs/2.2/mod/prefork.html
+.. _worker MPM: http://httpd.apache.org/docs/2.2/mod/worker.html
+.. _apache's own official documentation: http://httpd.apache.org/docs/
+
+Basic configuration
+===================
+
+To configure Django with mod_python, first make sure you have Apache installed,
+with the mod_python module activated.
+
+Then edit your ``httpd.conf`` file and add the following::
+
+ <Location "/mysite/">
+ SetHandler python-program
+ PythonHandler django.core.handlers.modpython
+ SetEnv DJANGO_SETTINGS_MODULE mysite.settings
+ PythonOption django.root /mysite
+ PythonDebug On
+ </Location>
+
+...and replace ``mysite.settings`` with the Python import path to your Django
+project's settings file.
+
+This tells Apache: "Use mod_python for any URL at or under '/mysite/', using the
+Django mod_python handler." It passes the value of :ref:`DJANGO_SETTINGS_MODULE
+<django-settings-module>` so mod_python knows which settings to use.
+
+.. versionadded:: 1.0
+ The ``PythonOption django.root ...`` is new in this version.
+
+Because mod_python does not know we are serving this site from underneath the
+``/mysite/`` prefix, this value needs to be passed through to the mod_python
+handler in Django, via the ``PythonOption django.root ...`` line. The value set
+on that line (the last item) should match the string given in the ``<Location
+...>`` directive. The effect of this is that Django will automatically strip the
+``/mysite`` string from the front of any URLs before matching them against your
+URLconf patterns. If you later move your site to live under ``/mysite2``, you
+will not have to change anything except the ``django.root`` option in the config
+file.
+
+When using ``django.root`` you should make sure that what's left, after the
+prefix has been removed, begins with a slash. Your URLconf patterns that are
+expecting an initial slash will then work correctly. In the above example,
+since we want to send things like ``/mysite/admin/`` to ``/admin/``, we need
+to remove the string ``/mysite`` from the beginning, so that is the
+``django.root`` value. It would be an error to use ``/mysite/`` (with a
+trailing slash) in this case.
+
+Note that we're using the ``<Location>`` directive, not the ``<Directory>``
+directive. The latter is used for pointing at places on your filesystem,
+whereas ``<Location>`` points at places in the URL structure of a Web site.
+``<Directory>`` would be meaningless here.
+
+Also, if your Django project is not on the default ``PYTHONPATH`` for your
+computer, you'll have to tell mod_python where your project can be found:
+
+.. parsed-literal::
+
+ <Location "/mysite/">
+ SetHandler python-program
+ PythonHandler django.core.handlers.modpython
+ SetEnv DJANGO_SETTINGS_MODULE mysite.settings
+ PythonOption django.root /mysite
+ PythonDebug On
+ **PythonPath "['/path/to/project'] + sys.path"**
+ </Location>
+
+The value you use for ``PythonPath`` should include the parent directories of
+all the modules you are going to import in your application. It should also
+include the parent directory of the :ref:`DJANGO_SETTINGS_MODULE
+<django-settings-module>` location. This is exactly the same situation as
+setting the Python path for interactive usage. Whenever you try to import
+something, Python will run through all the directories in ``sys.path`` in turn,
+from first to last, and try to import from each directory until one succeeds.
+
+Make sure that your Python source files' permissions are set such that the
+Apache user (usually named ``apache`` or ``httpd`` on most systems) will have
+read access to the files.
+
+An example might make this clearer. Suppose you have some applications under
+``/usr/local/django-apps/`` (for example, ``/usr/local/django-apps/weblog/`` and
+so forth), your settings file is at ``/var/www/mysite/settings.py`` and you have
+specified :ref:`DJANGO_SETTINGS_MODULE <django-settings-module>` as in the above
+example. In this case, you would need to write your ``PythonPath`` directive
+as::
+
+ PythonPath "['/usr/local/django-apps/', '/var/www'] + sys.path"
+
+With this path, ``import weblog`` and ``import mysite.settings`` will both
+work. If you had ``import blogroll`` in your code somewhere and ``blogroll``
+lived under the ``weblog/`` directory, you would *also* need to add
+``/usr/local/django-apps/weblog/`` to your ``PythonPath``. Remember: the
+**parent directories** of anything you import directly must be on the Python
+path.
+
+.. note::
+
+ If you're using Windows, we still recommended that you use forward
+ slashes in the pathnames, even though Windows normally uses the backslash
+ character as its native separator. Apache knows how to convert from the
+ forward slash format to the native format, so this approach is portable and
+ easier to read. (It avoids tricky problems with having to double-escape
+ backslashes.)
+
+ This is valid even on a Windows system::
+
+ PythonPath "['c:/path/to/project'] + sys.path"
+
+You can also add directives such as ``PythonAutoReload Off`` for performance.
+See the `mod_python documentation`_ for a full list of options.
+
+Note that you should set ``PythonDebug Off`` on a production server. If you
+leave ``PythonDebug On``, your users would see ugly (and revealing) Python
+tracebacks if something goes wrong within mod_python.
+
+Restart Apache, and any request to ``/mysite/`` or below will be served by
+Django. Note that Django's URLconfs won't trim the "/mysite/" -- they get passed
+the full URL.
+
+When deploying Django sites on mod_python, you'll need to restart Apache each
+time you make changes to your Python code.
+
+.. _mod_python documentation: http://modpython.org/live/current/doc-html/directives.html
+
+Multiple Django installations on the same Apache
+================================================
+
+It's entirely possible to run multiple Django installations on the same Apache
+instance. Just use ``VirtualHost`` for that, like so::
+
+ NameVirtualHost *
+
+ <VirtualHost *>
+ ServerName www.example.com
+ # ...
+ SetEnv DJANGO_SETTINGS_MODULE mysite.settings
+ </VirtualHost>
+
+ <VirtualHost *>
+ ServerName www2.example.com
+ # ...
+ SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings
+ </VirtualHost>
+
+If you need to put two Django installations within the same ``VirtualHost``
+(or in different ``VirtualHost`` blocks that share the same server name),
+you'll need to take a special precaution to ensure mod_python's cache doesn't
+mess things up. Use the ``PythonInterpreter`` directive to give different
+``<Location>`` directives separate interpreters::
+
+ <VirtualHost *>
+ ServerName www.example.com
+ # ...
+ <Location "/something">
+ SetEnv DJANGO_SETTINGS_MODULE mysite.settings
+ PythonInterpreter mysite
+ </Location>
+
+ <Location "/otherthing">
+ SetEnv DJANGO_SETTINGS_MODULE mysite.other_settings
+ PythonInterpreter othersite
+ </Location>
+ </VirtualHost>
+
+The values of ``PythonInterpreter`` don't really matter, as long as they're
+different between the two ``Location`` blocks.
+
+Running a development server with mod_python
+============================================
+
+If you use mod_python for your development server, you can avoid the hassle of
+having to restart the server each time you make code changes. Just set
+``MaxRequestsPerChild 1`` in your ``httpd.conf`` file to force Apache to reload
+everything for each request. But don't do that on a production server, or we'll
+revoke your Django privileges.
+
+If you're the type of programmer who debugs using scattered ``print``
+statements, note that output to ``stdout`` will not appear in the Apache
+log and can even `cause response errors`_.
+
+.. _cause response errors: http://blog.dscpl.com.au/2009/04/wsgi-and-printing-to-standard-output.html
+
+If you have the need to print debugging information in a mod_python setup, you
+have a few options. You can print to ``stderr`` explicitly, like so::
+
+ print >> sys.stderr, 'debug text'
+ sys.stderr.flush()
+
+(note that ``stderr`` is buffered, so calling ``flush`` is necessary if you wish
+debugging information to be displayed promptly.)
+
+A more compact approach is to use an assertion::
+
+ assert False, 'debug text'
+
+Another alternative is to add debugging information to the template of your page.
+
+.. _serving-media-files:
+
+Serving media files
+===================
+
+Django doesn't serve media files itself; it leaves that job to whichever Web
+server you choose.
+
+We recommend using a separate Web server -- i.e., one that's not also running
+Django -- for serving media. Here are some good choices:
+
+ * lighttpd_
+ * Nginx_
+ * TUX_
+ * A stripped-down version of Apache_
+ * Cherokee_
+
+If, however, you have no option but to serve media files on the same Apache
+``VirtualHost`` as Django, here's how you can turn off mod_python for a
+particular part of the site::
+
+ <Location "/media">
+ SetHandler None
+ </Location>
+
+Just change ``Location`` to the root URL of your media files. You can also use
+``<LocationMatch>`` to match a regular expression.
+
+This example sets up Django at the site root but explicitly disables Django for
+the ``media`` subdirectory and any URL that ends with ``.jpg``, ``.gif`` or
+``.png``::
+
+ <Location "/">
+ SetHandler python-program
+ PythonHandler django.core.handlers.modpython
+ SetEnv DJANGO_SETTINGS_MODULE mysite.settings
+ </Location>
+
+ <Location "/media">
+ SetHandler None
+ </Location>
+
+ <LocationMatch "\.(jpg|gif|png)$">
+ SetHandler None
+ </LocationMatch>
+
+
+.. _lighttpd: http://www.lighttpd.net/
+.. _Nginx: http://wiki.nginx.org/Main
+.. _TUX: http://en.wikipedia.org/wiki/TUX_web_server
+.. _Apache: http://httpd.apache.org/
+.. _Cherokee: http://www.cherokee-project.com/
+
+.. _serving-the-admin-files:
+
+Serving the admin files
+=======================
+
+Note that the Django development server automagically serves admin media files,
+but this is not the case when you use any other server arrangement. You're
+responsible for setting up Apache, or whichever media server you're using, to
+serve the admin files.
+
+The admin files live in (:file:`django/contrib/admin/media`) of the Django
+distribution.
+
+Here are two recommended approaches:
+
+ 1. Create a symbolic link to the admin media files from within your
+ document root. This way, all of your Django-related files -- code **and**
+ templates -- stay in one place, and you'll still be able to ``svn
+ update`` your code to get the latest admin templates, if they change.
+
+ 2. Or, copy the admin media files so that they live within your Apache
+ document root.
+
+Using "eggs" with mod_python
+============================
+
+If you installed Django from a Python egg_ or are using eggs in your Django
+project, some extra configuration is required. Create an extra file in your
+project (or somewhere else) that contains something like the following:
+
+.. code-block:: python
+
+ import os
+ os.environ['PYTHON_EGG_CACHE'] = '/some/directory'
+
+Here, ``/some/directory`` is a directory that the Apache Web server process can
+write to. It will be used as the location for any unpacking of code the eggs
+need to do.
+
+Then you have to tell mod_python to import this file before doing anything
+else. This is done using the PythonImport_ directive to mod_python. You need
+to ensure that you have specified the ``PythonInterpreter`` directive to
+mod_python as described above__ (you need to do this even if you aren't
+serving multiple installations in this case). Then add the ``PythonImport``
+line in the main server configuration (i.e., outside the ``Location`` or
+``VirtualHost`` sections). For example::
+
+ PythonInterpreter my_django
+ PythonImport /path/to/my/project/file.py my_django
+
+Note that you can use an absolute path here (or a normal dotted import path),
+as described in the `mod_python manual`_. We use an absolute path in the
+above example because if any Python path modifications are required to access
+your project, they will not have been done at the time the ``PythonImport``
+line is processed.
+
+.. _Egg: http://peak.telecommunity.com/DevCenter/PythonEggs
+.. _PythonImport: http://www.modpython.org/live/current/doc-html/dir-other-pimp.html
+.. _mod_python manual: PythonImport_
+__ `Multiple Django installations on the same Apache`_
+
+Error handling
+==============
+
+When you use Apache/mod_python, errors will be caught by Django -- in other
+words, they won't propagate to the Apache level and won't appear in the Apache
+``error_log``.
+
+The exception for this is if something is really wonky in your Django setup. In
+that case, you'll see an "Internal Server Error" page in your browser and the
+full Python traceback in your Apache ``error_log`` file. The ``error_log``
+traceback is spread over multiple lines. (Yes, this is ugly and rather hard to
+read, but it's how mod_python does things.)
+
+If you get a segmentation fault
+===============================
+
+If Apache causes a segmentation fault, there are two probable causes, neither
+of which has to do with Django itself.
+
+ 1. It may be because your Python code is importing the "pyexpat" module,
+ which may conflict with the version embedded in Apache. For full
+ information, see `Expat Causing Apache Crash`_.
+
+ 2. It may be because you're running mod_python and mod_php in the same
+ Apache instance, with MySQL as your database backend. In some cases,
+ this causes a known mod_python issue due to version conflicts in PHP and
+ the Python MySQL backend. There's full information in the
+ `mod_python FAQ entry`_.
+
+If you continue to have problems setting up mod_python, a good thing to do is
+get a barebones mod_python site working, without the Django framework. This is
+an easy way to isolate mod_python-specific problems. `Getting mod_python Working`_
+details this procedure.
+
+The next step should be to edit your test code and add an import of any
+Django-specific code you're using -- your views, your models, your URLconf,
+your RSS configuration, etc. Put these imports in your test handler function
+and access your test URL in a browser. If this causes a crash, you've confirmed
+it's the importing of Django code that causes the problem. Gradually reduce the
+set of imports until it stops crashing, so as to find the specific module that
+causes the problem. Drop down further into modules and look into their imports,
+as necessary.
+
+.. _Expat Causing Apache Crash: http://www.dscpl.com.au/wiki/ModPython/Articles/ExpatCausingApacheCrash
+.. _mod_python FAQ entry: http://modpython.org/FAQ/faqw.py?req=show&file=faq02.013.htp
+.. _Getting mod_python Working: http://www.dscpl.com.au/wiki/ModPython/Articles/GettingModPythonWorking
+
+If you get a UnicodeEncodeError
+===============================
+
+If you're taking advantage of the internationalization features of Django (see
+:doc:`/topics/i18n/index`) and you intend to allow users to upload files, you must
+ensure that the environment used to start Apache is configured to accept
+non-ASCII file names. If your environment is not correctly configured, you
+will trigger ``UnicodeEncodeError`` exceptions when calling functions like
+``os.path()`` on filenames that contain non-ASCII characters.
+
+To avoid these problems, the environment used to start Apache should contain
+settings analogous to the following::
+
+ export LANG='en_US.UTF-8'
+ export LC_ALL='en_US.UTF-8'
+
+Consult the documentation for your operating system for the appropriate syntax
+and location to put these configuration items; ``/etc/apache2/envvars`` is a
+common location on Unix platforms. Once you have added these statements
+to your environment, restart Apache.
diff --git a/parts/django/docs/howto/deployment/modwsgi.txt b/parts/django/docs/howto/deployment/modwsgi.txt
new file mode 100644
index 0000000..17ba0e3
--- /dev/null
+++ b/parts/django/docs/howto/deployment/modwsgi.txt
@@ -0,0 +1,118 @@
+==========================================
+How to use Django with Apache and mod_wsgi
+==========================================
+
+Deploying Django with Apache_ and `mod_wsgi`_ is the recommended way to get
+Django into production.
+
+.. _Apache: http://httpd.apache.org/
+.. _mod_wsgi: http://code.google.com/p/modwsgi/
+
+mod_wsgi is an Apache module which can be used to host any Python application
+which supports the `Python WSGI interface`_, including Django. Django will work
+with any version of Apache which supports mod_wsgi.
+
+.. _python wsgi interface: http://www.python.org/dev/peps/pep-0333/
+
+The `official mod_wsgi documentation`_ is fantastic; it's your source for all
+the details about how to use mod_wsgi. You'll probably want to start with the
+`installation and configuration documentation`_.
+
+.. _official mod_wsgi documentation: http://code.google.com/p/modwsgi/
+.. _installation and configuration documentation: http://code.google.com/p/modwsgi/wiki/InstallationInstructions
+
+Basic Configuration
+===================
+
+Once you've got mod_wsgi installed and activated, edit your ``httpd.conf`` file
+and add::
+
+ WSGIScriptAlias / /path/to/mysite/apache/django.wsgi
+
+The first bit above is the url you want to be serving your application at (``/``
+indicates the root url), and the second is the location of a "WSGI file" -- see
+below -- on your system, usually inside of your project. This tells Apache
+to serve any request below the given URL using the WSGI application defined by that file.
+
+Next we'll need to actually create this WSGI application, so create the file
+mentioned in the second part of ``WSGIScriptAlias`` and add::
+
+ import os
+ import sys
+
+ os.environ['DJANGO_SETTINGS_MODULE'] = 'mysite.settings'
+
+ import django.core.handlers.wsgi
+ application = django.core.handlers.wsgi.WSGIHandler()
+
+If your project is not on your ``PYTHONPATH`` by default you can add::
+
+ path = '/usr/local/django'
+ if path not in sys.path:
+ sys.path.append(path)
+
+just above the final ``import`` line to place your project on the path. Remember to
+replace 'mysite.settings' with your correct settings file, and '/usr/local/django'
+with your own project's location.
+
+Serving media files
+===================
+
+Django doesn't serve media files itself; it leaves that job to whichever Web
+server you choose.
+
+We recommend using a separate Web server -- i.e., one that's not also running
+Django -- for serving media. Here are some good choices:
+
+ * lighttpd_
+ * Nginx_
+ * TUX_
+ * A stripped-down version of Apache_
+ * Cherokee_
+
+If, however, you have no option but to serve media files on the same Apache
+``VirtualHost`` as Django, you can set up Apache to serve some URLs as
+static media, and others using the mod_wsgi interface to Django.
+
+This example sets up Django at the site root, but explicitly serves ``robots.txt``,
+``favicon.ico``, any CSS file, and anything in the ``/media/`` URL space as a static
+file. All other URLs will be served using mod_wsgi::
+
+ Alias /robots.txt /usr/local/wsgi/static/robots.txt
+ Alias /favicon.ico /usr/local/wsgi/static/favicon.ico
+
+ AliasMatch /([^/]*\.css) /usr/local/wsgi/static/styles/$1
+
+ Alias /media/ /usr/local/wsgi/static/media/
+
+ <Directory /usr/local/wsgi/static>
+ Order deny,allow
+ Allow from all
+ </Directory>
+
+ WSGIScriptAlias / /usr/local/wsgi/scripts/django.wsgi
+
+ <Directory /usr/local/wsgi/scripts>
+ Order allow,deny
+ Allow from all
+ </Directory>
+
+.. _lighttpd: http://www.lighttpd.net/
+.. _Nginx: http://wiki.nginx.org/Main
+.. _TUX: http://en.wikipedia.org/wiki/TUX_web_server
+.. _Apache: http://httpd.apache.org/
+.. _Cherokee: http://www.cherokee-project.com/
+
+More details on configuring a mod_wsgi site to serve static files can be found
+in the mod_wsgi documentation on `hosting static files`_.
+
+.. _hosting static files: http://code.google.com/p/modwsgi/wiki/ConfigurationGuidelines#Hosting_Of_Static_Files
+
+Details
+=======
+
+For more details, see the `mod_wsgi documentation on Django integration`_,
+which explains the above in more detail, and walks through all the various
+options you've got when deploying under mod_wsgi.
+
+.. _mod_wsgi documentation on Django integration: http://code.google.com/p/modwsgi/wiki/IntegrationWithDjango
diff --git a/parts/django/docs/howto/error-reporting.txt b/parts/django/docs/howto/error-reporting.txt
new file mode 100644
index 0000000..9c61c97
--- /dev/null
+++ b/parts/django/docs/howto/error-reporting.txt
@@ -0,0 +1,78 @@
+Error reporting via e-mail
+==========================
+
+When you're running a public site you should always turn off the
+:setting:`DEBUG` setting. That will make your server run much faster, and will
+also prevent malicious users from seeing details of your application that can be
+revealed by the error pages.
+
+However, running with :setting:`DEBUG` set to ``False`` means you'll never see
+errors generated by your site -- everyone will just see your public error pages.
+You need to keep track of errors that occur in deployed sites, so Django can be
+configured to e-mail you details of those errors.
+
+Server errors
+-------------
+
+When :setting:`DEBUG` is ``False``, Django will e-mail the users listed in the
+:setting:`ADMINS` setting whenever your code raises an unhandled exception and
+results in an internal server error (HTTP status code 500). This gives the
+administrators immediate notification of any errors. The :setting:`ADMINS` will
+get a description of the error, a complete Python traceback, and details about
+the HTTP request that caused the error.
+
+.. note::
+
+ In order to send e-mail, Django requires a few settings telling it
+ how to connect to your mail server. At the very least, you'll need
+ to specify :setting:`EMAIL_HOST` and possibly
+ :setting:`EMAIL_HOST_USER` and :setting:`EMAIL_HOST_PASSWORD`,
+ though other settings may be also required depending on your mail
+ server's configuration. Consult :doc:`the Django settings
+ documentation </ref/settings>` for a full list of email-related
+ settings.
+
+By default, Django will send e-mail from root@localhost. However, some mail
+providers reject all e-mail from this address. To use a different sender
+address, modify the :setting:`SERVER_EMAIL` setting.
+
+To disable this behavior, just remove all entries from the :setting:`ADMINS`
+setting.
+
+404 errors
+----------
+
+Django can also be configured to e-mail errors about broken links (404 "page
+not found" errors). Django sends e-mails about 404 errors when:
+
+ * :setting:`DEBUG` is ``False``
+
+ * :setting:`SEND_BROKEN_LINK_EMAILS` is ``True``
+
+ * Your :setting:`MIDDLEWARE_CLASSES` setting includes ``CommonMiddleware``
+ (which it does by default).
+
+If those conditions are met, Django will e-mail the users listed in the
+:setting:`MANAGERS` setting whenever your code raises a 404 and the request has
+a referer. (It doesn't bother to e-mail for 404s that don't have a referer --
+those are usually just people typing in broken URLs or broken Web 'bots).
+
+You can tell Django to stop reporting particular 404s by tweaking the
+:setting:`IGNORABLE_404_ENDS` and :setting:`IGNORABLE_404_STARTS` settings. Both
+should be a tuple of strings. For example::
+
+ IGNORABLE_404_ENDS = ('.php', '.cgi')
+ IGNORABLE_404_STARTS = ('/phpmyadmin/',)
+
+In this example, a 404 to any URL ending with ``.php`` or ``.cgi`` will *not* be
+reported. Neither will any URL starting with ``/phpmyadmin/``.
+
+The best way to disable this behavior is to set
+:setting:`SEND_BROKEN_LINK_EMAILS` to ``False``.
+
+.. seealso::
+
+ You can also set up custom error reporting by writing a custom piece of
+ :ref:`exception middleware <exception-middleware>`. If you do write custom
+ error handling, it's a good idea to emulate Django's built-in error handling
+ and only report/log errors if :setting:`DEBUG` is ``False``.
diff --git a/parts/django/docs/howto/i18n.txt b/parts/django/docs/howto/i18n.txt
new file mode 100644
index 0000000..64b33d7
--- /dev/null
+++ b/parts/django/docs/howto/i18n.txt
@@ -0,0 +1,103 @@
+.. _using-translations-in-your-own-projects:
+
+===============================================
+Using internationalization 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.
+
+This way, you can write applications that include their own translations, and
+you can override base translations in your project path. Or, you can just build
+a big project out of several apps and put all translations into one big project
+message file. The choice is yours.
+
+.. note::
+
+ If you're using manually configured settings, as described in
+ :ref:`settings-without-django-settings-module`, the ``locale`` directory in
+ the project directory will not be examined, since Django loses the ability
+ to work out the location of the project directory. (Django normally uses the
+ location of the settings file to determine this, and a settings file doesn't
+ exist if you're manually configuring your settings.)
+
+All message file repositories are structured the same way. They are:
+
+ * ``$APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
+ * ``$PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|mo)``
+ * All paths listed in ``LOCALE_PATHS`` in your settings file are
+ searched in that order for ``<language>/LC_MESSAGES/django.(po|mo)``
+ * ``$PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|mo)``
+
+To create message files, you use the :djadmin:`django-admin.py makemessages <makemessages>`
+tool. You only need to be in the same directory where the ``locale/`` directory
+is located. And you use :djadmin:`django-admin.py compilemessages <compilemessages>`
+to produce the binary ``.mo`` files that are used by ``gettext``. Read the
+:doc:`/topics/i18n/localization` document for more details.
+
+You can also run ``django-admin.py compilemessages --settings=path.to.settings``
+to make the compiler process all the directories in your :setting:`LOCALE_PATHS`
+setting.
+
+Application message files are a bit complicated to discover -- they need the
+:class:`~django.middleware.locale.LocaleMiddleware`. If you don't use the
+middleware, only the Django message files and project message files will be
+installed and available at runtime.
+
+Finally, you should give some thought to the structure of your translation
+files. If your applications need to be delivered to other users and will
+be used in other projects, you might want to use app-specific translations.
+But using app-specific translations and project translations could produce
+weird problems with ``makemessages``: It will traverse all directories below
+the current path and so might put message IDs into the project message file
+that are already in application message files.
+
+The easiest way out is to store applications that are not part of the project
+(and so carry their own translations) outside the project tree. That way,
+``django-admin.py makemessages`` on the project level will only translate
+strings that are connected to your explicit project and not strings that are
+distributed independently.
+
+Using translations outside views and templates
+==============================================
+
+While Django provides a rich set of i18n tools for use in views and templates,
+it does not restrict the usage to Django-specific code. The Django translation
+mechanisms can be used to translate arbitrary texts to any language that is
+supported by Django (as long as an appropriate translation catalog exists, of
+course). You can load a translation catalog, activate it and translate text to
+language of your choice, but remember to switch back to original language, as
+activating a translation catalog is done on per-thread basis and such change
+will affect code running in the same thread.
+
+For example::
+
+ from django.utils import translation
+ def welcome_translated(language):
+ cur_language = translation.get_language()
+ try:
+ translation.activate(language)
+ text = translation.ugettext('welcome')
+ finally:
+ translation.activate(cur_language)
+ return text
+
+Calling this function with the value 'de' will give you ``"Willkommen"``,
+regardless of :setting:`LANGUAGE_CODE` and language set by middleware.
+
+Functions of particular interest are ``django.utils.translation.get_language()``
+which returns the language used in the current thread,
+``django.utils.translation.activate()`` which activates a translation catalog
+for the current thread, and ``django.utils.translation.check_for_language()``
+which checks if the given language is supported by Django.
diff --git a/parts/django/docs/howto/index.txt b/parts/django/docs/howto/index.txt
new file mode 100644
index 0000000..49d0644
--- /dev/null
+++ b/parts/django/docs/howto/index.txt
@@ -0,0 +1,34 @@
+"How-to" guides
+===============
+
+Here you'll find short answers to "How do I....?" types of questions. These
+how-to guides don't cover topics in depth -- you'll find that material in the
+:doc:`/topics/index` and the :doc:`/ref/index`. However, these guides will help
+you quickly accomplish common tasks.
+
+.. toctree::
+ :maxdepth: 1
+
+ apache-auth
+ auth-remote-user
+ custom-management-commands
+ custom-model-fields
+ custom-template-tags
+ custom-file-storage
+ deployment/index
+ error-reporting
+ initial-data
+ i18n
+ jython
+ legacy-databases
+ outputting-csv
+ outputting-pdf
+ static-files
+
+.. seealso::
+
+ The `Django community aggregator`_, where we aggregate content from the
+ global Django community. Many writers in the aggregator write this sort of
+ how-to material.
+
+ .. _django community aggregator: http://www.djangoproject.com/community/
diff --git a/parts/django/docs/howto/initial-data.txt b/parts/django/docs/howto/initial-data.txt
new file mode 100644
index 0000000..cf3f65d
--- /dev/null
+++ b/parts/django/docs/howto/initial-data.txt
@@ -0,0 +1,142 @@
+=================================
+Providing initial data for models
+=================================
+
+It's sometimes useful to pre-populate your database with hard-coded data when
+you're first setting up an app. There's a couple of ways you can have Django
+automatically create this data: you can provide `initial data via fixtures`_, or
+you can provide `initial data as SQL`_.
+
+In general, using a fixture is a cleaner method since it's database-agnostic,
+but initial SQL is also quite a bit more flexible.
+
+.. _initial data as sql: `providing initial sql data`_
+.. _initial data via fixtures: `providing initial data with fixtures`_
+
+Providing initial data with fixtures
+====================================
+
+A fixture is a collection of data that Django knows how to import into a
+database. The most straightforward way of creating a fixture if you've already
+got some data is to use the :djadmin:`manage.py dumpdata <dumpdata>` command.
+Or, you can write fixtures by hand; fixtures can be written as XML, YAML, or
+JSON documents. The :doc:`serialization documentation </topics/serialization>`
+has more details about each of these supported :ref:`serialization formats
+<serialization-formats>`.
+
+As an example, though, here's what a fixture for a simple ``Person`` model might
+look like in JSON:
+
+.. code-block:: js
+
+ [
+ {
+ "model": "myapp.person",
+ "pk": 1,
+ "fields": {
+ "first_name": "John",
+ "last_name": "Lennon"
+ }
+ },
+ {
+ "model": "myapp.person",
+ "pk": 2,
+ "fields": {
+ "first_name": "Paul",
+ "last_name": "McCartney"
+ }
+ }
+ ]
+
+And here's that same fixture as YAML:
+
+.. code-block:: none
+
+ - model: myapp.person
+ pk: 1
+ fields:
+ first_name: John
+ last_name: Lennon
+ - model: myapp.person
+ pk: 2
+ fields:
+ first_name: Paul
+ last_name: McCartney
+
+You'll store this data in a ``fixtures`` directory inside your app.
+
+Loading data is easy: just call :djadmin:`manage.py loaddata fixturename
+<loaddata>`, where *fixturename* is the name of the fixture file you've created.
+Every time you run :djadmin:`loaddata` the data will be read from the fixture
+and re-loaded into the database. Note that this means that if you change one of
+the rows created by a fixture and then run :djadmin:`loaddata` again you'll
+wipe out any changes you've made.
+
+Automatically loading initial data fixtures
+-------------------------------------------
+
+If you create a fixture named ``initial_data.[xml/yaml/json]``, that fixture will
+be loaded every time you run :djadmin:`syncdb`. This is extremely convenient,
+but be careful: remember that the data will be refreshed *every time* you run
+:djadmin:`syncdb`. So don't use ``initial_data`` for data you'll want to edit.
+
+.. seealso::
+
+ Fixtures are also used by the :ref:`testing framework
+ <topics-testing-fixtures>` to help set up a consistent test environment.
+
+.. _initial-sql:
+
+Providing initial SQL data
+==========================
+
+Django provides a hook for passing the database arbitrary SQL that's executed
+just after the CREATE TABLE statements when you run :djadmin:`syncdb`. You can
+use this hook to populate default records, or you could also create SQL
+functions, views, triggers, etc.
+
+The hook is simple: Django just looks for a file called ``sql/<modelname>.sql``,
+in your app directory, where ``<modelname>`` is the model's name in lowercase.
+
+So, if you had a ``Person`` model in an app called ``myapp``, you could add
+arbitrary SQL to the file ``sql/person.sql`` inside your ``myapp`` directory.
+Here's an example of what the file might contain:
+
+.. code-block:: sql
+
+ INSERT INTO myapp_person (first_name, last_name) VALUES ('John', 'Lennon');
+ INSERT INTO myapp_person (first_name, last_name) VALUES ('Paul', 'McCartney');
+
+Each SQL file, if given, is expected to contain valid SQL statements
+which will insert the desired data (e.g., properly-formatted
+``INSERT`` statements separated by semicolons).
+
+The SQL files are read by the :djadmin:`sqlcustom`, :djadmin:`sqlreset`,
+:djadmin:`sqlall` and :djadmin:`reset` commands in :doc:`manage.py
+</ref/django-admin>`. Refer to the :doc:`manage.py documentation
+</ref/django-admin>` for more information.
+
+Note that if you have multiple SQL data files, there's no guarantee of
+the order in which they're executed. The only thing you can assume is
+that, by the time your custom data files are executed, all the
+database tables already will have been created.
+
+Database-backend-specific SQL data
+----------------------------------
+
+There's also a hook for backend-specific SQL data. For example, you
+can have separate initial-data files for PostgreSQL and MySQL. For
+each app, Django looks for a file called
+``<appname>/sql/<modelname>.<backend>.sql``, where ``<appname>`` is
+your app directory, ``<modelname>`` is the model's name in lowercase
+and ``<backend>`` is the last part of the module name provided for the
+:setting:`ENGINE` in your settings file (e.g., if you have defined a
+database with an :setting:`ENGINE` value of
+``django.db.backends.postgresql``, Django will look for
+``<appname>/sql/<modelname>.postgresql.sql``).
+
+Backend-specific SQL data is executed before non-backend-specific SQL
+data. For example, if your app contains the files ``sql/person.sql``
+and ``sql/person.postgresql.sql`` and you're installing the app on
+PostgreSQL, Django will execute the contents of
+``sql/person.postgresql.sql`` first, then ``sql/person.sql``.
diff --git a/parts/django/docs/howto/jython.txt b/parts/django/docs/howto/jython.txt
new file mode 100644
index 0000000..1bf8d6c
--- /dev/null
+++ b/parts/django/docs/howto/jython.txt
@@ -0,0 +1,73 @@
+========================
+Running Django on Jython
+========================
+
+.. index:: Jython, Java, JVM
+
+Jython_ is an implementation of Python that runs on the Java platform (JVM).
+Django runs cleanly on Jython version 2.5 or later, which means you can deploy
+Django on any Java platform.
+
+This document will get you up and running with Django on top of Jython.
+
+.. _jython: http://www.jython.org/
+
+Installing Jython
+=================
+
+Django works with Jython versions 2.5b3 and higher. Download Jython at
+http://www.jython.org/.
+
+Creating a servlet container
+============================
+
+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 anything else until you're ready to deploy Django in production.
+
+If you want to use Django on a production site, use a Java servlet container,
+such as `Apache Tomcat`_. Full JavaEE applications servers such as `GlassFish`_
+or `JBoss`_ are also OK, if you need the extra features they include.
+
+.. _`Apache Tomcat`: http://tomcat.apache.org/
+.. _GlassFish: https://glassfish.dev.java.net/
+.. _JBoss: http://www.jboss.org/
+
+Installing Django
+=================
+
+The next step is to install Django itself. This is exactly the same as
+installing Django on standard Python, so see
+:ref:`removing-old-versions-of-django` and :ref:`install-django-code` for
+instructions.
+
+Installing Jython platform support libraries
+============================================
+
+The `django-jython`_ project contains database backends and management commands
+for Django/Jython development. Note that the builtin Django backends won't work
+on top of Jython.
+
+.. _`django-jython`: http://code.google.com/p/django-jython/
+
+To install it, follow the `installation instructions`_ detailed on the project
+Web site. Also, read the `database backends`_ documentation there.
+
+.. _`installation instructions`: http://code.google.com/p/django-jython/wiki/Install
+.. _`database backends`: http://code.google.com/p/django-jython/wiki/DatabaseBackends
+
+Differences with Django on Jython
+=================================
+
+.. index:: JYTHONPATH
+
+At this point, Django on Jython should behave nearly identically to Django
+running on standard Python. However, are a few differences to keep in mind:
+
+ * Remember to use the ``jython`` command instead of ``python``. The
+ documentation uses ``python`` for consistancy, but if you're using Jython
+ you'll want to mentally replace ``python`` with ``jython`` every time it
+ occurs.
+
+ * Similarly, you'll need to use the ``JYTHONPATH`` environment variable
+ instead of ``PYTHONPATH``.
diff --git a/parts/django/docs/howto/legacy-databases.txt b/parts/django/docs/howto/legacy-databases.txt
new file mode 100644
index 0000000..2121871
--- /dev/null
+++ b/parts/django/docs/howto/legacy-databases.txt
@@ -0,0 +1,66 @@
+=========================================
+Integrating Django with a legacy database
+=========================================
+
+While Django is best suited for developing new applications, it's quite
+possible to integrate it into legacy databases. Django includes a couple of
+utilities to automate as much of this process as possible.
+
+This document assumes you know the Django basics, as covered in the
+:doc:`tutorial </intro/tutorial01>`.
+
+Once you've got Django set up, you'll follow this general process to integrate
+with an existing database.
+
+Give Django your database parameters
+====================================
+
+You'll need to tell Django what your database connection parameters are, and
+what the name of the database is. Do that by editing the :setting:`DATABASES`
+setting and assigning values to the following keys for the ``'default'``
+connection:
+
+ * :setting:`NAME`
+ * :setting:`ENGINE`
+ * :setting:`USER`
+ * :setting:`PASSWORD`
+ * :setting:`HOST`
+ * :setting:`PORT`
+
+Auto-generate the models
+========================
+
+.. highlight:: bash
+
+Django comes with a utility called :djadmin:`inspectdb` that can create models
+by introspecting an existing database. You can view the output by running this
+command::
+
+ python manage.py inspectdb
+
+Save this as a file by using standard Unix output redirection::
+
+ python manage.py inspectdb > models.py
+
+This feature is meant as a shortcut, not as definitive model generation. See the
+:djadmin:`documentation of inspectdb <inspectdb>` for more information.
+
+Once you've cleaned up your models, name the file ``models.py`` and put it in
+the Python package that holds your app. Then add the app to your
+:setting:`INSTALLED_APPS` setting.
+
+Install the core Django tables
+==============================
+
+Next, run the :djadmin:`syncdb` command to install any extra needed database
+records such as admin permissions and content types::
+
+ python manage.py syncdb
+
+Test and tweak
+==============
+
+Those are the basic steps -- from here you'll want to tweak the models Django
+generated until they work the way you'd like. Try accessing your data via the
+Django database API, and try editing objects via Django's admin site, and edit
+the models file accordingly.
diff --git a/parts/django/docs/howto/outputting-csv.txt b/parts/django/docs/howto/outputting-csv.txt
new file mode 100644
index 0000000..46e111d
--- /dev/null
+++ b/parts/django/docs/howto/outputting-csv.txt
@@ -0,0 +1,137 @@
+==========================
+Outputting CSV with Django
+==========================
+
+This document explains how to output CSV (Comma Separated Values) dynamically
+using Django views. To do this, you can either use the `Python CSV library`_ or
+the Django template system.
+
+.. _Python CSV library: http://docs.python.org/library/csv.html
+
+Using the Python CSV library
+============================
+
+Python comes with a CSV library, ``csv``. The key to using it with Django is
+that the ``csv`` module's CSV-creation capability acts on file-like objects, and
+Django's :class:`~django.http.HttpResponse` objects are file-like objects.
+
+Here's an example::
+
+ import csv
+ from django.http import HttpResponse
+
+ def some_view(request):
+ # Create the HttpResponse object with the appropriate CSV header.
+ response = HttpResponse(mimetype='text/csv')
+ response['Content-Disposition'] = 'attachment; filename=somefilename.csv'
+
+ writer = csv.writer(response)
+ writer.writerow(['First row', 'Foo', 'Bar', 'Baz'])
+ writer.writerow(['Second row', 'A', 'B', 'C', '"Testing"', "Here's a quote"])
+
+ return response
+
+The code and comments should be self-explanatory, but a few things deserve a
+mention:
+
+ * The response gets a special MIME type, ``text/csv``. This tells
+ browsers that the document is a CSV file, rather than an HTML file. If
+ you leave this off, browsers will probably interpret the output as HTML,
+ which will result in ugly, scary gobbledygook in the browser window.
+
+ * The response gets an additional ``Content-Disposition`` header, which
+ contains the name of the CSV file. This filename is arbitrary; call it
+ whatever you want. It'll be used by browsers in the "Save as..."
+ dialogue, etc.
+
+ * Hooking into the CSV-generation API is easy: Just pass ``response`` as the
+ first argument to ``csv.writer``. The ``csv.writer`` function expects a
+ file-like object, and :class:`~django.http.HttpResponse` objects fit the
+ bill.
+
+ * For each row in your CSV file, call ``writer.writerow``, passing it an
+ iterable object such as a list or tuple.
+
+ * The CSV module takes care of quoting for you, so you don't have to worry
+ about escaping strings with quotes or commas in them. Just pass
+ ``writerow()`` your raw strings, and it'll do the right thing.
+
+Handling Unicode
+~~~~~~~~~~~~~~~~
+
+Python's ``csv`` module does not support Unicode input. Since Django uses
+Unicode internally this means strings read from sources such as
+:class:`~django.http.HttpRequest` are potentially problematic. There are a few
+options for handling this:
+
+ * Manually encode all Unicode objects to a compatible encoding.
+
+ * Use the ``UnicodeWriter`` class provided in the `csv module's examples
+ section`_.
+
+ * Use the `python-unicodecsv module`_, which aims to be a drop-in
+ replacement for ``csv`` that gracefully handles Unicode.
+
+For more information, see the Python `CSV File Reading and Writing`_
+documentation.
+
+.. _`csv module's examples section`: http://docs.python.org/library/csv.html#examples
+.. _`python-unicodecsv module`: https://github.com/jdunck/python-unicodecsv
+.. _`CSV File Reading and Writing`: http://docs.python.org/library/csv.html
+
+Using the template system
+=========================
+
+Alternatively, you can use the :doc:`Django template system </topics/templates>`
+to generate CSV. This is lower-level than using the convenient Python ``csv``
+module, but the solution is presented here for completeness.
+
+The idea here is to pass a list of items to your template, and have the
+template output the commas in a :ttag:`for` loop.
+
+Here's an example, which generates the same CSV file as above::
+
+ from django.http import HttpResponse
+ from django.template import loader, Context
+
+ def some_view(request):
+ # Create the HttpResponse object with the appropriate CSV header.
+ response = HttpResponse(mimetype='text/csv')
+ response['Content-Disposition'] = 'attachment; filename=somefilename.csv'
+
+ # The data is hard-coded here, but you could load it from a database or
+ # some other source.
+ csv_data = (
+ ('First row', 'Foo', 'Bar', 'Baz'),
+ ('Second row', 'A', 'B', 'C', '"Testing"', "Here's a quote"),
+ )
+
+ t = loader.get_template('my_template_name.txt')
+ c = Context({
+ 'data': csv_data,
+ })
+ response.write(t.render(c))
+ return response
+
+The only difference between this example and the previous example is that this
+one uses template loading instead of the CSV module. The rest of the code --
+such as the ``mimetype='text/csv'`` -- is the same.
+
+Then, create the template ``my_template_name.txt``, with this template code:
+
+.. code-block:: html+django
+
+ {% for row in data %}"{{ row.0|addslashes }}", "{{ row.1|addslashes }}", "{{ row.2|addslashes }}", "{{ row.3|addslashes }}", "{{ row.4|addslashes }}"
+ {% endfor %}
+
+This template is quite basic. It just iterates over the given data and displays
+a line of CSV for each row. It uses the :tfilter:`addslashes` template filter to
+ensure there aren't any problems with quotes.
+
+Other text-based formats
+========================
+
+Notice that there isn't very much specific to CSV here -- just the specific
+output format. You can use either of these techniques to output any text-based
+format you can dream of. You can also use a similar technique to generate
+arbitrary binary data; see :doc:`/howto/outputting-pdf` for an example.
diff --git a/parts/django/docs/howto/outputting-pdf.txt b/parts/django/docs/howto/outputting-pdf.txt
new file mode 100644
index 0000000..67950d0
--- /dev/null
+++ b/parts/django/docs/howto/outputting-pdf.txt
@@ -0,0 +1,160 @@
+===========================
+Outputting PDFs with Django
+===========================
+
+This document explains how to output PDF files dynamically using Django views.
+This is made possible by the excellent, open-source ReportLab_ Python PDF
+library.
+
+The advantage of generating PDF files dynamically is that you can create
+customized PDFs for different purposes -- say, for different users or different
+pieces of content.
+
+For example, Django was used at kusports.com_ to generate customized,
+printer-friendly NCAA tournament brackets, as PDF files, for people
+participating in a March Madness contest.
+
+.. _ReportLab: http://www.reportlab.org/oss/rl-toolkit/
+.. _kusports.com: http://www.kusports.com/
+
+Install ReportLab
+=================
+
+Download and install the ReportLab library from http://www.reportlab.org/oss/rl-toolkit/download/.
+The `user guide`_ (not coincidentally, a PDF file) explains how to install it.
+
+Test your installation by importing it in the Python interactive interpreter::
+
+ >>> import reportlab
+
+If that command doesn't raise any errors, the installation worked.
+
+.. _user guide: http://www.reportlab.com/docs/reportlab-userguide.pdf
+
+Write your view
+===============
+
+The key to generating PDFs dynamically with Django is that the ReportLab API
+acts on file-like objects, and Django's :class:`~django.http.HttpResponse`
+objects are file-like objects.
+
+Here's a "Hello World" example::
+
+ from reportlab.pdfgen import canvas
+ from django.http import HttpResponse
+
+ def some_view(request):
+ # Create the HttpResponse object with the appropriate PDF headers.
+ response = HttpResponse(mimetype='application/pdf')
+ response['Content-Disposition'] = 'attachment; filename=somefilename.pdf'
+
+ # Create the PDF object, using the response object as its "file."
+ p = canvas.Canvas(response)
+
+ # Draw things on the PDF. Here's where the PDF generation happens.
+ # See the ReportLab documentation for the full list of functionality.
+ p.drawString(100, 100, "Hello world.")
+
+ # Close the PDF object cleanly, and we're done.
+ p.showPage()
+ p.save()
+ return response
+
+The code and comments should be self-explanatory, but a few things deserve a
+mention:
+
+ * The response gets a special MIME type, ``application/pdf``. This tells
+ browsers that the document is a PDF file, rather than an HTML file. If
+ you leave this off, browsers will probably interpret the output as HTML,
+ which would result in ugly, scary gobbledygook in the browser window.
+
+ * The response gets an additional ``Content-Disposition`` header, which
+ contains the name of the PDF file. This filename is arbitrary: Call it
+ whatever you want. It'll be used by browsers in the "Save as..."
+ dialogue, etc.
+
+ * The ``Content-Disposition`` header starts with ``'attachment; '`` in this
+ example. This forces Web browsers to pop-up a dialog box
+ prompting/confirming how to handle the document even if a default is set
+ on the machine. If you leave off ``'attachment;'``, browsers will handle
+ the PDF using whatever program/plugin they've been configured to use for
+ PDFs. Here's what that code would look like::
+
+ response['Content-Disposition'] = 'filename=somefilename.pdf'
+
+ * Hooking into the ReportLab API is easy: Just pass ``response`` as the
+ first argument to ``canvas.Canvas``. The ``Canvas`` class expects a
+ file-like object, and :class:`~django.http.HttpResponse` objects fit the
+ bill.
+
+ * Note that all subsequent PDF-generation methods are called on the PDF
+ object (in this case, ``p``) -- not on ``response``.
+
+ * Finally, it's important to call ``showPage()`` and ``save()`` on the PDF
+ file.
+
+Complex PDFs
+============
+
+If you're creating a complex PDF document with ReportLab, consider using the
+cStringIO_ library as a temporary holding place for your PDF file. The cStringIO
+library provides a file-like object interface that is particularly efficient.
+Here's the above "Hello World" example rewritten to use ``cStringIO``::
+
+ # Fall back to StringIO in environments where cStringIO is not available
+ try:
+ from cStringIO import StringIO
+ except ImportError:
+ from StringIO import StringIO
+ from reportlab.pdfgen import canvas
+ from django.http import HttpResponse
+
+ def some_view(request):
+ # Create the HttpResponse object with the appropriate PDF headers.
+ response = HttpResponse(mimetype='application/pdf')
+ response['Content-Disposition'] = 'attachment; filename=somefilename.pdf'
+
+ buffer = StringIO()
+
+ # Create the PDF object, using the StringIO object as its "file."
+ p = canvas.Canvas(buffer)
+
+ # Draw things on the PDF. Here's where the PDF generation happens.
+ # See the ReportLab documentation for the full list of functionality.
+ p.drawString(100, 100, "Hello world.")
+
+ # Close the PDF object cleanly.
+ p.showPage()
+ p.save()
+
+ # Get the value of the StringIO buffer and write it to the response.
+ pdf = buffer.getvalue()
+ buffer.close()
+ response.write(pdf)
+ return response
+
+.. _cStringIO: http://docs.python.org/library/stringio.html#module-cStringIO
+
+Further resources
+=================
+
+ * PDFlib_ is another PDF-generation library that has Python bindings. To
+ use it with Django, just use the same concepts explained in this article.
+ * `Pisa XHTML2PDF`_ is yet another PDF-generation library. Pisa ships with
+ an example of how to integrate Pisa with Django.
+ * HTMLdoc_ is a command-line script that can convert HTML to PDF. It
+ doesn't have a Python interface, but you can escape out to the shell
+ using ``system`` or ``popen`` and retrieve the output in Python.
+
+.. _PDFlib: http://www.pdflib.org/
+.. _`Pisa XHTML2PDF`: http://www.xhtml2pdf.com/
+.. _HTMLdoc: http://www.htmldoc.org/
+
+Other formats
+=============
+
+Notice that there isn't a lot in these examples that's PDF-specific -- just the
+bits using ``reportlab``. You can use a similar technique to generate any
+arbitrary format that you can find a Python library for. Also see
+:doc:`/howto/outputting-csv` for another example and some techniques you can use
+when generated text-based formats.
diff --git a/parts/django/docs/howto/static-files.txt b/parts/django/docs/howto/static-files.txt
new file mode 100644
index 0000000..c3692d5
--- /dev/null
+++ b/parts/django/docs/howto/static-files.txt
@@ -0,0 +1,162 @@
+=========================
+How to serve static files
+=========================
+
+.. module:: django.views.static
+ :synopsis: Serving of static files during development.
+
+Django itself doesn't serve static (media) files, such as images, style sheets,
+or video. It leaves that job to whichever Web server you choose.
+
+The reasoning here is that standard Web servers, such as Apache_, lighttpd_ and
+Cherokee_, are much more fine-tuned at serving static files than a Web
+application framework.
+
+With that said, Django does support static files **during development**. You can
+use the :func:`django.views.static.serve` view to serve media files.
+
+.. _Apache: http://httpd.apache.org/
+.. _lighttpd: http://www.lighttpd.net/
+.. _Cherokee: http://www.cherokee-project.com/
+
+.. seealso::
+
+ If you just need to serve the admin media from a nonstandard location, see
+ the :djadminopt:`--adminmedia` parameter to :djadmin:`runserver`.
+
+The big, fat disclaimer
+=======================
+
+Using this method is **inefficient** and **insecure**. Do not use this in a
+production setting. Use this only for development.
+
+For information on serving static files in an Apache production environment,
+see the :ref:`Django mod_python documentation <serving-media-files>`.
+
+How to do it
+============
+
+Here's the formal definition of the :func:`~django.views.static.serve` view:
+
+.. function:: def serve(request, path, document_root, show_indexes=False)
+
+To use it, just put this in your :doc:`URLconf </topics/http/urls>`::
+
+ (r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
+ {'document_root': '/path/to/media'}),
+
+...where ``site_media`` is the URL where your media will be rooted, and
+``/path/to/media`` is the filesystem root for your media. This will call the
+:func:`~django.views.static.serve` view, passing in the path from the URLconf
+and the (required) ``document_root`` parameter.
+
+Given the above URLconf:
+
+ * The file ``/path/to/media/foo.jpg`` will be made available at the URL
+ ``/site_media/foo.jpg``.
+
+ * The file ``/path/to/media/css/mystyles.css`` will be made available
+ at the URL ``/site_media/css/mystyles.css``.
+
+ * The file ``/path/bar.jpg`` will not be accessible, because it doesn't
+ fall under the document root.
+
+Of course, it's not compulsory to use a fixed string for the
+``'document_root'`` value. You might wish to make that an entry in your
+settings file and use the setting value there. That will allow you and
+other developers working on the code to easily change the value as
+required. For example, if we have a line in ``settings.py`` that says::
+
+ STATIC_DOC_ROOT = '/path/to/media'
+
+...we could write the above :doc:`URLconf </topics/http/urls>` entry as::
+
+ from django.conf import settings
+ ...
+ (r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
+ {'document_root': settings.STATIC_DOC_ROOT}),
+
+Be careful not to use the same path as your :setting:`ADMIN_MEDIA_PREFIX` (which defaults
+to ``/media/``) as this will overwrite your URLconf entry.
+
+Directory listings
+==================
+
+Optionally, you can pass the ``show_indexes`` parameter to the
+:func:`~django.views.static.serve` view. This is ``False`` by default. If it's
+``True``, Django will display file listings for directories.
+
+For example::
+
+ (r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
+ {'document_root': '/path/to/media', 'show_indexes': True}),
+
+You can customize the index view by creating a template called
+``static/directory_index.html``. That template gets two objects in its context:
+
+ * ``directory`` -- the directory name (a string)
+ * ``file_list`` -- a list of file names (as strings) in the directory
+
+Here's the default ``static/directory_index.html`` template:
+
+.. code-block:: html+django
+
+ <!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>
+ <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
+ <meta http-equiv="Content-Language" content="en-us" />
+ <meta name="robots" content="NONE,NOARCHIVE" />
+ <title>Index of {{ directory }}</title>
+ </head>
+ <body>
+ <h1>Index of {{ directory }}</h1>
+ <ul>
+ {% for f in file_list %}
+ <li><a href="{{ f }}">{{ f }}</a></li>
+ {% endfor %}
+ </ul>
+ </body>
+ </html>
+
+.. versionchanged:: 1.0.3
+ Prior to Django 1.0.3, there was a bug in the view that provided directory
+ listings. The template that was loaded had to be called
+ ``static/directory_listing`` (with no ``.html`` extension). For backwards
+ compatibility with earlier versions, Django will still load templates with
+ the older (no extension) name, but it will prefer the
+ ``directory_index.html`` version.
+
+Limiting use to DEBUG=True
+==========================
+
+Because URLconfs are just plain Python modules, you can use Python logic to
+make the static-media view available only in development mode. This is a handy
+trick to make sure the static-serving view doesn't slip into a production
+setting by mistake.
+
+Do this by wrapping an ``if DEBUG`` statement around the
+:func:`django.views.static.serve` inclusion. Here's a full example URLconf::
+
+ from django.conf.urls.defaults import *
+ from django.conf import settings
+
+ 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'),
+ )
+
+ if settings.DEBUG:
+ urlpatterns += patterns('',
+ (r'^site_media/(?P<path>.*)$', 'django.views.static.serve', {'document_root': '/path/to/media'}),
+ )
+
+This code is straightforward. It imports the settings and checks the value of
+the :setting:`DEBUG` setting. If it evaluates to ``True``, then ``site_media``
+will be associated with the ``django.views.static.serve`` view. If not, then the
+view won't be made available.
+
+Of course, the catch here is that you'll have to remember to set ``DEBUG=False``
+in your production settings file. But you should be doing that anyway.