#

## Django documentation

# 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.

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, passing it a `{{ params }}` template variable, which is a dictionary of the parameters captured in the URL. This 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`, an `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.

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.

## 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

  Note

  See the manipulator and formfield documentation for more information about using form wrappers in templates.

`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

## Comments

### Max July 25, 2005 at 2:13 a.m.

There are a lot of references to slugs here, but is there any documentation about that "slug-style-url"? In fact, what is a slug?

### Edgars July 25, 2005 at 3:22 a.m.

Max, for example http://myserver/2005/jul/25/my_test_post... - my_test_post is a slug.

### sway July 25, 2005 at 2:03 p.m.

It seems like generic.viewDispatcher would be more accurate to what's really happening here.

### xtian July 26, 2005 at 7:32 a.m.

Man, you guys needed to document this bit earlier - this is the stuff that really makes this a RAD-style framework. Although I guess it would all be a bit academic without the DB api and the templating language.

Looks brilliant - I'm looking forward to having a bit more of a play with this.

### Randy July 30, 2005 at 1:55 p.m.

I would like to see more examples, of how to use these generic views. Like xtian mentioned above, this is very powerful stuff. I think it merits more explanation and examples.

### Grzegorz July 31, 2005 at 8:37 a.m.

hello i think to there should be more examples about generic view, this looks very interesting. The good example will be e.g. how it was used on the pages that runs on django (i mean lawrence.com...)

### maurycy July 31, 2005 at 5:55 p.m.

Grzegorz, take a look at djangoproject.com sources. They're freely available in the subversion repository.

### ianm August 17, 2005 at 11:08 a.m.

Matt Croydon posted a nice tutorial on his blog:

http://www.postneo.com/2005/08/17/django...

### pedro August 25, 2005 at 12:17 p.m.

Is there a way to use this login_required argument to lock the entire site (views and CRUD)?

### Luke September 16, 2005 at 6:32 p.m.

You don't have to use URLconf to use generic views. You can also write your own (very short) view functions which do something with the request first, then call the generic view function directly. This allows the parameters that generic views accept to be generated dynamically.

### Scott Pierce September 19, 2005 at 11:58 p.m.

for detail/list generic views, you might want to throw in the fact that these views have more optional keyword arguments than shown above:

paginate_by, allow_empty, template_name, extra_lookup_kwargs, extra_context. An example of extra_lookup_kwargs would likely be helpful.

## Post a comment

Note: Please only use the comments for questions/critcisms/suggestions on the docs; if you experience errors please file a ticket, ask in the IRC channel, or post to the django-users list. Comments will be periodically reviewed, integrated into the documentation proper, and removed.

Your name:

Comment: