Migrating function-based generic views

All the function-based generic views that existed in Django 1.2 have analogs as class-based generic views in Django 1.3. The feature set exposed in those function-based views can be replicated in a class-based way.

How to migrate

Replace generic views with generic classes

Existing usage of function-based generic views should be replaced with their class-based analogs:

Old function-based generic view New class-based generic view
django.views.generic.simple.direct_to_template django.views.generic.base.TemplateView
django.views.generic.simple.redirect_to django.views.generic.base.RedirectView
django.views.generic.list_detail.object_list django.views.generic.list.ListView
django.views.generic.list_detail.object_detail django.views.generic.detail.DetailView
django.views.generic.create_update.create_object django.views.generic.edit.CreateView
django.views.generic.create_update.update_object django.views.generic.edit.UpdateView
django.views.generic.create_update.delete_object django.views.generic.edit.DeleteView
django.views.generic.date_based.archive_index django.views.generic.dates.ArchiveIndexView
django.views.generic.date_based.archive_year django.views.generic.dates.YearArchiveView
django.views.generic.date_based.archive_month django.views.generic.dates.MonthArchiveView
django.views.generic.date_based.archive_week django.views.generic.dates.WeekArchiveView
django.views.generic.date_based.archive_day django.views.generic.dates.DayArchiveView
django.views.generic.date_based.archive_today django.views.generic.dates.TodayArchiveView
django.views.generic.date_based.object_detail django.views.generic.dates.DateDetailView

To do this, replace the reference to the generic view function with a as_view() instantiation of the class-based view. For example, the old-style direct_to_template pattern:

('^about/$', direct_to_template, {'template': 'about.html'})

can be replaced with an instance of TemplateView:

('^about/$', TemplateView.as_view(template_name='about.html'))

template argument to direct_to_template views

The template argument to the direct_to_template view has been renamed template_name. This has been done to maintain consistency with other views.

object_id argument to detail views

The object_id argument to the object_detail view has been renamed pk on the DetailView.

template_object_name

template_object_name has been renamed context_object_name, reflecting the fact that the context data can be used for purposes other than template rendering (e.g., to populate JSON output).

The _list suffix on list views

In a function-based ListView, the template_object_name was appended with the suffix '_list' to yield the final context variable name. In a class-based ListView, the context_object_name is used verbatim. The '_list' suffix is only applied when generating a default context object name.

The context data for object_list views

The context provided by MultipleObjectMixin is quite different from that provided by object_list, with most pagination related variables replaced by a single page_obj object. The following are no longer provided:

  • first_on_page
  • has_next
  • has_previous
  • hits
  • last_on_page
  • next
  • page_range
  • page
  • pages
  • previous
  • results_per_page

extra_context

Function-based generic views provided an extra_context argument as way to insert extra items into the context at time of rendering.

Class-based views don't provide an extra_context argument. Instead, you subclass the view, overriding get_context_data(). For example:

class MyListView(ListView):
    def get_context_data(self, **kwargs):
        context = super(MyListView, self).get_context_data(**kwargs)
        context.update({
            'foo': 42,
            'bar': 37
        })
        return context

post_save_redirect argument to create and update views

The post_save_redirect argument to the create and update views has been renamed success_url on the ModelFormMixin.

mimetype

Some function-based generic views provided a mimetype argument as way to control the mimetype of the response.

Class-based views don't provide a mimetype argument. Instead, you subclass the view, overriding TemplateResponseMixin.render_to_response() and pass in arguments for the TemplateResponse constructor. For example:

class MyListView(ListView):
    def render_to_response(self, context, **kwargs):
        return super(MyListView, self).render_to_response(context,
                        content_type='application/json', **kwargs)

context_processors

Some function-based generic views provided a context_processors argument that could be used to force the use of specialized context processors when rendering template content.

Class-based views don't provide a context_processors argument. Instead, you subclass the view, overriding TemplateResponseMixin.render_to_response(), and passing in a context instance that has been instantiated with the processors you want to use. For example:

class MyListView(ListView):
    def render_to_response(self, context, **kwargs):
        return super(MyListView, self).render_to_response(
                RequestContext(self.request,
                               context,
                               processors=[custom_processor]),
                **kwargs)