summaryrefslogtreecommitdiff
path: root/parts/django/docs/topics/http
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/topics/http
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/topics/http')
-rw-r--r--parts/django/docs/topics/http/_images/middleware.pngbin0 -> 56301 bytes
-rw-r--r--parts/django/docs/topics/http/file-uploads.txt394
-rw-r--r--parts/django/docs/topics/http/generic-views.txt5
-rw-r--r--parts/django/docs/topics/http/index.txt15
-rw-r--r--parts/django/docs/topics/http/middleware.txt179
-rw-r--r--parts/django/docs/topics/http/sessions.txt529
-rw-r--r--parts/django/docs/topics/http/shortcuts.txt229
-rw-r--r--parts/django/docs/topics/http/urls.txt890
-rw-r--r--parts/django/docs/topics/http/views.txt202
9 files changed, 2443 insertions, 0 deletions
diff --git a/parts/django/docs/topics/http/_images/middleware.png b/parts/django/docs/topics/http/_images/middleware.png
new file mode 100644
index 0000000..505c70a
--- /dev/null
+++ b/parts/django/docs/topics/http/_images/middleware.png
Binary files differ
diff --git a/parts/django/docs/topics/http/file-uploads.txt b/parts/django/docs/topics/http/file-uploads.txt
new file mode 100644
index 0000000..a06a1ca
--- /dev/null
+++ b/parts/django/docs/topics/http/file-uploads.txt
@@ -0,0 +1,394 @@
+============
+File Uploads
+============
+
+.. currentmodule:: django.core.files
+
+.. versionadded:: 1.0
+
+When Django handles a file upload, the file data ends up placed in
+:attr:`request.FILES <django.http.HttpRequest.FILES>` (for more on the
+``request`` object see the documentation for :doc:`request and response objects
+</ref/request-response>`). This document explains how files are stored on disk
+and in memory, and how to customize the default behavior.
+
+Basic file uploads
+==================
+
+Consider a simple form containing a :class:`~django.forms.FileField`::
+
+ from django import forms
+
+ class UploadFileForm(forms.Form):
+ title = forms.CharField(max_length=50)
+ file = forms.FileField()
+
+A view handling this form will receive the file data in
+:attr:`request.FILES <django.http.HttpRequest.FILES>`, which is a dictionary
+containing a key for each :class:`~django.forms.FileField` (or
+:class:`~django.forms.ImageField`, or other :class:`~django.forms.FileField`
+subclass) in the form. So the data from the above form would
+be accessible as ``request.FILES['file']``.
+
+Note that :attr:`request.FILES <django.http.HttpRequest.FILES>` will only
+contain data if the request method was ``POST`` and the ``<form>`` that posted
+the request has the attribute ``enctype="multipart/form-data"``. Otherwise,
+``request.FILES`` will be empty.
+
+Most of the time, you'll simply pass the file data from ``request`` into the
+form as described in :ref:`binding-uploaded-files`. This would look
+something like::
+
+ from django.http import HttpResponseRedirect
+ from django.shortcuts import render_to_response
+
+ # Imaginary function to handle an uploaded file.
+ from somewhere import handle_uploaded_file
+
+ def upload_file(request):
+ if request.method == 'POST':
+ form = UploadFileForm(request.POST, request.FILES)
+ if form.is_valid():
+ handle_uploaded_file(request.FILES['file'])
+ return HttpResponseRedirect('/success/url/')
+ else:
+ form = UploadFileForm()
+ return render_to_response('upload.html', {'form': form})
+
+Notice that we have to pass :attr:`request.FILES <django.http.HttpRequest.FILES>`
+into the form's constructor; this is how file data gets bound into a form.
+
+Handling uploaded files
+-----------------------
+
+The final piece of the puzzle is handling the actual file data from
+:attr:`request.FILES <django.http.HttpRequest.FILES>`. Each entry in this
+dictionary is an ``UploadedFile`` object -- a simple wrapper around an uploaded
+file. You'll usually use one of these methods to access the uploaded content:
+
+ ``UploadedFile.read()``
+ Read the entire uploaded data from the file. Be careful with this
+ method: if the uploaded file is huge it can overwhelm your system if you
+ try to read it into memory. You'll probably want to use ``chunks()``
+ instead; see below.
+
+ ``UploadedFile.multiple_chunks()``
+ Returns ``True`` if the uploaded file is big enough to require
+ reading in multiple chunks. By default this will be any file
+ larger than 2.5 megabytes, but that's configurable; see below.
+
+ ``UploadedFile.chunks()``
+ A generator returning chunks of the file. If ``multiple_chunks()`` is
+ ``True``, you should use this method in a loop instead of ``read()``.
+
+ In practice, it's often easiest simply to use ``chunks()`` all the time;
+ see the example below.
+
+ ``UploadedFile.name``
+ The name of the uploaded file (e.g. ``my_file.txt``).
+
+ ``UploadedFile.size``
+ The size, in bytes, of the uploaded file.
+
+There are a few other methods and attributes available on ``UploadedFile``
+objects; see `UploadedFile objects`_ for a complete reference.
+
+Putting it all together, here's a common way you might handle an uploaded file::
+
+ def handle_uploaded_file(f):
+ destination = open('some/file/name.txt', 'wb+')
+ for chunk in f.chunks():
+ destination.write(chunk)
+ destination.close()
+
+Looping over ``UploadedFile.chunks()`` instead of using ``read()`` ensures that
+large files don't overwhelm your system's memory.
+
+Where uploaded data is stored
+-----------------------------
+
+Before you save uploaded files, the data needs to be stored somewhere.
+
+By default, if an uploaded file is smaller than 2.5 megabytes, Django will hold
+the entire contents of the upload in memory. This means that saving the file
+involves only a read from memory and a write to disk and thus is very fast.
+
+However, if an uploaded file is too large, Django will write the uploaded file
+to a temporary file stored in your system's temporary directory. On a Unix-like
+platform this means you can expect Django to generate a file called something
+like ``/tmp/tmpzfp6I6.upload``. If an upload is large enough, you can watch this
+file grow in size as Django streams the data onto disk.
+
+These specifics -- 2.5 megabytes; ``/tmp``; etc. -- are simply "reasonable
+defaults". Read on for details on how you can customize or completely replace
+upload behavior.
+
+Changing upload handler behavior
+--------------------------------
+
+Three settings control Django's file upload behavior:
+
+ :setting:`FILE_UPLOAD_MAX_MEMORY_SIZE`
+ The maximum size, in bytes, for files that will be uploaded into memory.
+ Files larger than :setting:`FILE_UPLOAD_MAX_MEMORY_SIZE` will be
+ streamed to disk.
+
+ Defaults to 2.5 megabytes.
+
+ :setting:`FILE_UPLOAD_TEMP_DIR`
+ The directory where uploaded files larger than
+ :setting:`FILE_UPLOAD_MAX_MEMORY_SIZE` will be stored.
+
+ Defaults to your system's standard temporary directory (i.e. ``/tmp`` on
+ most Unix-like systems).
+
+ :setting:`FILE_UPLOAD_PERMISSIONS`
+ The numeric mode (i.e. ``0644``) to set newly uploaded files to. For
+ more information about what these modes mean, see the `documentation for
+ os.chmod`_
+
+ If this isn't given or is ``None``, you'll get operating-system
+ dependent behavior. On most platforms, temporary files will have a mode
+ of ``0600``, and files saved from memory will be saved using the
+ system's standard umask.
+
+ .. warning::
+
+ If you're not familiar with file modes, please note that the leading
+ ``0`` is very important: it indicates an octal number, which is the
+ way that modes must be specified. If you try to use ``644``, you'll
+ get totally incorrect behavior.
+
+ **Always prefix the mode with a 0.**
+
+ :setting:`FILE_UPLOAD_HANDLERS`
+ The actual handlers for uploaded files. Changing this setting allows
+ complete customization -- even replacement -- of Django's upload
+ process. See `upload handlers`_, below, for details.
+
+ Defaults to::
+
+ ("django.core.files.uploadhandler.MemoryFileUploadHandler",
+ "django.core.files.uploadhandler.TemporaryFileUploadHandler",)
+
+ Which means "try to upload to memory first, then fall back to temporary
+ files."
+
+.. _documentation for os.chmod: http://docs.python.org/library/os.html#os.chmod
+
+``UploadedFile`` objects
+========================
+
+.. class:: UploadedFile
+
+In addition to those inherited from :class:`File`, all ``UploadedFile`` objects
+define the following methods/attributes:
+
+ ``UploadedFile.content_type``
+ The content-type header uploaded with the file (e.g. ``text/plain`` or
+ ``application/pdf``). Like any data supplied by the user, you shouldn't
+ trust that the uploaded file is actually this type. You'll still need to
+ validate that the file contains the content that the content-type header
+ claims -- "trust but verify."
+
+ ``UploadedFile.charset``
+ For ``text/*`` content-types, the character set (i.e. ``utf8``) supplied
+ by the browser. Again, "trust but verify" is the best policy here.
+
+ ``UploadedFile.temporary_file_path()``
+ Only files uploaded onto disk will have this method; it returns the full
+ path to the temporary uploaded file.
+
+.. note::
+
+ Like regular Python files, you can read the file line-by-line simply by
+ iterating over the uploaded file:
+
+ .. code-block:: python
+
+ for line in uploadedfile:
+ do_something_with(line)
+
+ However, *unlike* standard Python files, :class:`UploadedFile` only
+ understands ``\n`` (also known as "Unix-style") line endings. If you know
+ that you need to handle uploaded files with different line endings, you'll
+ need to do so in your view.
+
+Upload Handlers
+===============
+
+When a user uploads a file, Django passes off the file data to an *upload
+handler* -- a small class that handles file data as it gets uploaded. Upload
+handlers are initially defined in the ``FILE_UPLOAD_HANDLERS`` setting, which
+defaults to::
+
+ ("django.core.files.uploadhandler.MemoryFileUploadHandler",
+ "django.core.files.uploadhandler.TemporaryFileUploadHandler",)
+
+Together the ``MemoryFileUploadHandler`` and ``TemporaryFileUploadHandler``
+provide Django's default file upload behavior of reading small files into memory
+and large ones onto disk.
+
+You can write custom handlers that customize how Django handles files. You
+could, for example, use custom handlers to enforce user-level quotas, compress
+data on the fly, render progress bars, and even send data to another storage
+location directly without storing it locally.
+
+Modifying upload handlers on the fly
+------------------------------------
+
+Sometimes particular views require different upload behavior. In these cases,
+you can override upload handlers on a per-request basis by modifying
+``request.upload_handlers``. By default, this list will contain the upload
+handlers given by ``FILE_UPLOAD_HANDLERS``, but you can modify the list as you
+would any other list.
+
+For instance, suppose you've written a ``ProgressBarUploadHandler`` that
+provides feedback on upload progress to some sort of AJAX widget. You'd add this
+handler to your upload handlers like this::
+
+ request.upload_handlers.insert(0, ProgressBarUploadHandler())
+
+You'd probably want to use ``list.insert()`` in this case (instead of
+``append()``) because a progress bar handler would need to run *before* any
+other handlers. Remember, the upload handlers are processed in order.
+
+If you want to replace the upload handlers completely, you can just assign a new
+list::
+
+ request.upload_handlers = [ProgressBarUploadHandler()]
+
+.. note::
+
+ You can only modify upload handlers *before* accessing
+ ``request.POST`` or ``request.FILES`` -- it doesn't make sense to
+ change upload handlers after upload handling has already
+ started. If you try to modify ``request.upload_handlers`` after
+ reading from ``request.POST`` or ``request.FILES`` Django will
+ throw an error.
+
+ Thus, you should always modify uploading handlers as early in your view as
+ possible.
+
+ Also, ``request.POST`` is accessed by
+ :class:`~django.middleware.csrf.CsrfViewMiddleware` which is enabled by
+ default. This means you will probably need to use
+ :func:`~django.views.decorators.csrf.csrf_exempt` on your view to allow you
+ to change the upload handlers. Assuming you do need CSRF protection, you
+ will then need to use :func:`~django.views.decorators.csrf.csrf_protect` on
+ the function that actually processes the request. Note that this means that
+ the handlers may start receiving the file upload before the CSRF checks have
+ been done. Example code:
+
+ .. code-block:: python
+
+ from django.views.decorators.csrf import csrf_exempt, csrf_protect
+
+ @csrf_exempt
+ def upload_file_view(request):
+ request.upload_handlers.insert(0, ProgressBarUploadHandler())
+ return _upload_file_view(request)
+
+ @csrf_protect
+ def _upload_file_view(request):
+ ... # Process request
+
+
+Writing custom upload handlers
+------------------------------
+
+All file upload handlers should be subclasses of
+``django.core.files.uploadhandler.FileUploadHandler``. You can define upload
+handlers wherever you wish.
+
+Required methods
+~~~~~~~~~~~~~~~~
+
+Custom file upload handlers **must** define the following methods:
+
+ ``FileUploadHandler.receive_data_chunk(self, raw_data, start)``
+ Receives a "chunk" of data from the file upload.
+
+ ``raw_data`` is a byte string containing the uploaded data.
+
+ ``start`` is the position in the file where this ``raw_data`` chunk
+ begins.
+
+ The data you return will get fed into the subsequent upload handlers'
+ ``receive_data_chunk`` methods. In this way, one handler can be a
+ "filter" for other handlers.
+
+ Return ``None`` from ``receive_data_chunk`` to sort-circuit remaining
+ upload handlers from getting this chunk.. This is useful if you're
+ storing the uploaded data yourself and don't want future handlers to
+ store a copy of the data.
+
+ If you raise a ``StopUpload`` or a ``SkipFile`` exception, the upload
+ will abort or the file will be completely skipped.
+
+ ``FileUploadHandler.file_complete(self, file_size)``
+ Called when a file has finished uploading.
+
+ The handler should return an ``UploadedFile`` object that will be stored
+ in ``request.FILES``. Handlers may also return ``None`` to indicate that
+ the ``UploadedFile`` object should come from subsequent upload handlers.
+
+Optional methods
+~~~~~~~~~~~~~~~~
+
+Custom upload handlers may also define any of the following optional methods or
+attributes:
+
+ ``FileUploadHandler.chunk_size``
+ Size, in bytes, of the "chunks" Django should store into memory and feed
+ into the handler. That is, this attribute controls the size of chunks
+ fed into ``FileUploadHandler.receive_data_chunk``.
+
+ For maximum performance the chunk sizes should be divisible by ``4`` and
+ should not exceed 2 GB (2\ :sup:`31` bytes) in size. When there are
+ multiple chunk sizes provided by multiple handlers, Django will use the
+ smallest chunk size defined by any handler.
+
+ The default is 64*2\ :sup:`10` bytes, or 64 KB.
+
+ ``FileUploadHandler.new_file(self, field_name, file_name, content_type, content_length, charset)``
+ Callback signaling that a new file upload is starting. This is called
+ before any data has been fed to any upload handlers.
+
+ ``field_name`` is a string name of the file ``<input>`` field.
+
+ ``file_name`` is the unicode filename that was provided by the browser.
+
+ ``content_type`` is the MIME type provided by the browser -- E.g.
+ ``'image/jpeg'``.
+
+ ``content_length`` is the length of the image given by the browser.
+ Sometimes this won't be provided and will be ``None``.
+
+ ``charset`` is the character set (i.e. ``utf8``) given by the browser.
+ Like ``content_length``, this sometimes won't be provided.
+
+ This method may raise a ``StopFutureHandlers`` exception to prevent
+ future handlers from handling this file.
+
+ ``FileUploadHandler.upload_complete(self)``
+ Callback signaling that the entire upload (all files) has completed.
+
+ ``FileUploadHandler.handle_raw_input(self, input_data, META, content_length, boundary, encoding)``
+ Allows the handler to completely override the parsing of the raw
+ HTTP input.
+
+ ``input_data`` is a file-like object that supports ``read()``-ing.
+
+ ``META`` is the same object as ``request.META``.
+
+ ``content_length`` is the length of the data in ``input_data``. Don't
+ read more than ``content_length`` bytes from ``input_data``.
+
+ ``boundary`` is the MIME boundary for this request.
+
+ ``encoding`` is the encoding of the request.
+
+ Return ``None`` if you want upload handling to continue, or a tuple of
+ ``(POST, FILES)`` if you want to return the new data structures suitable
+ for the request directly.
diff --git a/parts/django/docs/topics/http/generic-views.txt b/parts/django/docs/topics/http/generic-views.txt
new file mode 100644
index 0000000..15f895e
--- /dev/null
+++ b/parts/django/docs/topics/http/generic-views.txt
@@ -0,0 +1,5 @@
+=============
+Generic views
+=============
+
+See :doc:`/ref/generic-views`.
diff --git a/parts/django/docs/topics/http/index.txt b/parts/django/docs/topics/http/index.txt
new file mode 100644
index 0000000..5ef776d
--- /dev/null
+++ b/parts/django/docs/topics/http/index.txt
@@ -0,0 +1,15 @@
+Handling HTTP requests
+======================
+
+Information on handling HTTP requests in Django:
+
+.. toctree::
+ :maxdepth: 1
+
+ urls
+ views
+ file-uploads
+ shortcuts
+ generic-views
+ middleware
+ sessions
diff --git a/parts/django/docs/topics/http/middleware.txt b/parts/django/docs/topics/http/middleware.txt
new file mode 100644
index 0000000..d376c6b
--- /dev/null
+++ b/parts/django/docs/topics/http/middleware.txt
@@ -0,0 +1,179 @@
+==========
+Middleware
+==========
+
+Middleware is a framework of hooks into Django's request/response processing.
+It's a light, low-level "plugin" system for globally altering Django's input
+and/or output.
+
+Each middleware component is responsible for doing some specific function. For
+example, Django includes a middleware component, ``XViewMiddleware``, that adds
+an ``"X-View"`` HTTP header to every response to a ``HEAD`` request.
+
+This document explains how middleware works, how you activate middleware, and
+how to write your own middleware. Django ships with some built-in middleware
+you can use right out of the box; they're documented in the :doc:`built-in
+middleware reference </ref/middleware>`.
+
+Activating middleware
+=====================
+
+To activate a middleware component, add it to the :setting:`MIDDLEWARE_CLASSES`
+list in your Django settings. In :setting:`MIDDLEWARE_CLASSES`, each middleware
+component is represented by a string: the full Python path to the middleware's
+class name. For example, here's the default :setting:`MIDDLEWARE_CLASSES`
+created by :djadmin:`django-admin.py startproject <startproject>`::
+
+ MIDDLEWARE_CLASSES = (
+ 'django.middleware.common.CommonMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
+ )
+
+During the request phases (:meth:`process_request` and :meth:`process_view`
+middleware), Django applies middleware in the order it's defined in
+:setting:`MIDDLEWARE_CLASSES`, top-down. During the response phases
+(:meth:`process_response` and :meth:`process_exception` middleware), the
+classes are applied in reverse order, from the bottom up. You can think of it
+like an onion: each middleware class is a "layer" that wraps the view:
+
+.. image:: _images/middleware.png
+ :width: 502
+ :height: 417
+ :alt: Middleware application order.
+
+A Django installation doesn't require any middleware -- e.g.,
+:setting:`MIDDLEWARE_CLASSES` can be empty, if you'd like -- but it's strongly
+suggested that you at least use
+:class:`~django.middleware.common.CommonMiddleware`.
+
+Writing your own middleware
+===========================
+
+Writing your own middleware is easy. Each middleware component is a single
+Python class that defines one or more of the following methods:
+
+.. _request-middleware:
+
+``process_request``
+-------------------
+
+.. method:: process_request(self, request)
+
+``request`` is an :class:`~django.http.HttpRequest` object. This method is
+called on each request, before Django decides which view to execute.
+
+``process_request()`` should return either ``None`` or an
+:class:`~django.http.HttpResponse` object. If it returns ``None``, Django will
+continue processing this request, executing any other middleware and, then, the
+appropriate view. If it returns an :class:`~django.http.HttpResponse` object,
+Django won't bother calling ANY other request, view or exception middleware, or
+the appropriate view; it'll return that :class:`~django.http.HttpResponse`.
+Response middleware is always called on every response.
+
+.. _view-middleware:
+
+``process_view``
+----------------
+
+.. method:: process_view(self, request, view_func, view_args, view_kwargs)
+
+``request`` is an :class:`~django.http.HttpRequest` object. ``view_func`` is
+the Python function that Django is about to use. (It's the actual function
+object, not the name of the function as a string.) ``view_args`` is a list of
+positional arguments that will be passed to the view, and ``view_kwargs`` is a
+dictionary of keyword arguments that will be passed to the view. Neither
+``view_args`` nor ``view_kwargs`` include the first view argument
+(``request``).
+
+``process_view()`` is called just before Django calls the view. It should
+return either ``None`` or an :class:`~django.http.HttpResponse` object. If it
+returns ``None``, Django will continue processing this request, executing any
+other ``process_view()`` middleware and, then, the appropriate view. If it
+returns an :class:`~django.http.HttpResponse` object, Django won't bother
+calling ANY other request, view or exception middleware, or the appropriate
+view; it'll return that :class:`~django.http.HttpResponse`. Response
+middleware is always called on every response.
+
+.. _response-middleware:
+
+``process_response``
+--------------------
+
+.. method:: process_response(self, request, response)
+
+``request`` is an :class:`~django.http.HttpRequest` object. ``response`` is the
+:class:`~django.http.HttpResponse` object returned by a Django view.
+
+``process_response()`` must return an :class:`~django.http.HttpResponse`
+object. It could alter the given ``response``, or it could create and return a
+brand-new :class:`~django.http.HttpResponse`.
+
+Unlike the ``process_request()`` and ``process_view()`` methods, the
+``process_response()`` method is always called, even if the ``process_request()``
+and ``process_view()`` methods of the same middleware class were skipped because
+an earlier middleware method returned an :class:`~django.http.HttpResponse`
+(this means that your ``process_response()`` method cannot rely on setup done in
+``process_request()``, for example). In addition, during the response phase the
+classes are applied in reverse order, from the bottom up. This means classes
+defined at the end of :setting:`MIDDLEWARE_CLASSES` will be run first.
+
+.. _exception-middleware:
+
+``process_exception``
+---------------------
+
+.. method:: process_exception(self, request, exception)
+
+``request`` is an :class:`~django.http.HttpRequest` object. ``exception`` is an
+``Exception`` object raised by the view function.
+
+Django calls ``process_exception()`` when a view raises an exception.
+``process_exception()`` should return either ``None`` or an
+:class:`~django.http.HttpResponse` object. If it returns an
+:class:`~django.http.HttpResponse` object, the response will be returned to
+the browser. Otherwise, default exception handling kicks in.
+
+Again, middleware are run in reverse order during the response phase, which
+includes ``process_exception``. If an exception middleware return a response,
+the middleware classes above that middleware will not be called at all.
+
+``__init__``
+------------
+
+Most middleware classes won't need an initializer since middleware classes are
+essentially placeholders for the ``process_*`` methods. If you do need some
+global state you may use ``__init__`` to set up. However, keep in mind a couple
+of caveats:
+
+ * Django initializes your middleware without any arguments, so you can't
+ define ``__init__`` as requiring any arguments.
+
+ * Unlike the ``process_*`` methods which get called once per request,
+ ``__init__`` gets called only *once*, when the Web server starts up.
+
+Marking middleware as unused
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+It's sometimes useful to determine at run-time whether a piece of middleware
+should be used. In these cases, your middleware's ``__init__`` method may raise
+``django.core.exceptions.MiddlewareNotUsed``. Django will then remove that
+piece of middleware from the middleware process.
+
+Guidelines
+----------
+
+ * Middleware classes don't have to subclass anything.
+
+ * The middleware class can live anywhere on your Python path. All Django
+ cares about is that the :setting:`MIDDLEWARE_CLASSES` setting includes
+ the path to it.
+
+ * Feel free to look at :doc:`Django's available middleware
+ </ref/middleware>` for examples.
+
+ * If you write a middleware component that you think would be useful to
+ other people, contribute to the community! :doc:`Let us know
+ </internals/contributing>`, and we'll consider adding it to Django.
diff --git a/parts/django/docs/topics/http/sessions.txt b/parts/django/docs/topics/http/sessions.txt
new file mode 100644
index 0000000..8a0f0d4
--- /dev/null
+++ b/parts/django/docs/topics/http/sessions.txt
@@ -0,0 +1,529 @@
+===================
+How to use sessions
+===================
+
+.. module:: django.contrib.sessions
+ :synopsis: Provides session management for Django projects.
+
+Django provides full support for anonymous sessions. The session framework lets
+you store and retrieve arbitrary data on a per-site-visitor basis. It stores
+data on the server side and abstracts the sending and receiving of cookies.
+Cookies contain a session ID -- not the data itself.
+
+Enabling sessions
+=================
+
+Sessions are implemented via a piece of :doc:`middleware </ref/middleware>`.
+
+To enable session functionality, do the following:
+
+ * Edit the ``MIDDLEWARE_CLASSES`` setting and make sure
+ ``MIDDLEWARE_CLASSES`` contains ``'django.contrib.sessions.middleware.SessionMiddleware'``.
+ The default ``settings.py`` created by ``django-admin.py startproject`` has
+ ``SessionMiddleware`` activated.
+
+If you don't want to use sessions, you might as well remove the
+``SessionMiddleware`` line from ``MIDDLEWARE_CLASSES`` and ``'django.contrib.sessions'``
+from your ``INSTALLED_APPS``. It'll save you a small bit of overhead.
+
+Configuring the session engine
+==============================
+
+.. versionadded:: 1.0
+
+By default, Django stores sessions in your database (using the model
+``django.contrib.sessions.models.Session``). Though this is convenient, in
+some setups it's faster to store session data elsewhere, so Django can be
+configured to store session data on your filesystem or in your cache.
+
+Using database-backed sessions
+------------------------------
+
+If you want to use a database-backed session, you need to add
+``'django.contrib.sessions'`` to your ``INSTALLED_APPS`` setting.
+
+Once you have configured your installation, run ``manage.py syncdb``
+to install the single database table that stores session data.
+
+Using cached sessions
+---------------------
+
+For better performance, you may want to use a cache-based session backend.
+
+.. versionchanged:: 1.1
+ Django 1.0 did not include the ``cached_db`` session backend.
+
+To store session data using Django's cache system, you'll first need to make
+sure you've configured your cache; see the :doc:`cache documentation
+</topics/cache>` for details.
+
+.. warning::
+
+ You should only use cache-based sessions if you're using the Memcached
+ cache backend. The local-memory cache backend doesn't retain data long
+ enough to be a good choice, and it'll be faster to use file or database
+ sessions directly instead of sending everything through the file or
+ database cache backends.
+
+Once your cache is configured, you've got two choices for how to store data in
+the cache:
+
+ * Set :setting:`SESSION_ENGINE` to
+ ``"django.contrib.sessions.backends.cache"`` for a simple caching session
+ store. Session data will be stored directly your cache. However, session
+ data may not be persistent: cached data can be evicted if the cache fills
+ up or if the cache server is restarted.
+
+ * For persistent, cached data, set :setting:`SESSION_ENGINE` to
+ ``"django.contrib.sessions.backends.cached_db"``. This uses a
+ write-through cache -- every write to the cache will also be written to
+ the database. Session reads only use the database if the data is not
+ already in the cache.
+
+Both session stores are quite fast, but the simple cache is faster because it
+disregards persistence. In most cases, the ``cached_db`` backend will be fast
+enough, but if you need that last bit of performance, and are willing to let
+session data be expunged from time to time, the ``cache`` backend is for you.
+
+If you use the ``cached_db`` session backend, you also need to follow the
+configuration instructions for the `using database-backed sessions`_.
+
+Using file-based sessions
+-------------------------
+
+To use file-based sessions, set the ``SESSION_ENGINE`` setting to
+``"django.contrib.sessions.backends.file"``.
+
+You might also want to set the ``SESSION_FILE_PATH`` setting (which defaults
+to output from ``tempfile.gettempdir()``, most likely ``/tmp``) to control
+where Django stores session files. Be sure to check that your Web server has
+permissions to read and write to this location.
+
+
+Using sessions in views
+=======================
+
+When ``SessionMiddleware`` is activated, each ``HttpRequest`` object -- the
+first argument to any Django view function -- will have a ``session``
+attribute, which is a dictionary-like object. You can read it and write to it.
+
+A session object has the following standard dictionary methods:
+
+ * ``__getitem__(key)``
+
+ Example: ``fav_color = request.session['fav_color']``
+
+ * ``__setitem__(key, value)``
+
+ Example: ``request.session['fav_color'] = 'blue'``
+
+ * ``__delitem__(key)``
+
+ Example: ``del request.session['fav_color']``. This raises ``KeyError``
+ if the given ``key`` isn't already in the session.
+
+ * ``__contains__(key)``
+
+ Example: ``'fav_color' in request.session``
+
+ * ``get(key, default=None)``
+
+ Example: ``fav_color = request.session.get('fav_color', 'red')``
+
+ * ``keys()``
+
+ * ``items()``
+
+ * ``setdefault()``
+
+ * ``clear()``
+
+.. versionadded:: 1.0
+ ``setdefault()`` and ``clear()`` are new in this version.
+
+It also has these methods:
+
+ * ``flush()``
+
+ .. versionadded:: 1.0
+
+ Delete the current session data from the session and regenerate the
+ session key value that is sent back to the user in the cookie. This is
+ used if you want to ensure that the previous session data can't be
+ accessed again from the user's browser (for example, the
+ :func:`django.contrib.auth.logout()` function calls it).
+
+ * ``set_test_cookie()``
+
+ Sets a test cookie to determine whether the user's browser supports
+ cookies. Due to the way cookies work, you won't be able to test this
+ until the user's next page request. See `Setting test cookies`_ below for
+ more information.
+
+ * ``test_cookie_worked()``
+
+ Returns either ``True`` or ``False``, depending on whether the user's
+ browser accepted the test cookie. Due to the way cookies work, you'll
+ have to call ``set_test_cookie()`` on a previous, separate page request.
+ See `Setting test cookies`_ below for more information.
+
+ * ``delete_test_cookie()``
+
+ Deletes the test cookie. Use this to clean up after yourself.
+
+ * ``set_expiry(value)``
+
+ .. versionadded:: 1.0
+
+ Sets the expiration time for the session. You can pass a number of
+ different values:
+
+ * If ``value`` is an integer, the session will expire after that
+ many seconds of inactivity. For example, calling
+ ``request.session.set_expiry(300)`` would make the session expire
+ in 5 minutes.
+
+ * If ``value`` is a ``datetime`` or ``timedelta`` object, the
+ session will expire at that specific date/time.
+
+ * If ``value`` is ``0``, the user's session cookie will expire
+ when the user's Web browser is closed.
+
+ * If ``value`` is ``None``, the session reverts to using the global
+ session expiry policy.
+
+ Reading a session is not considered activity for expiration
+ purposes. Session expiration is computed from the last time the
+ session was *modified*.
+
+ * ``get_expiry_age()``
+
+ .. versionadded:: 1.0
+
+ Returns the number of seconds until this session expires. For sessions
+ with no custom expiration (or those set to expire at browser close), this
+ will equal ``settings.SESSION_COOKIE_AGE``.
+
+ * ``get_expiry_date()``
+
+ .. versionadded:: 1.0
+
+ Returns the date this session will expire. For sessions with no custom
+ expiration (or those set to expire at browser close), this will equal the
+ date ``settings.SESSION_COOKIE_AGE`` seconds from now.
+
+ * ``get_expire_at_browser_close()``
+
+ .. versionadded:: 1.0
+
+ Returns either ``True`` or ``False``, depending on whether the user's
+ session cookie will expire when the user's Web browser is closed.
+
+You can edit ``request.session`` at any point in your view. You can edit it
+multiple times.
+
+Session object guidelines
+-------------------------
+
+ * Use normal Python strings as dictionary keys on ``request.session``. This
+ is more of a convention than a hard-and-fast rule.
+
+ * Session dictionary keys that begin with an underscore are reserved for
+ internal use by Django.
+
+ * Don't override ``request.session`` with a new object, and don't access or
+ set its attributes. Use it like a Python dictionary.
+
+Examples
+--------
+
+This simplistic view sets a ``has_commented`` variable to ``True`` after a user
+posts a comment. It doesn't let a user post a comment more than once::
+
+ def post_comment(request, new_comment):
+ if request.session.get('has_commented', False):
+ return HttpResponse("You've already commented.")
+ c = comments.Comment(comment=new_comment)
+ c.save()
+ request.session['has_commented'] = True
+ return HttpResponse('Thanks for your comment!')
+
+This simplistic view logs in a "member" of the site::
+
+ def login(request):
+ m = Member.objects.get(username=request.POST['username'])
+ if m.password == request.POST['password']:
+ request.session['member_id'] = m.id
+ return HttpResponse("You're logged in.")
+ else:
+ return HttpResponse("Your username and password didn't match.")
+
+...And this one logs a member out, according to ``login()`` above::
+
+ def logout(request):
+ try:
+ del request.session['member_id']
+ except KeyError:
+ pass
+ return HttpResponse("You're logged out.")
+
+The standard ``django.contrib.auth.logout()`` function actually does a bit
+more than this to prevent inadvertent data leakage. It calls
+``request.session.flush()``. We are using this example as a demonstration of
+how to work with session objects, not as a full ``logout()`` implementation.
+
+Setting test cookies
+====================
+
+As a convenience, Django provides an easy way to test whether the user's
+browser accepts cookies. Just call ``request.session.set_test_cookie()`` in a
+view, and call ``request.session.test_cookie_worked()`` in a subsequent view --
+not in the same view call.
+
+This awkward split between ``set_test_cookie()`` and ``test_cookie_worked()``
+is necessary due to the way cookies work. When you set a cookie, you can't
+actually tell whether a browser accepted it until the browser's next request.
+
+It's good practice to use ``delete_test_cookie()`` to clean up after yourself.
+Do this after you've verified that the test cookie worked.
+
+Here's a typical usage example::
+
+ def login(request):
+ if request.method == 'POST':
+ if request.session.test_cookie_worked():
+ request.session.delete_test_cookie()
+ return HttpResponse("You're logged in.")
+ else:
+ return HttpResponse("Please enable cookies and try again.")
+ request.session.set_test_cookie()
+ return render_to_response('foo/login_form.html')
+
+Using sessions out of views
+===========================
+
+.. versionadded:: 1.0
+
+An API is available to manipulate session data outside of a view::
+
+ >>> from django.contrib.sessions.backends.db import SessionStore
+ >>> s = SessionStore(session_key='2b1189a188b44ad18c35e113ac6ceead')
+ >>> s['last_login'] = datetime.datetime(2005, 8, 20, 13, 35, 10)
+ >>> s['last_login']
+ datetime.datetime(2005, 8, 20, 13, 35, 0)
+ >>> s.save()
+
+If you're using the ``django.contrib.sessions.backends.db`` backend, each
+session is just a normal Django model. The ``Session`` model is defined in
+``django/contrib/sessions/models.py``. Because it's a normal model, you can
+access sessions using the normal Django database API::
+
+ >>> from django.contrib.sessions.models import Session
+ >>> s = Session.objects.get(pk='2b1189a188b44ad18c35e113ac6ceead')
+ >>> s.expire_date
+ datetime.datetime(2005, 8, 20, 13, 35, 12)
+
+Note that you'll need to call ``get_decoded()`` to get the session dictionary.
+This is necessary because the dictionary is stored in an encoded format::
+
+ >>> s.session_data
+ 'KGRwMQpTJ19hdXRoX3VzZXJfaWQnCnAyCkkxCnMuMTExY2ZjODI2Yj...'
+ >>> s.get_decoded()
+ {'user_id': 42}
+
+When sessions are saved
+=======================
+
+By default, Django only saves to the session database when the session has been
+modified -- that is if any of its dictionary values have been assigned or
+deleted::
+
+ # Session is modified.
+ request.session['foo'] = 'bar'
+
+ # Session is modified.
+ del request.session['foo']
+
+ # Session is modified.
+ request.session['foo'] = {}
+
+ # Gotcha: Session is NOT modified, because this alters
+ # request.session['foo'] instead of request.session.
+ request.session['foo']['bar'] = 'baz'
+
+In the last case of the above example, we can tell the session object
+explicitly that it has been modified by setting the ``modified`` attribute on
+the session object::
+
+ request.session.modified = True
+
+To change this default behavior, set the ``SESSION_SAVE_EVERY_REQUEST`` setting
+to ``True``. If ``SESSION_SAVE_EVERY_REQUEST`` is ``True``, Django will save
+the session to the database on every single request.
+
+Note that the session cookie is only sent when a session has been created or
+modified. If ``SESSION_SAVE_EVERY_REQUEST`` is ``True``, the session cookie
+will be sent on every request.
+
+Similarly, the ``expires`` part of a session cookie is updated each time the
+session cookie is sent.
+
+Browser-length sessions vs. persistent sessions
+===============================================
+
+You can control whether the session framework uses browser-length sessions vs.
+persistent sessions with the ``SESSION_EXPIRE_AT_BROWSER_CLOSE`` setting.
+
+By default, ``SESSION_EXPIRE_AT_BROWSER_CLOSE`` is set to ``False``, which
+means session cookies will be stored in users' browsers for as long as
+``SESSION_COOKIE_AGE``. Use this if you don't want people to have to log in
+every time they open a browser.
+
+If ``SESSION_EXPIRE_AT_BROWSER_CLOSE`` is set to ``True``, Django will use
+browser-length cookies -- cookies that expire as soon as the user closes his or
+her browser. Use this if you want people to have to log in every time they open
+a browser.
+
+.. versionadded:: 1.0
+
+This setting is a global default and can be overwritten at a per-session level
+by explicitly calling ``request.session.set_expiry()`` as described above in
+`using sessions in views`_.
+
+Clearing the session table
+==========================
+
+If you're using the database backend, note that session data can accumulate in
+the ``django_session`` database table and Django does *not* provide automatic
+purging. Therefore, it's your job to purge expired sessions on a regular basis.
+
+To understand this problem, consider what happens when a user uses a session.
+When a user logs in, Django adds a row to the ``django_session`` database
+table. Django updates this row each time the session data changes. If the user
+logs out manually, Django deletes the row. But if the user does *not* log out,
+the row never gets deleted.
+
+Django provides a sample clean-up script: ``django-admin.py cleanup``.
+That script deletes any session in the session table whose ``expire_date`` is
+in the past -- but your application may have different requirements.
+
+Settings
+========
+
+A few :doc:`Django settings </ref/settings>` give you control over session behavior:
+
+SESSION_ENGINE
+--------------
+
+.. versionadded:: 1.0
+
+.. versionchanged:: 1.1
+ The ``cached_db`` backend was added
+
+Default: ``django.contrib.sessions.backends.db``
+
+Controls where Django stores session data. Valid values are:
+
+ * ``'django.contrib.sessions.backends.db'``
+ * ``'django.contrib.sessions.backends.file'``
+ * ``'django.contrib.sessions.backends.cache'``
+ * ``'django.contrib.sessions.backends.cached_db'``
+
+See `configuring the session engine`_ for more details.
+
+SESSION_FILE_PATH
+-----------------
+
+.. versionadded:: 1.0
+
+Default: ``/tmp/``
+
+If you're using file-based session storage, this sets the directory in
+which Django will store session data.
+
+SESSION_COOKIE_AGE
+------------------
+
+Default: ``1209600`` (2 weeks, in seconds)
+
+The age of session cookies, in seconds.
+
+SESSION_COOKIE_DOMAIN
+---------------------
+
+Default: ``None``
+
+The domain to use for session cookies. Set this to a string such as
+``".lawrence.com"`` (note the leading dot!) for cross-domain cookies, or use
+``None`` for a standard domain cookie.
+
+SESSION_COOKIE_NAME
+-------------------
+
+Default: ``'sessionid'``
+
+The name of the cookie to use for sessions. This can be whatever you want.
+
+SESSION_COOKIE_PATH
+-------------------
+
+.. versionadded:: 1.0
+
+Default: ``'/'``
+
+The path set on the session cookie. This should either match the URL path of
+your Django installation or be parent of that path.
+
+This is useful if you have multiple Django instances running under the same
+hostname. They can use different cookie paths, and each instance will only see
+its own session cookie.
+
+SESSION_COOKIE_SECURE
+---------------------
+
+Default: ``False``
+
+Whether to use a secure cookie for the session cookie. If this is set to
+``True``, the cookie will be marked as "secure," which means browsers may
+ensure that the cookie is only sent under an HTTPS connection.
+
+SESSION_EXPIRE_AT_BROWSER_CLOSE
+-------------------------------
+
+Default: ``False``
+
+Whether to expire the session when the user closes his or her browser. See
+"Browser-length sessions vs. persistent sessions" above.
+
+SESSION_SAVE_EVERY_REQUEST
+--------------------------
+
+Default: ``False``
+
+Whether to save the session data on every request. If this is ``False``
+(default), then the session data will only be saved if it has been modified --
+that is, if any of its dictionary values have been assigned or deleted.
+
+.. _Django settings: ../settings/
+
+Technical details
+=================
+
+ * The session dictionary should accept any pickleable Python object. See
+ `the pickle module`_ for more information.
+
+ * Session data is stored in a database table named ``django_session`` .
+
+ * Django only sends a cookie if it needs to. If you don't set any session
+ data, it won't send a session cookie.
+
+.. _`the pickle module`: http://docs.python.org/library/pickle.html
+
+Session IDs in URLs
+===================
+
+The Django sessions framework is entirely, and solely, cookie-based. It does
+not fall back to putting session IDs in URLs as a last resort, as PHP does.
+This is an intentional design decision. Not only does that behavior make URLs
+ugly, it makes your site vulnerable to session-ID theft via the "Referer"
+header.
diff --git a/parts/django/docs/topics/http/shortcuts.txt b/parts/django/docs/topics/http/shortcuts.txt
new file mode 100644
index 0000000..315460e
--- /dev/null
+++ b/parts/django/docs/topics/http/shortcuts.txt
@@ -0,0 +1,229 @@
+=========================
+Django shortcut functions
+=========================
+
+.. module:: django.shortcuts
+ :synopsis:
+ Convience shortcuts that spam multiple levels of Django's MVC stack.
+
+.. index:: shortcuts
+
+The package ``django.shortcuts`` collects helper functions and classes that
+"span" multiple levels of MVC. In other words, these functions/classes
+introduce controlled coupling for convenience's sake.
+
+``render_to_response``
+======================
+
+.. function:: render_to_response(template[, dictionary][, context_instance][, mimetype])
+
+ Renders a given template with a given context dictionary and returns an
+ :class:`~django.http.HttpResponse` object with that rendered text.
+
+Required arguments
+------------------
+
+``template``
+ The full name of a template to use or sequence of template names. If a
+ sequence is given, the first template that exists will be used. See the
+ :ref:`template loader documentation <ref-templates-api-the-python-api>`
+ for more information on how templates are found.
+
+Optional arguments
+------------------
+
+``dictionary``
+ A dictionary of values to add to the template context. By default, this
+ is an empty dictionary. If a value in the dictionary is callable, the
+ view will call it just before rendering the template.
+
+``context_instance``
+ The context instance to render the template with. By default, the template
+ will be rendered with a :class:`~django.template.Context` instance (filled
+ with values from ``dictionary``). If you need to use :ref:`context
+ processors <subclassing-context-requestcontext>`, render the template with
+ a :class:`~django.template.RequestContext` instance instead. Your code
+ might look something like this::
+
+ return render_to_response('my_template.html',
+ my_data_dictionary,
+ context_instance=RequestContext(request))
+
+``mimetype``
+ The MIME type to use for the resulting document. Defaults to the value of
+ the :setting:`DEFAULT_CONTENT_TYPE` setting.
+
+Example
+-------
+
+The following example renders the template ``myapp/index.html`` with the
+MIME type ``application/xhtml+xml``::
+
+ from django.shortcuts import render_to_response
+
+ def my_view(request):
+ # View code here...
+ return render_to_response('myapp/index.html', {"foo": "bar"},
+ mimetype="application/xhtml+xml")
+
+This example is equivalent to::
+
+ from django.http import HttpResponse
+ from django.template import Context, loader
+
+ def my_view(request):
+ # View code here...
+ t = loader.get_template('myapp/template.html')
+ c = Context({'foo': 'bar'})
+ return HttpResponse(t.render(c),
+ mimetype="application/xhtml+xml")
+
+``redirect``
+============
+
+.. function:: redirect(to[, permanent=False], *args, **kwargs)
+
+ .. versionadded:: 1.1
+
+ Returns an :class:`~django.http.HttpResponseRedirect` to the appropriate URL
+ for the arguments passed.
+
+ The arguments could be:
+
+ * A model: the model's `get_absolute_url()` function will be called.
+
+ * A view name, possibly with arguments: `urlresolvers.reverse()` will
+ be used to reverse-resolve the name.
+
+ * A URL, which will be used as-is for the redirect location.
+
+ By default issues a temporary redirect; pass ``permanent=True`` to issue a
+ permanent redirect
+
+Examples
+--------
+
+You can use the :func:`redirect` function in a number of ways.
+
+ 1. By passing some object; that object's
+ :meth:`~django.db.models.Model.get_absolute_url` method will be called
+ to figure out the redirect URL::
+
+ def my_view(request):
+ ...
+ object = MyModel.objects.get(...)
+ return redirect(object)
+
+ 2. By passing the name of a view and optionally some positional or
+ keyword arguments; the URL will be reverse resolved using the
+ :func:`~django.core.urlresolvers.reverse` method::
+
+ def my_view(request):
+ ...
+ return redirect('some-view-name', foo='bar')
+
+ 3. By passing a hardcoded URL to redirect to::
+
+ def my_view(request):
+ ...
+ return redirect('/some/url/')
+
+ This also works with full URLs::
+
+ def my_view(request):
+ ...
+ return redirect('http://example.com/')
+
+By default, :func:`redirect` returns a temporary redirect. All of the above
+forms accept a ``permanent`` argument; if set to ``True`` a permanent redirect
+will be returned::
+
+ def my_view(request):
+ ...
+ object = MyModel.objects.get(...)
+ return redirect(object, permanent=True)
+
+``get_object_or_404``
+=====================
+
+.. function:: get_object_or_404(klass, *args, **kwargs)
+
+ Calls :meth:`~django.db.models.QuerySet.get()` on a given model manager,
+ but it raises :class:`~django.http.Http404` instead of the model's
+ :class:`~django.core.exceptions.DoesNotExist` exception.
+
+Required arguments
+------------------
+
+``klass``
+ A :class:`~django.db.models.Model`, :class:`~django.db.models.Manager` or
+ :class:`~django.db.models.QuerySet` instance from which to get the object.
+
+``**kwargs``
+ Lookup parameters, which should be in the format accepted by ``get()`` and
+ ``filter()``.
+
+Example
+-------
+
+The following example gets the object with the primary key of 1 from
+``MyModel``::
+
+ from django.shortcuts import get_object_or_404
+
+ def my_view(request):
+ my_object = get_object_or_404(MyModel, pk=1)
+
+This example is equivalent to::
+
+ from django.http import Http404
+
+ def my_view(request):
+ try:
+ my_object = MyModel.objects.get(pk=1)
+ except MyModel.DoesNotExist:
+ raise Http404
+
+Note: As with ``get()``, a
+:class:`~django.core.exceptions.MultipleObjectsReturned` exception
+will be raised if more than one object is found.
+
+``get_list_or_404``
+===================
+
+.. function:: get_list_or_404(klass, *args, **kwargs)
+
+ Returns the result of :meth:`~django.db.models.QuerySet.filter()` on a
+ given model manager, raising :class:`~django.http.Http404` if the resulting
+ list is empty.
+
+Required arguments
+------------------
+
+``klass``
+ A :class:`~django.db.models.Model`, :class:`~django.db.models.Manager` or
+ :class:`~django.db.models.query.QuerySet` instance from which to get the
+ list.
+
+``**kwargs``
+ Lookup parameters, which should be in the format accepted by ``get()`` and
+ ``filter()``.
+
+Example
+-------
+
+The following example gets all published objects from ``MyModel``::
+
+ from django.shortcuts import get_list_or_404
+
+ def my_view(request):
+ my_objects = get_list_or_404(MyModel, published=True)
+
+This example is equivalent to::
+
+ from django.http import Http404
+
+ def my_view(request):
+ my_objects = list(MyModel.objects.filter(published=True))
+ if not my_objects:
+ raise Http404
diff --git a/parts/django/docs/topics/http/urls.txt b/parts/django/docs/topics/http/urls.txt
new file mode 100644
index 0000000..2361297
--- /dev/null
+++ b/parts/django/docs/topics/http/urls.txt
@@ -0,0 +1,890 @@
+==============
+URL dispatcher
+==============
+
+.. module:: django.core.urlresolvers
+
+A clean, elegant URL scheme is an important detail in a high-quality Web
+application. Django lets you design URLs however you want, with no framework
+limitations.
+
+There's no ``.php`` or ``.cgi`` required, and certainly none of that
+``0,2097,1-1-1928,00`` nonsense.
+
+See `Cool URIs don't change`_, by World Wide Web creator Tim Berners-Lee, for
+excellent arguments on why URLs should be clean and usable.
+
+.. _Cool URIs don't change: http://www.w3.org/Provider/Style/URI
+
+Overview
+========
+
+To design URLs for an app, you create a Python module informally called a
+**URLconf** (URL configuration). This module is pure Python code and
+is a simple mapping between URL patterns (as simple regular expressions) to
+Python callback functions (your views).
+
+This mapping can be as short or as long as needed. It can reference other
+mappings. And, because it's pure Python code, it can be constructed
+dynamically.
+
+.. _how-django-processes-a-request:
+
+How Django processes a request
+==============================
+
+When a user requests a page from your Django-powered site, this is the
+algorithm the system follows to determine which Python code to execute:
+
+ 1. Django determines the root URLconf module to use. Ordinarily,
+ this is the value of the :setting:`ROOT_URLCONF` setting, but if the incoming
+ ``HttpRequest`` object has an attribute called ``urlconf`` (set by
+ middleware :ref:`request processing <request-middleware>`), its value
+ will be used in place of the :setting:`ROOT_URLCONF` setting.
+
+ 2. Django loads that Python module and looks for the variable
+ ``urlpatterns``. This should be a Python list, in the format returned by
+ the function :func:`django.conf.urls.defaults.patterns`.
+
+ 3. Django runs through each URL pattern, in order, and stops at the first
+ one that matches the requested URL.
+
+ 4. Once one of the regexes matches, Django imports and calls the given
+ view, which is a simple Python function. The view gets passed an
+ :class:`~django.http.HttpRequest` as its first argument and any values
+ captured in the regex as remaining arguments.
+
+Example
+=======
+
+Here's a sample URLconf::
+
+ from django.conf.urls.defaults import *
+
+ urlpatterns = patterns('',
+ (r'^articles/2003/$', 'news.views.special_case_2003'),
+ (r'^articles/(\d{4})/$', 'news.views.year_archive'),
+ (r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
+ (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'),
+ )
+
+Notes:
+
+ * ``from django.conf.urls.defaults import *`` makes the ``patterns()``
+ function available.
+
+ * To capture a value from the URL, just put parenthesis around it.
+
+ * There's no need to add a leading slash, because every URL has that. For
+ example, it's ``^articles``, not ``^/articles``.
+
+ * The ``'r'`` in front of each regular expression string is optional but
+ recommended. It tells Python that a string is "raw" -- that nothing in
+ the string should be escaped. See `Dive Into Python's explanation`_.
+
+Example requests:
+
+ * A request to ``/articles/2005/03/`` would match the third entry in the
+ list. Django would call the function
+ ``news.views.month_archive(request, '2005', '03')``.
+
+ * ``/articles/2005/3/`` would not match any URL patterns, because the
+ third entry in the list requires two digits for the month.
+
+ * ``/articles/2003/`` would match the first pattern in the list, not the
+ second one, because the patterns are tested in order, and the first one
+ is the first test to pass. Feel free to exploit the ordering to insert
+ special cases like this.
+
+ * ``/articles/2003`` would not match any of these patterns, because each
+ pattern requires that the URL end with a slash.
+
+ * ``/articles/2003/03/3/`` would match the final pattern. Django would call
+ the function ``news.views.article_detail(request, '2003', '03', '3')``.
+
+.. _Dive Into Python's explanation: http://diveintopython.org/regular_expressions/street_addresses.html#re.matching.2.3
+
+Named groups
+============
+
+The above example used simple, *non-named* regular-expression groups (via
+parenthesis) to capture bits of the URL and pass them as *positional* arguments
+to a view. In more advanced usage, it's possible to use *named*
+regular-expression groups to capture URL bits and pass them as *keyword*
+arguments to a view.
+
+In Python regular expressions, the syntax for named regular-expression groups
+is ``(?P<name>pattern)``, where ``name`` is the name of the group and
+``pattern`` is some pattern to match.
+
+Here's the above example URLconf, rewritten to use named groups::
+
+ urlpatterns = patterns('',
+ (r'^articles/2003/$', 'news.views.special_case_2003'),
+ (r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
+ (r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/$', 'news.views.month_archive'),
+ (r'^articles/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d+)/$', 'news.views.article_detail'),
+ )
+
+This accomplishes exactly the same thing as the previous example, with one
+subtle difference: The captured values are passed to view functions as keyword
+arguments rather than positional arguments. For example:
+
+ * A request to ``/articles/2005/03/`` would call the function
+ ``news.views.month_archive(request, year='2005', month='03')``, instead
+ of ``news.views.month_archive(request, '2005', '03')``.
+
+ * A request to ``/articles/2003/03/3/`` would call the function
+ ``news.views.article_detail(request, year='2003', month='03', day='3')``.
+
+In practice, this means your URLconfs are slightly more explicit and less prone
+to argument-order bugs -- and you can reorder the arguments in your views'
+function definitions. Of course, these benefits come at the cost of brevity;
+some developers find the named-group syntax ugly and too verbose.
+
+The matching/grouping algorithm
+-------------------------------
+
+Here's the algorithm the URLconf parser follows, with respect to named groups
+vs. non-named groups in a regular expression:
+
+If there are any named arguments, it will use those, ignoring non-named arguments.
+Otherwise, it will pass all non-named arguments as positional arguments.
+
+In both cases, it will pass any extra keyword arguments as keyword arguments.
+See "Passing extra options to view functions" below.
+
+What the URLconf searches against
+=================================
+
+The URLconf searches against the requested URL, as a normal Python string. This
+does not include GET or POST parameters, or the domain name.
+
+For example, in a request to ``http://www.example.com/myapp/``, the URLconf
+will look for ``myapp/``.
+
+In a request to ``http://www.example.com/myapp/?page=3``, the URLconf will look
+for ``myapp/``.
+
+The URLconf doesn't look at the request method. In other words, all request
+methods -- ``POST``, ``GET``, ``HEAD``, etc. -- will be routed to the same
+function for the same URL.
+
+Syntax of the urlpatterns variable
+==================================
+
+``urlpatterns`` should be a Python list, in the format returned by the function
+:func:`django.conf.urls.defaults.patterns`. Always use ``patterns()`` to create
+the ``urlpatterns`` variable.
+
+Convention is to use ``from django.conf.urls.defaults import *`` at the top of
+your URLconf. This gives your module access to these objects:
+
+.. module:: django.conf.urls.defaults
+
+patterns
+--------
+
+.. function:: patterns(prefix, pattern_description, ...)
+
+A function that takes a prefix, and an arbitrary number of URL patterns, and
+returns a list of URL patterns in the format Django needs.
+
+The first argument to ``patterns()`` is a string ``prefix``. See
+`The view prefix`_ below.
+
+The remaining arguments should be tuples in this format::
+
+ (regular expression, Python callback function [, optional dictionary [, optional name]])
+
+...where ``optional dictionary`` and ``optional name`` are optional. (See
+`Passing extra options to view functions`_ below.)
+
+.. note::
+ Because `patterns()` is a function call, it accepts a maximum of 255
+ arguments (URL patterns, in this case). This is a limit for all Python
+ function calls. This is rarely a problem in practice, because you'll
+ typically structure your URL patterns modularly by using `include()`
+ sections. However, on the off-chance you do hit the 255-argument limit,
+ realize that `patterns()` returns a Python list, so you can split up the
+ construction of the list.
+
+ ::
+
+ urlpatterns = patterns('',
+ ...
+ )
+ urlpatterns += patterns('',
+ ...
+ )
+
+ Python lists have unlimited size, so there's no limit to how many URL
+ patterns you can construct. The only limit is that you can only create 254
+ at a time (the 255th argument is the initial prefix argument).
+
+url
+---
+
+.. versionadded:: 1.0
+
+.. function:: url(regex, view, kwargs=None, name=None, prefix='')
+
+You can use the ``url()`` function, instead of a tuple, as an argument to
+``patterns()``. This is convenient if you want to specify a name without the
+optional extra arguments dictionary. For example::
+
+ urlpatterns = patterns('',
+ url(r'^index/$', index_view, name="main-view"),
+ ...
+ )
+
+This function takes five arguments, most of which are optional::
+
+ url(regex, view, kwargs=None, name=None, prefix='')
+
+See `Naming URL patterns`_ for why the ``name`` parameter is useful.
+
+The ``prefix`` parameter has the same meaning as the first argument to
+``patterns()`` and is only relevant when you're passing a string as the
+``view`` parameter.
+
+handler404
+----------
+
+.. data:: handler404
+
+A callable, or a string representing the full Python import path to the view
+that should be called if none of the URL patterns match.
+
+By default, this is ``'django.views.defaults.page_not_found'``. That default
+value should suffice.
+
+.. versionchanged:: 1.2
+ Previous versions of Django only accepted strings representing import paths.
+
+handler500
+----------
+
+.. data:: handler500
+
+A callable, or a string representing the full Python import path to the view
+that should be called in case of server errors. Server errors happen when you
+have runtime errors in view code.
+
+By default, this is ``'django.views.defaults.server_error'``. That default
+value should suffice.
+
+.. versionchanged:: 1.2
+ Previous versions of Django only accepted strings representing import paths.
+
+include
+-------
+
+.. function:: include(<module or pattern_list>)
+
+A function that takes a full Python import path to another URLconf module that
+should be "included" in this place.
+
+.. versionadded:: 1.1
+
+:func:`include` also accepts as an argument an iterable that returns URL
+patterns.
+
+See `Including other URLconfs`_ below.
+
+Notes on capturing text in URLs
+===============================
+
+Each captured argument is sent to the view as a plain Python string, regardless
+of what sort of match the regular expression makes. For example, in this
+URLconf line::
+
+ (r'^articles/(?P<year>\d{4})/$', 'news.views.year_archive'),
+
+...the ``year`` argument to ``news.views.year_archive()`` will be a string, not
+an integer, even though the ``\d{4}`` will only match integer strings.
+
+A convenient trick is to specify default parameters for your views' arguments.
+Here's an example URLconf and view::
+
+ # URLconf
+ urlpatterns = patterns('',
+ (r'^blog/$', 'blog.views.page'),
+ (r'^blog/page(?P<num>\d+)/$', 'blog.views.page'),
+ )
+
+ # View (in blog/views.py)
+ def page(request, num="1"):
+ # Output the appropriate page of blog entries, according to num.
+
+In the above example, both URL patterns point to the same view --
+``blog.views.page`` -- but the first pattern doesn't capture anything from the
+URL. If the first pattern matches, the ``page()`` function will use its
+default argument for ``num``, ``"1"``. If the second pattern matches,
+``page()`` will use whatever ``num`` value was captured by the regex.
+
+Performance
+===========
+
+Each regular expression in a ``urlpatterns`` is compiled the first time it's
+accessed. This makes the system blazingly fast.
+
+The view prefix
+===============
+
+You can specify a common prefix in your ``patterns()`` call, to cut down on
+code duplication.
+
+Here's the example URLconf from the :doc:`Django overview </intro/overview>`::
+
+ from django.conf.urls.defaults import *
+
+ urlpatterns = patterns('',
+ (r'^articles/(\d{4})/$', 'news.views.year_archive'),
+ (r'^articles/(\d{4})/(\d{2})/$', 'news.views.month_archive'),
+ (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'news.views.article_detail'),
+ )
+
+In this example, each view has a common prefix -- ``'news.views'``.
+Instead of typing that out for each entry in ``urlpatterns``, you can use the
+first argument to the ``patterns()`` function to specify a prefix to apply to
+each view function.
+
+With this in mind, the above example can be written more concisely as::
+
+ from django.conf.urls.defaults import *
+
+ urlpatterns = patterns('news.views',
+ (r'^articles/(\d{4})/$', 'year_archive'),
+ (r'^articles/(\d{4})/(\d{2})/$', 'month_archive'),
+ (r'^articles/(\d{4})/(\d{2})/(\d+)/$', 'article_detail'),
+ )
+
+Note that you don't put a trailing dot (``"."``) in the prefix. Django puts
+that in automatically.
+
+Multiple view prefixes
+----------------------
+
+In practice, you'll probably end up mixing and matching views to the point
+where the views in your ``urlpatterns`` won't have a common prefix. However,
+you can still take advantage of the view prefix shortcut to remove duplication.
+Just add multiple ``patterns()`` objects together, like this:
+
+Old::
+
+ from django.conf.urls.defaults import *
+
+ urlpatterns = patterns('',
+ (r'^$', 'django.views.generic.date_based.archive_index'),
+ (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', 'django.views.generic.date_based.archive_month'),
+ (r'^tag/(?P<tag>\w+)/$', 'weblog.views.tag'),
+ )
+
+New::
+
+ from django.conf.urls.defaults import *
+
+ urlpatterns = patterns('django.views.generic.date_based',
+ (r'^$', 'archive_index'),
+ (r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$','archive_month'),
+ )
+
+ urlpatterns += patterns('weblog.views',
+ (r'^tag/(?P<tag>\w+)/$', 'tag'),
+ )
+
+Including other URLconfs
+========================
+
+At any point, your ``urlpatterns`` can "include" other URLconf modules. This
+essentially "roots" a set of URLs below other ones.
+
+For example, here's the URLconf for the `Django Web site`_ itself. It includes a
+number of other URLconfs::
+
+ from django.conf.urls.defaults import *
+
+ urlpatterns = patterns('',
+ (r'^weblog/', include('django_website.apps.blog.urls.blog')),
+ (r'^documentation/', include('django_website.apps.docs.urls.docs')),
+ (r'^comments/', include('django.contrib.comments.urls')),
+ )
+
+Note that the regular expressions in this example don't have a ``$``
+(end-of-string match character) but do include a trailing slash. Whenever
+Django encounters ``include()``, it chops off whatever part of the URL matched
+up to that point and sends the remaining string to the included URLconf for
+further processing.
+
+.. versionadded:: 1.1
+
+Another possibility is to include additional URL patterns not by specifying the
+URLconf Python module defining them as the `include`_ argument but by using
+directly the pattern list as returned by `patterns`_ instead. For example::
+
+ from django.conf.urls.defaults import *
+
+ extra_patterns = patterns('',
+ url(r'reports/(?P<id>\d+)/$', 'credit.views.report', name='credit-reports'),
+ url(r'charge/$', 'credit.views.charge', name='credit-charge'),
+ )
+
+ urlpatterns = patterns('',
+ url(r'^$', 'apps.main.views.homepage', name='site-homepage'),
+ (r'^help/', include('apps.help.urls')),
+ (r'^credit/', include(extra_patterns)),
+ )
+
+This approach can be seen in use when you deploy an instance of the Django
+Admin application. The Django Admin is deployed as instances of a
+:class:`~django.contrib.admin.AdminSite`; each
+:class:`~django.contrib.admin.AdminSite` instance has an attribute ``urls``
+that returns the url patterns available to that instance. It is this attribute
+that you ``include()`` into your projects ``urlpatterns`` when you deploy the
+admin instance.
+
+.. _`Django Web site`: http://www.djangoproject.com/
+
+Captured parameters
+-------------------
+
+An included URLconf receives any captured parameters from parent URLconfs, so
+the following example is valid::
+
+ # In settings/urls/main.py
+ urlpatterns = patterns('',
+ (r'^(?P<username>\w+)/blog/', include('foo.urls.blog')),
+ )
+
+ # In foo/urls/blog.py
+ urlpatterns = patterns('foo.views',
+ (r'^$', 'blog.index'),
+ (r'^archive/$', 'blog.archive'),
+ )
+
+In the above example, the captured ``"username"`` variable is passed to the
+included URLconf, as expected.
+
+.. _topics-http-defining-url-namespaces:
+
+Defining URL Namespaces
+-----------------------
+
+When you need to deploy multiple instances of a single application, it can be
+helpful to be able to differentiate between instances. This is especially
+important when using :ref:`named URL patterns <naming-url-patterns>`, since
+multiple instances of a single application will share named URLs. Namespaces
+provide a way to tell these named URLs apart.
+
+A URL namespace comes in two parts, both of which are strings:
+
+ * An **application namespace**. This describes the name of the application
+ that is being deployed. Every instance of a single application will have
+ the same application namespace. For example, Django's admin application
+ has the somewhat predictable application namespace of ``admin``.
+
+ * An **instance namespace**. This identifies a specific instance of an
+ application. Instance namespaces should be unique across your entire
+ project. However, an instance namespace can be the same as the
+ application namespace. This is used to specify a default instance of an
+ application. For example, the default Django Admin instance has an
+ instance namespace of ``admin``.
+
+URL Namespaces can be specified in two ways.
+
+Firstly, you can provide the application and instance namespace as arguments
+to ``include()`` when you construct your URL patterns. For example,::
+
+ (r'^help/', include('apps.help.urls', namespace='foo', app_name='bar')),
+
+This will include the URLs defined in ``apps.help.urls`` into the application
+namespace ``bar``, with the instance namespace ``foo``.
+
+Secondly, you can include an object that contains embedded namespace data. If
+you ``include()`` a ``patterns`` object, that object will be added to the
+global namespace. However, you can also ``include()`` an object that contains
+a 3-tuple containing::
+
+ (<patterns object>, <application namespace>, <instance namespace>)
+
+This will include the nominated URL patterns into the given application and
+instance namespace. For example, the ``urls`` attribute of Django's
+:class:`~django.contrib.admin.AdminSite` object returns a 3-tuple that contains
+all the patterns in an admin site, plus the name of the admin instance, and the
+application namespace ``admin``.
+
+Once you have defined namespaced URLs, you can reverse them. For details on
+reversing namespaced urls, see the documentation on :ref:`reversing namespaced
+URLs <topics-http-reversing-url-namespaces>`.
+
+Passing extra options to view functions
+=======================================
+
+URLconfs have a hook that lets you pass extra arguments to your view functions,
+as a Python dictionary.
+
+Any URLconf tuple can have an optional third element, which should be a
+dictionary of extra keyword arguments to pass to the view function.
+
+For example::
+
+ urlpatterns = patterns('blog.views',
+ (r'^blog/(?P<year>\d{4})/$', 'year_archive', {'foo': 'bar'}),
+ )
+
+In this example, for a request to ``/blog/2005/``, Django will call the
+``blog.views.year_archive()`` view, passing it these keyword arguments::
+
+ year='2005', foo='bar'
+
+This technique is used in :doc:`generic views </ref/generic-views>` and in the
+:doc:`syndication framework </ref/contrib/syndication>` to pass metadata and
+options to views.
+
+.. admonition:: Dealing with conflicts
+
+ It's possible to have a URL pattern which captures named keyword arguments,
+ and also passes arguments with the same names in its dictionary of extra
+ arguments. When this happens, the arguments in the dictionary will be used
+ instead of the arguments captured in the URL.
+
+Passing extra options to ``include()``
+--------------------------------------
+
+Similarly, you can pass extra options to ``include()``. When you pass extra
+options to ``include()``, *each* line in the included URLconf will be passed
+the extra options.
+
+For example, these two URLconf sets are functionally identical:
+
+Set one::
+
+ # main.py
+ urlpatterns = patterns('',
+ (r'^blog/', include('inner'), {'blogid': 3}),
+ )
+
+ # inner.py
+ urlpatterns = patterns('',
+ (r'^archive/$', 'mysite.views.archive'),
+ (r'^about/$', 'mysite.views.about'),
+ )
+
+Set two::
+
+ # main.py
+ urlpatterns = patterns('',
+ (r'^blog/', include('inner')),
+ )
+
+ # inner.py
+ urlpatterns = patterns('',
+ (r'^archive/$', 'mysite.views.archive', {'blogid': 3}),
+ (r'^about/$', 'mysite.views.about', {'blogid': 3}),
+ )
+
+Note that extra options will *always* be passed to *every* line in the included
+URLconf, regardless of whether the line's view actually accepts those options
+as valid. For this reason, this technique is only useful if you're certain that
+every view in the included URLconf accepts the extra options you're passing.
+
+Passing callable objects instead of strings
+===========================================
+
+Some developers find it more natural to pass the actual Python function object
+rather than a string containing the path to its module. This alternative is
+supported -- you can pass any callable object as the view.
+
+For example, given this URLconf in "string" notation::
+
+ urlpatterns = patterns('',
+ (r'^archive/$', 'mysite.views.archive'),
+ (r'^about/$', 'mysite.views.about'),
+ (r'^contact/$', 'mysite.views.contact'),
+ )
+
+You can accomplish the same thing by passing objects rather than strings. Just
+be sure to import the objects::
+
+ from mysite.views import archive, about, contact
+
+ urlpatterns = patterns('',
+ (r'^archive/$', archive),
+ (r'^about/$', about),
+ (r'^contact/$', contact),
+ )
+
+The following example is functionally identical. It's just a bit more compact
+because it imports the module that contains the views, rather than importing
+each view individually::
+
+ from mysite import views
+
+ urlpatterns = patterns('',
+ (r'^archive/$', views.archive),
+ (r'^about/$', views.about),
+ (r'^contact/$', views.contact),
+ )
+
+The style you use is up to you.
+
+Note that if you use this technique -- passing objects rather than strings --
+the view prefix (as explained in "The view prefix" above) will have no effect.
+
+.. _naming-url-patterns:
+
+Naming URL patterns
+===================
+
+.. versionadded:: 1.0
+
+It's fairly common to use the same view function in multiple URL patterns in
+your URLconf. For example, these two URL patterns both point to the ``archive``
+view::
+
+ urlpatterns = patterns('',
+ (r'^archive/(\d{4})/$', archive),
+ (r'^archive-summary/(\d{4})/$', archive, {'summary': True}),
+ )
+
+This is completely valid, but it leads to problems when you try to do reverse
+URL matching (through the ``permalink()`` decorator or the :ttag:`url` template
+tag). Continuing this example, if you wanted to retrieve the URL for the
+``archive`` view, Django's reverse URL matcher would get confused, because *two*
+URLpatterns point at that view.
+
+To solve this problem, Django supports **named URL patterns**. That is, you can
+give a name to a URL pattern in order to distinguish it from other patterns
+using the same view and parameters. Then, you can use this name in reverse URL
+matching.
+
+Here's the above example, rewritten to use named URL patterns::
+
+ urlpatterns = patterns('',
+ url(r'^archive/(\d{4})/$', archive, name="full-archive"),
+ url(r'^archive-summary/(\d{4})/$', archive, {'summary': True}, "arch-summary"),
+ )
+
+With these names in place (``full-archive`` and ``arch-summary``), you can
+target each pattern individually by using its name:
+
+.. code-block:: html+django
+
+ {% url arch-summary 1945 %}
+ {% url full-archive 2007 %}
+
+Even though both URL patterns refer to the ``archive`` view here, using the
+``name`` parameter to ``url()`` allows you to tell them apart in templates.
+
+The string used for the URL name can contain any characters you like. You are
+not restricted to valid Python names.
+
+.. note::
+
+ When you name your URL patterns, make sure you use names that are unlikely
+ to clash with any other application's choice of names. If you call your URL
+ pattern ``comment``, and another application does the same thing, there's
+ no guarantee which URL will be inserted into your template when you use
+ this name.
+
+ Putting a prefix on your URL names, perhaps derived from the application
+ name, will decrease the chances of collision. We recommend something like
+ ``myapp-comment`` instead of ``comment``.
+
+.. _topics-http-reversing-url-namespaces:
+
+URL namespaces
+--------------
+
+.. versionadded:: 1.1
+
+Namespaced URLs are specified using the ``:`` operator. For example, the main
+index page of the admin application is referenced using ``admin:index``. This
+indicates a namespace of ``admin``, and a named URL of ``index``.
+
+Namespaces can also be nested. The named URL ``foo:bar:whiz`` would look for
+a pattern named ``whiz`` in the namespace ``bar`` that is itself defined within
+the top-level namespace ``foo``.
+
+When given a namespaced URL (e.g. ``myapp:index``) to resolve, Django splits
+the fully qualified name into parts, and then tries the following lookup:
+
+ 1. First, Django looks for a matching application namespace (in this
+ example, ``myapp``). This will yield a list of instances of that
+ application.
+
+ 2. If there is a *current* application defined, Django finds and returns
+ the URL resolver for that instance. The *current* application can be
+ specified as an attribute on the template context - applications that
+ expect to have multiple deployments should set the ``current_app``
+ attribute on any ``Context`` or ``RequestContext`` that is used to
+ render a template.
+
+ The current application can also be specified manually as an argument
+ to the :func:`reverse()` function.
+
+ 3. If there is no current application. Django looks for a default
+ application instance. The default application instance is the instance
+ that has an instance namespace matching the application namespace (in
+ this example, an instance of the ``myapp`` called ``myapp``).
+
+ 4. If there is no default application instance, Django will pick the last
+ deployed instance of the application, whatever its instance name may be.
+
+ 5. If the provided namespace doesn't match an application namespace in
+ step 1, Django will attempt a direct lookup of the namespace as an
+ instance namespace.
+
+If there are nested namespaces, these steps are repeated for each part of the
+namespace until only the view name is unresolved. The view name will then be
+resolved into a URL in the namespace that has been found.
+
+To show this resolution strategy in action, consider an example of two instances
+of ``myapp``: one called ``foo``, and one called ``bar``. ``myapp`` has a main
+index page with a URL named `index`. Using this setup, the following lookups are
+possible:
+
+ * If one of the instances is current - say, if we were rendering a utility page
+ in the instance ``bar`` - ``myapp:index`` will resolve to the index page of
+ the instance ``bar``.
+
+ * If there is no current instance - say, if we were rendering a page
+ somewhere else on the site - ``myapp:index`` will resolve to the last
+ registered instance of ``myapp``. Since there is no default instance,
+ the last instance of ``myapp`` that is registered will be used. This could
+ be ``foo`` or ``bar``, depending on the order they are introduced into the
+ urlpatterns of the project.
+
+ * ``foo:index`` will always resolve to the index page of the instance ``foo``.
+
+If there was also a default instance - i.e., an instance named `myapp` - the
+following would happen:
+
+ * If one of the instances is current - say, if we were rendering a utility page
+ in the instance ``bar`` - ``myapp:index`` will resolve to the index page of
+ the instance ``bar``.
+
+ * If there is no current instance - say, if we were rendering a page somewhere
+ else on the site - ``myapp:index`` will resolve to the index page of the
+ default instance.
+
+ * ``foo:index`` will again resolve to the index page of the instance ``foo``.
+
+
+Utility methods
+===============
+
+reverse()
+---------
+
+If you need to use something similar to the :ttag:`url` template tag in
+your code, Django provides the following method (in the
+``django.core.urlresolvers`` module):
+
+.. function:: reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)
+
+``viewname`` is either the function name (either a function reference, or the
+string version of the name, if you used that form in ``urlpatterns``) or the
+`URL pattern name`_. Normally, you won't need to worry about the
+``urlconf`` parameter and will only pass in the positional and keyword
+arguments to use in the URL matching. For example::
+
+ from django.core.urlresolvers import reverse
+
+ def myview(request):
+ return HttpResponseRedirect(reverse('arch-summary', args=[1945]))
+
+.. _URL pattern name: `Naming URL patterns`_
+
+The ``reverse()`` function can reverse a large variety of regular expression
+patterns for URLs, but not every possible one. The main restriction at the
+moment is that the pattern cannot contain alternative choices using the
+vertical bar (``"|"``) character. You can quite happily use such patterns for
+matching against incoming URLs and sending them off to views, but you cannot
+reverse such patterns.
+
+.. versionadded:: 1.1
+
+The ``current_app`` argument allows you to provide a hint to the resolver
+indicating the application to which the currently executing view belongs.
+This ``current_app`` argument is used as a hint to resolve application
+namespaces into URLs on specific application instances, according to the
+:ref:`namespaced URL resolution strategy <topics-http-reversing-url-namespaces>`.
+
+.. admonition:: Make sure your views are all correct.
+
+ As part of working out which URL names map to which patterns, the
+ ``reverse()`` function has to import all of your URLconf files and examine
+ the name of each view. This involves importing each view function. If
+ there are *any* errors whilst importing any of your view functions, it
+ will cause ``reverse()`` to raise an error, even if that view function is
+ not the one you are trying to reverse.
+
+ Make sure that any views you reference in your URLconf files exist and can
+ be imported correctly. Do not include lines that reference views you
+ haven't written yet, because those views will not be importable.
+
+resolve()
+---------
+
+The :func:`django.core.urlresolvers.resolve` function can be used for resolving
+URL paths to the corresponding view functions. It has the following signature:
+
+.. function:: resolve(path, urlconf=None)
+
+``path`` is the URL path you want to resolve. As with
+:func:`~django.core.urlresolvers.reverse`, you don't need to
+worry about the ``urlconf`` parameter. The function returns
+the triple (view function, arguments, keyword arguments).
+
+If the URL does not resolve, the function raises an
+:class:`~django.http.Http404` exception.
+
+For example, it can be used for testing if a view would raise a ``Http404``
+error before redirecting to it::
+
+ from urlparse import urlparse
+ from django.core.urlresolvers import resolve
+ from django.http import HttpResponseRedirect, Http404
+
+ def myview(request):
+ next = request.META.get('HTTP_REFERER', None) or '/'
+ response = HttpResponseRedirect(next)
+
+ # modify the request and response as required, e.g. change locale
+ # and set corresponding locale cookie
+
+ view, args, kwargs = resolve(urlparse(next)[2])
+ kwargs['request'] = request
+ try:
+ view(*args, **kwargs)
+ except Http404:
+ return HttpResponseRedirect('/')
+ return response
+
+permalink()
+-----------
+
+The :func:`django.db.models.permalink` decorator is useful for writing short
+methods that return a full URL path. For example, a model's
+``get_absolute_url()`` method. See :func:`django.db.models.permalink` for more.
+
+get_script_prefix()
+-------------------
+
+.. function:: get_script_prefix()
+
+.. versionadded:: 1.0
+
+Normally, you should always use :func:`~django.core.urlresolvers.reverse` or
+:func:`~django.db.models.permalink` to define URLs within your application.
+However, if your application constructs part of the URL hierarchy itself, you
+may occasionally need to generate URLs. In that case, you need to be able to
+find the base URL of the Django project within its web server
+(normally, :func:`~django.core.urlresolvers.reverse` takes care of this for
+you). In that case, you can call ``get_script_prefix()``, which will return the
+script prefix portion of the URL for your Django project. If your Django
+project is at the root of its webserver, this is always ``"/"``, but it can be
+changed, for instance by using ``django.root`` (see :ref:`How to use
+Django with Apache and mod_python <howto-deployment-modpython>`). \ No newline at end of file
diff --git a/parts/django/docs/topics/http/views.txt b/parts/django/docs/topics/http/views.txt
new file mode 100644
index 0000000..2818f42
--- /dev/null
+++ b/parts/django/docs/topics/http/views.txt
@@ -0,0 +1,202 @@
+=============
+Writing Views
+=============
+
+A view function, or *view* for short, is simply a Python function that takes a
+Web request and returns a Web response. This response can be the HTML contents
+of a Web page, or a redirect, or a 404 error, or an XML document, or an image .
+. . or anything, really. The view itself contains whatever arbitrary logic is
+necessary to return that response. This code can live anywhere you want, as long
+as it's on your Python path. There's no other requirement--no "magic," so to
+speak. For the sake of putting the code *somewhere*, let's create a file called
+``views.py`` in the ``mysite`` directory, which you created in the previous
+chapter.
+
+A simple view
+=============
+
+Here's a view that returns the current date and time, as an HTML document:
+
+.. code-block:: python
+
+ from django.http import HttpResponse
+ import datetime
+
+ def current_datetime(request):
+ now = datetime.datetime.now()
+ html = "<html><body>It is now %s.</body></html>" % now
+ return HttpResponse(html)
+
+Let's step through this code one line at a time:
+
+ * First, we import the class :class:`~django.http.HttpResponse` from the
+ :mod:`django.http` module, along with Python's ``datetime`` library.
+
+ * Next, we define a function called ``current_datetime``. This is the view
+ function. Each view function takes an :class:`~django.http.HttpRequest`
+ object as its first parameter, which is typically named ``request``.
+
+ Note that the name of the view function doesn't matter; it doesn't have to
+ be named in a certain way in order for Django to recognize it. We're
+ calling it ``current_datetime`` here, because that name clearly indicates
+ what it does.
+
+ * The view returns an :class:`~django.http.HttpResponse` object that
+ contains the generated response. Each view function is responsible for
+ returning an :class:`~django.http.HttpResponse` object. (There are
+ exceptions, but we'll get to those later.)
+
+.. admonition:: Django's Time Zone
+
+ Django includes a ``TIME_ZONE`` setting that defaults to
+ ``America/Chicago``. This probably isn't where you live, so you might want
+ to change it in your settings file.
+
+Mapping URLs to Views
+=====================
+
+So, to recap, this view function returns an HTML page that includes the current
+date and time. To display this view at a particular URL, you'll need to create a
+*URLconf*; see :doc:`/topics/http/urls` for instructions.
+
+Returning errors
+================
+
+Returning HTTP error codes in Django is easy. There are subclasses of
+:class:`~django.http.HttpResponse` for a number of common HTTP status codes
+other than 200 (which means *"OK"*). You can find the full list of available
+subclasses in the :ref:`request/response <ref-httpresponse-subclasses>`
+documentation. Just return an instance of one of those subclasses instead of
+a normal :class:`~django.http.HttpResponse` in order to signify an error. For
+example::
+
+ def my_view(request):
+ # ...
+ if foo:
+ return HttpResponseNotFound('<h1>Page not found</h1>')
+ else:
+ return HttpResponse('<h1>Page was found</h1>')
+
+There isn't a specialized subclass for every possible HTTP response code,
+since many of them aren't going to be that common. However, as documented in
+the :class:`~django.http.HttpResponse` documentation, you can also pass the
+HTTP status code into the constructor for :class:`~django.http.HttpResponse`
+to create a return class for any status code you like. For example::
+
+ def my_view(request):
+ # ...
+
+ # Return a "created" (201) response code.
+ return HttpResponse(status=201)
+
+Because 404 errors are by far the most common HTTP error, there's an easier way
+to handle those errors.
+
+The Http404 exception
+---------------------
+
+.. class:: django.http.Http404()
+
+When you return an error such as :class:`~django.http.HttpResponseNotFound`,
+you're responsible for defining the HTML of the resulting error page::
+
+ return HttpResponseNotFound('<h1>Page not found</h1>')
+
+For convenience, and because it's a good idea to have a consistent 404 error page
+across your site, Django provides an ``Http404`` exception. If you raise
+``Http404`` at any point in a view function, Django will catch it and return the
+standard error page for your application, along with an HTTP error code 404.
+
+Example usage::
+
+ from django.http import Http404
+
+ def detail(request, poll_id):
+ try:
+ p = Poll.objects.get(pk=poll_id)
+ except Poll.DoesNotExist:
+ raise Http404
+ return render_to_response('polls/detail.html', {'poll': p})
+
+In order to use the ``Http404`` exception to its fullest, you should create a
+template that is displayed when a 404 error is raised. This template should be
+called ``404.html`` and located in the top level of your template tree.
+
+Customizing error views
+=======================
+
+The 404 (page not found) view
+-----------------------------
+
+When you raise an ``Http404`` exception, Django loads a special view devoted
+to handling 404 errors. By default, it's the view
+``django.views.defaults.page_not_found``, which loads and renders the template
+``404.html``.
+
+This means you need to define a ``404.html`` template in your root template
+directory. This template will be used for all 404 errors.
+
+This ``page_not_found`` view should suffice for 99% of Web applications, but if
+you want to override the 404 view, you can specify ``handler404`` in your
+URLconf, like so::
+
+ handler404 = 'mysite.views.my_custom_404_view'
+
+Behind the scenes, Django determines the 404 view by looking for ``handler404``.
+By default, URLconfs contain the following line::
+
+ from django.conf.urls.defaults import *
+
+That takes care of setting ``handler404`` in the current module. As you can see
+in ``django/conf/urls/defaults.py``, ``handler404`` is set to
+``'django.views.defaults.page_not_found'`` by default.
+
+Three things to note about 404 views:
+
+ * The 404 view is also called if Django doesn't find a match after checking
+ every regular expression in the URLconf.
+
+ * If you don't define your own 404 view -- and simply use the
+ default, which is recommended -- you still have one obligation:
+ you must create a ``404.html`` template in the root of your
+ template directory. The default 404 view will use that template
+ for all 404 errors. The default 404 view will pass one variable
+ to the template: ``request_path``, which is the URL that resulted
+ in the 404.
+
+ * The 404 view is passed a :class:`~django.template.RequestContext` and
+ will have access to variables supplied by your
+ :setting:`TEMPLATE_CONTEXT_PROCESSORS` setting (e.g.,
+ :setting:`MEDIA_URL`).
+
+ * If :setting:`DEBUG` is set to ``True`` (in your settings module), then
+ your 404 view will never be used, and the traceback will be displayed
+ instead.
+
+The 500 (server error) view
+----------------------------
+
+Similarly, Django executes special-case behavior in the case of runtime errors
+in view code. If a view results in an exception, Django will, by default, call
+the view ``django.views.defaults.server_error``, which loads and renders the
+template ``500.html``.
+
+This means you need to define a ``500.html`` template in your root template
+directory. This template will be used for all server errors. The default 500
+view passes no variables to this template and is rendered with an empty
+``Context`` to lessen the chance of additional errors.
+
+This ``server_error`` view should suffice for 99% of Web applications, but if
+you want to override the view, you can specify ``handler500`` in your
+URLconf, like so::
+
+ handler500 = 'mysite.views.my_custom_error_view'
+
+Behind the scenes, Django determines the error view by looking for ``handler500``.
+By default, URLconfs contain the following line::
+
+ from django.conf.urls.defaults import *
+
+That takes care of setting ``handler500`` in the current module. As you can see
+in ``django/conf/urls/defaults.py``, ``handler500`` is set to
+``'django.views.defaults.server_error'`` by default.