362 lines
14 KiB
Plaintext
362 lines
14 KiB
Plaintext
===================
|
|
Using generic views
|
|
===================
|
|
|
|
Writing Web applications can be monotonous, because we repeat certain patterns
|
|
again and again. In Django, the most common of these patterns have been
|
|
abstracted into "generic views" that let you quickly provide common views of
|
|
an object without actually needing to write any views.
|
|
|
|
Django's generic views contain the following:
|
|
|
|
* A set of views for doing list/detail interfaces (for example,
|
|
Django's `documentation index`_ and `detail pages`_).
|
|
|
|
* A set of views for year/month/day archive pages and associated
|
|
detail and "latest" pages (for example, the Django weblog's year_,
|
|
month_, day_, detail_, and latest_ pages).
|
|
|
|
* A set of views for creating, editing, and deleting objects.
|
|
|
|
.. _`documentation index`: http://www.djangoproject.com/documentation/
|
|
.. _`detail pages`: http://www.djangoproject.com/documentation/faq/
|
|
.. _year: http://www.djangoproject.com/weblog/2005/
|
|
.. _month: http://www.djangoproject.com/weblog/2005/jul/
|
|
.. _day: http://www.djangoproject.com/weblog/2005/jul/20/
|
|
.. _detail: http://www.djangoproject.com/weblog/2005/jul/20/autoreload/
|
|
.. _latest: http://www.djangoproject.com/weblog/
|
|
|
|
All of these views are used by creating configuration dictionaries in
|
|
your URLconf files and passing those dictionaries as the third member of the
|
|
URLconf tuple. For example, here's the URLconf for the simple weblog app that
|
|
drives the blog on djangoproject.com::
|
|
|
|
from django.conf.urls.defaults import *
|
|
|
|
info_dict = {
|
|
'app_label': 'blog',
|
|
'module_name': 'entries',
|
|
'date_field': 'pub_date',
|
|
}
|
|
|
|
urlpatterns = patterns('django.views.generic.date_based',
|
|
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/(?P<slug>\w+)/$', 'object_detail', dict(info_dict, slug_field='slug')),
|
|
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/(?P<day>\w{1,2})/$', 'archive_day', info_dict),
|
|
(r'^(?P<year>\d{4})/(?P<month>[a-z]{3})/$', 'archive_month', info_dict),
|
|
(r'^(?P<year>\d{4})/$', 'archive_year', info_dict),
|
|
(r'^/?$', 'archive_index', info_dict),
|
|
)
|
|
|
|
As you can see, this URLconf defines a few options in ``info_dict`` that tell
|
|
the generic view which model to use (``blog.entries`` in this case), as well as
|
|
some extra information.
|
|
|
|
Documentation of each generic view follows, along with a list of all keyword
|
|
arguments that a generic view expects. Remember that as in the example above,
|
|
arguments may either come from the URL pattern (as ``month``, ``day``,
|
|
``year``, etc. do above) or from the additional-information dictionary (as for
|
|
``app_label``, ``module_name``, etc.).
|
|
|
|
Most of the generic views that follow require the ``app_label`` and
|
|
``module_name`` keys. These values are easiest to explain through example::
|
|
|
|
>>> from django.models.blog import entries
|
|
|
|
In the above line, ``blog`` is the ``app_label`` (the name of the file that
|
|
holds all your model definitions) and ``entries`` is the ``module_name``
|
|
(either a pluralized, lowercased version of the model class name, or the value
|
|
of the ``module_name`` option of your model). In the docs below, these keys
|
|
will not be repeated, but each generic view requires them.
|
|
|
|
Using "simple" generic views
|
|
============================
|
|
|
|
The ``django.views.generic.simple`` module contains simple views to handle a
|
|
couple of common cases: rendering a template when no view logic is needed,
|
|
and issuing a redirect. These views are:
|
|
|
|
``direct_to_template``
|
|
Renders a given template using any extra parameters passed in the
|
|
urlpattern; requires the ``template`` argument.
|
|
|
|
For example, given the following URL patterns::
|
|
|
|
urlpatterns = patterns('django.views.generic.simple',
|
|
(r'^foo/$', 'direct_to_template', {'template' : 'foo_index'}),
|
|
(r'^foo/(?P<id>\d+)/$', 'direct_to_template', {'template' : 'foo_detail'}),
|
|
)
|
|
|
|
... a request to ``/foo/`` would cause the ``foo_index`` template to be
|
|
rendered, and a request to ``/foo/15/`` would cause the ``foo_detail``
|
|
template to be rendered with a context variable ``{{ params.id }}`` that is
|
|
set to ``15``.
|
|
|
|
``redirect_to``
|
|
Issue a redirect to a given URL.
|
|
|
|
The given url may contain dict-style string formatting which will be
|
|
interpolated against the params in the URL. For example, to redirect from
|
|
``/foo/<id>/`` to ``/bar/<id>/``, you could use the following urlpattern::
|
|
|
|
urlpatterns = patterns('django.views.generic.simple',
|
|
('^foo/(?p<id>\d+)/$', 'redirect_to', {'url' : '/bar/%(id)s/'}),
|
|
)
|
|
|
|
If the given url is ``None``, a HttpResponseGone (410) will be issued.
|
|
|
|
Using date-based generic views
|
|
==============================
|
|
|
|
Date-based generic views (in the module ``django.views.generic.date_based``)
|
|
feature six functions for dealing with date-based data. Besides ``app_label``
|
|
and ``module_name``, all date-based generic views require that the
|
|
``date_field`` argument be passed to them. This is the name of the field that
|
|
stores the date the objects should key off of.
|
|
|
|
Additionally, all date-based generic views have the following optional
|
|
arguments:
|
|
|
|
======================= ==================================================
|
|
Argument Description
|
|
======================= ==================================================
|
|
``template_name`` Overrides the default template name used for the
|
|
view.
|
|
|
|
``extra_lookup_kwargs`` A dictionary of extra lookup parameters (see
|
|
the `database API docs`_).
|
|
|
|
``extra_context`` A dictionary of extra data to put into the
|
|
template's context.
|
|
======================= ==================================================
|
|
|
|
.. _`database API docs`: http://www.djangoproject.com/documentation/db_api/
|
|
|
|
The date-based generic functions are:
|
|
|
|
``archive_index``
|
|
A top-level index page showing the "latest" objects. Has an optional
|
|
argument, ``num_latest``, which is the number of items to display on the
|
|
page (defaults to 15).
|
|
|
|
Uses the template ``app_label/module_name_archive`` by default.
|
|
|
|
Has the following template context:
|
|
|
|
``date_list``
|
|
List of years with objects
|
|
``latest``
|
|
Latest objects by date
|
|
|
|
``archive_year``
|
|
Yearly archive. Requires that the ``year`` argument be present in the URL
|
|
pattern.
|
|
|
|
Uses the template ``app_label/module_name_archive_year`` by default.
|
|
|
|
Has the following template context:
|
|
|
|
``date_list``
|
|
List of months in the given year with objects
|
|
``year``
|
|
The given year (an integer)
|
|
|
|
``archive_month``
|
|
Monthly archive. Requires that ``year`` and ``month`` arguments be given.
|
|
You can pass the additional option ``month_format`` if you'd like to change
|
|
the way months are specified in the URL.
|
|
|
|
``month_format`` is a format string in the same syntax accepted by Python's
|
|
``time.strftime``. (See the `strftime docs`_.) It's set to ``"%b"`` by
|
|
default, which is a three-letter month abbreviation. To change it to use
|
|
numbers, use ``"%m"``.
|
|
|
|
Uses the template ``app_label/module_name_archive_month`` by default.
|
|
|
|
Has the following template context:
|
|
|
|
``month``
|
|
The given month (a datetime.datetime object)
|
|
``object_list``
|
|
List of objects published in the given month
|
|
|
|
``archive_day``
|
|
Daily archive. Requires that ``year``, ``month``, and ``day`` arguments be
|
|
given.
|
|
|
|
As in ``archive_month``, you can pass an optional ``month_format``. You can
|
|
also pass ``day_format``, which defaults to ``"%d"`` (day of the month as a
|
|
decimal number, 1-31).
|
|
|
|
Uses the template ``app_label/module_name_archive_day`` by default.
|
|
|
|
Has the following template context:
|
|
|
|
``object_list``
|
|
List of objects published this day
|
|
``day``
|
|
The given day (a datetime.datetime object)
|
|
``previous_day``
|
|
The previous day (a datetime.datetime object)
|
|
``next_day``
|
|
The next day (a datetime.datetime object), or None if the given
|
|
day is today
|
|
|
|
``archive_today``
|
|
List of objects for today. Exactly the same as ``archive_day``, except
|
|
the year/month/day arguments are not given, and today's date is used
|
|
instead.
|
|
|
|
``object_detail``
|
|
Individual object page. Requires ``year``/``month``/``day`` arguments like
|
|
``archive_day``. This function can be used with two types of URLs: either
|
|
``/year/month/day/slug/`` or ``/year/month/day/object_id/``.
|
|
|
|
If you're using the slug-style URLs, you'll need to have a ``slug`` item in
|
|
your URLconf, and you'll need to pass a ``slug_field`` key in your info
|
|
dictionary to indicate the name of the slug field.
|
|
|
|
If your using the object_id-style URLs, you'll just need to give the URL
|
|
pattern an ``object_id`` field.
|
|
|
|
You can also pass the ``template_name_field`` argument to indicate that the
|
|
the object stores the name of its template in a field on the object itself.
|
|
|
|
As in ``archive_day``, ``object_detail`` takes optional ``month_format``
|
|
and ``day_format`` parameters.
|
|
|
|
.. _strftime docs: http://www.python.org/doc/current/lib/module-time.html#l2h-1941
|
|
|
|
Using list/detail generic views
|
|
===============================
|
|
|
|
The list-detail generic-view framework (in the
|
|
``django.views.generic.list_detail`` module) is similar to the date-based one,
|
|
except the former simply has two views: a list of objects and an individual
|
|
object page.
|
|
|
|
All these views take the same three optional arguments as the date-based ones
|
|
-- and, clearly, they don't accept the ``date_field`` argument.
|
|
|
|
Individual views are:
|
|
|
|
``object_list``
|
|
List of objects.
|
|
|
|
Takes the following optional arguments:
|
|
|
|
======================= =================================================
|
|
Argument Description
|
|
======================= =================================================
|
|
``paginate_by`` If set to an integer, the view will paginate
|
|
objects with ``paginate_by`` objects per page.
|
|
The view will expect a ``page`` GET param with
|
|
the (zero-indexed) page number.
|
|
|
|
``allow_empty`` If ``False`` and there are no objects to display,
|
|
the view will raise a 404 instead of displaying
|
|
an empty index page. ``False`` is default.
|
|
======================= =================================================
|
|
|
|
Uses the template ``app_label/module_name_list`` by default.
|
|
|
|
Has the following template context:
|
|
|
|
``object_list``
|
|
List of objects
|
|
``is_paginated``
|
|
Are the results paginated? Either True or False
|
|
|
|
If the results are paginated, the context will have some extra variables:
|
|
|
|
``results_per_page``
|
|
Number of objects per page
|
|
``has_next``
|
|
Is there a next page?
|
|
``has_previous``
|
|
Is there a previous page?
|
|
``page``
|
|
The current page number
|
|
``next``
|
|
The next page number
|
|
``previous``
|
|
The previous page
|
|
``pages``
|
|
Number of pages total
|
|
``hits``
|
|
Total number of objects
|
|
|
|
``object_detail``
|
|
Object detail page. This works like and takes the same arguments as
|
|
the date-based ``object_detail`` above, except this one, obviously,
|
|
does not take the year/month/day arguments.
|
|
|
|
Using create/update/delete generic views
|
|
========================================
|
|
|
|
The ``django.views.generic.create_update`` module contains a set of functions
|
|
for creating, editing and deleting objects. These views take the same global
|
|
arguments as the above sets of generic views. They also have a
|
|
``login_required`` argument which, if ``True``, requires the user to be logged
|
|
in to have access to the page. (``login_required`` defaults to ``False``.)
|
|
|
|
The create/update/delete views are:
|
|
|
|
``create_object``
|
|
Create a new object. Has an extra optional argument, ``post_save_redirect``,
|
|
which is a URL to which the view will redirect after saving the object.
|
|
It defaults to ``object.get_absolute_url()``.
|
|
|
|
``post_save_redirect`` may contain dictionary string formatting, which will
|
|
be interpolated against the object's field attributes. For example, you
|
|
could use ``post_save_redirect="/polls/%(slug)s/"``.
|
|
|
|
Uses the template ``app_label/module_name_form`` by default. This is the
|
|
same template as the ``update_object`` view below. Your template can tell
|
|
the different by the presence or absence of ``{{ object }}`` in the
|
|
context.
|
|
|
|
Has the following template context:
|
|
|
|
form
|
|
The form wrapper for the object
|
|
|
|
.. admonition:: Note
|
|
|
|
See the `manipulator and formfield documentation`_ for more information
|
|
about using form wrappers in templates.
|
|
|
|
.. _`manipulator and formfield documentation`: http://www.djangoproject.com/documentation/forms/
|
|
|
|
``update_object``
|
|
Edit an existing object. Has the same extra slug/ID parameters as
|
|
``list_detail.object_detail`` does (see above), and the same
|
|
``post_save_redirect`` as ``create_object`` does.
|
|
|
|
Uses the template ``app_label/module_name_form`` by default.
|
|
|
|
Has the following template context:
|
|
|
|
form
|
|
The form wrapper for the object
|
|
object
|
|
The original object being edited
|
|
|
|
``delete_object``
|
|
Delete an existing object. The given object will only actually be deleted
|
|
if the request method is POST. If this view is fetched with GET, it will
|
|
display a confirmation page that should contain a form that POSTs to the
|
|
same URL.
|
|
|
|
You must provide the ``post_delete_redirect`` argument to this function, so
|
|
that the view knows where to go after the object is deleted.
|
|
|
|
If fetched with GET, it uses the template
|
|
``app_label/module_name_confirm_delete`` by default. It uses no template
|
|
if POSTed -- it simply deletes the object and redirects.
|
|
|
|
Has the following template context:
|
|
|
|
object
|
|
The object about to be deleted
|
|
|