<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Using mixins with class-based views — Django 1.5.8 documentation</title> <link rel="stylesheet" href="../../_static/default.css" type="text/css" /> <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" /> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: '../../', VERSION: '1.5.8', COLLAPSE_INDEX: false, FILE_SUFFIX: '.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="../../_static/jquery.js"></script> <script type="text/javascript" src="../../_static/underscore.js"></script> <script type="text/javascript" src="../../_static/doctools.js"></script> <link rel="top" title="Django 1.5.8 documentation" href="../../index.html" /> <link rel="up" title="Class-based views" href="index.html" /> <link rel="next" title="Managing files" href="../files.html" /> <link rel="prev" title="Form handling with class-based views" href="generic-editing.html" /> <script type="text/javascript" src="../../templatebuiltins.js"></script> <script type="text/javascript"> (function($) { if (!django_template_builtins) { // templatebuiltins.js missing, do nothing. return; } $(document).ready(function() { // Hyperlink Django template tags and filters var base = "../../ref/templates/builtins.html"; if (base == "#") { // Special case for builtins.html itself base = ""; } // Tags are keywords, class '.k' $("div.highlight\\-html\\+django span.k").each(function(i, elem) { var tagname = $(elem).text(); if ($.inArray(tagname, django_template_builtins.ttags) != -1) { var fragment = tagname.replace(/_/, '-'); $(elem).html("<a href='" + base + "#" + fragment + "'>" + tagname + "</a>"); } }); // Filters are functions, class '.nf' $("div.highlight\\-html\\+django span.nf").each(function(i, elem) { var filtername = $(elem).text(); if ($.inArray(filtername, django_template_builtins.tfilters) != -1) { var fragment = filtername.replace(/_/, '-'); $(elem).html("<a href='" + base + "#" + fragment + "'>" + filtername + "</a>"); } }); }); })(jQuery); </script> </head> <body> <div class="document"> <div id="custom-doc" class="yui-t6"> <div id="hd"> <h1><a href="../../index.html">Django 1.5.8 documentation</a></h1> <div id="global-nav"> <a title="Home page" href="../../index.html">Home</a> | <a title="Table of contents" href="../../contents.html">Table of contents</a> | <a title="Global index" href="../../genindex.html">Index</a> | <a title="Module index" href="../../py-modindex.html">Modules</a> </div> <div class="nav"> « <a href="generic-editing.html" title="Form handling with class-based views">previous</a> | <a href="../index.html" title="Using Django" accesskey="U">up</a> | <a href="../files.html" title="Managing files">next</a> »</div> </div> <div id="bd"> <div id="yui-main"> <div class="yui-b"> <div class="yui-g" id="topics-class-based-views-mixins"> <div class="section" id="s-using-mixins-with-class-based-views"> <span id="using-mixins-with-class-based-views"></span><h1>Using mixins with class-based views<a class="headerlink" href="#using-mixins-with-class-based-views" title="Permalink to this headline">¶</a></h1> <div class="admonition caution"> <p class="first admonition-title">Caution</p> <p class="last">This is an advanced topic. A working knowledge of <a class="reference internal" href="index.html"><em>Django’s class-based views</em></a> is advised before exploring these techniques.</p> </div> <p>Django’s built-in class-based views provide a lot of functionality, but some of it you may want to use separately. For instance, you may want to write a view that renders a template to make the HTTP response, but you can’t use <a class="reference internal" href="../../ref/class-based-views/base.html#django.views.generic.base.TemplateView" title="django.views.generic.base.TemplateView"><tt class="xref py py-class docutils literal"><span class="pre">TemplateView</span></tt></a>; perhaps you need to render a template only on <tt class="docutils literal"><span class="pre">POST</span></tt>, with <tt class="docutils literal"><span class="pre">GET</span></tt> doing something else entirely. While you could use <a class="reference internal" href="../../ref/template-response.html#django.template.response.TemplateResponse" title="django.template.response.TemplateResponse"><tt class="xref py py-class docutils literal"><span class="pre">TemplateResponse</span></tt></a> directly, this will likely result in duplicate code.</p> <p>For this reason, Django also provides a number of mixins that provide more discrete functionality. Template rendering, for instance, is encapsulated in the <a class="reference internal" href="../../ref/class-based-views/mixins-simple.html#django.views.generic.base.TemplateResponseMixin" title="django.views.generic.base.TemplateResponseMixin"><tt class="xref py py-class docutils literal"><span class="pre">TemplateResponseMixin</span></tt></a>. The Django reference documentation contains <a class="reference internal" href="../../ref/class-based-views/mixins.html"><em>full documentation of all the mixins</em></a>.</p> <div class="section" id="s-context-and-template-responses"> <span id="context-and-template-responses"></span><h2>Context and template responses<a class="headerlink" href="#context-and-template-responses" title="Permalink to this headline">¶</a></h2> <p>Two central mixins are provided that help in providing a consistent interface to working with templates in class-based views.</p> <dl class="docutils"> <dt><a class="reference internal" href="../../ref/class-based-views/mixins-simple.html#django.views.generic.base.TemplateResponseMixin" title="django.views.generic.base.TemplateResponseMixin"><tt class="xref py py-class docutils literal"><span class="pre">TemplateResponseMixin</span></tt></a></dt> <dd><p class="first">Every built in view which returns a <a class="reference internal" href="../../ref/template-response.html#django.template.response.TemplateResponse" title="django.template.response.TemplateResponse"><tt class="xref py py-class docutils literal"><span class="pre">TemplateResponse</span></tt></a> will call the <a class="reference internal" href="../../ref/class-based-views/mixins-simple.html#django.views.generic.base.TemplateResponseMixin.render_to_response" title="django.views.generic.base.TemplateResponseMixin.render_to_response"><tt class="xref py py-meth docutils literal"><span class="pre">render_to_response()</span></tt></a> method that <tt class="docutils literal"><span class="pre">TemplateResponseMixin</span></tt> provides. Most of the time this will be called for you (for instance, it is called by the <tt class="docutils literal"><span class="pre">get()</span></tt> method implemented by both <a class="reference internal" href="../../ref/class-based-views/base.html#django.views.generic.base.TemplateView" title="django.views.generic.base.TemplateView"><tt class="xref py py-class docutils literal"><span class="pre">TemplateView</span></tt></a> and <a class="reference internal" href="../../ref/class-based-views/generic-display.html#django.views.generic.detail.DetailView" title="django.views.generic.detail.DetailView"><tt class="xref py py-class docutils literal"><span class="pre">DetailView</span></tt></a>); similarly, it’s unlikely that you’ll need to override it, although if you want your response to return something not rendered via a Django template then you’ll want to do it. For an example of this, see the <a class="reference internal" href="#jsonresponsemixin-example"><em>JSONResponseMixin example</em></a>.</p> <p class="last"><tt class="docutils literal"><span class="pre">render_to_response</span></tt> itself calls <a class="reference internal" href="../../ref/class-based-views/mixins-simple.html#django.views.generic.base.TemplateResponseMixin.get_template_names" title="django.views.generic.base.TemplateResponseMixin.get_template_names"><tt class="xref py py-meth docutils literal"><span class="pre">get_template_names()</span></tt></a>, which by default will just look up <a class="reference internal" href="../../ref/class-based-views/mixins-simple.html#django.views.generic.base.TemplateResponseMixin.template_name" title="django.views.generic.base.TemplateResponseMixin.template_name"><tt class="xref py py-attr docutils literal"><span class="pre">template_name</span></tt></a> on the class-based view; two other mixins (<a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectTemplateResponseMixin" title="django.views.generic.detail.SingleObjectTemplateResponseMixin"><tt class="xref py py-class docutils literal"><span class="pre">SingleObjectTemplateResponseMixin</span></tt></a> and <a class="reference internal" href="../../ref/class-based-views/mixins-multiple-object.html#django.views.generic.list.MultipleObjectTemplateResponseMixin" title="django.views.generic.list.MultipleObjectTemplateResponseMixin"><tt class="xref py py-class docutils literal"><span class="pre">MultipleObjectTemplateResponseMixin</span></tt></a>) override this to provide more flexible defaults when dealing with actual objects.</p> </dd> </dl> <div class="versionadded"> <span class="title">New in Django 1.5.</span> </div> <dl class="docutils"> <dt><a class="reference internal" href="../../ref/class-based-views/mixins-simple.html#django.views.generic.base.ContextMixin" title="django.views.generic.base.ContextMixin"><tt class="xref py py-class docutils literal"><span class="pre">ContextMixin</span></tt></a></dt> <dd>Every built in view which needs context data, such as for rendering a template (including <tt class="docutils literal"><span class="pre">TemplateResponseMixin</span></tt> above), should call <a class="reference internal" href="../../ref/class-based-views/mixins-simple.html#django.views.generic.base.ContextMixin.get_context_data" title="django.views.generic.base.ContextMixin.get_context_data"><tt class="xref py py-meth docutils literal"><span class="pre">get_context_data()</span></tt></a> passing any data they want to ensure is in there as keyword arguments. <tt class="docutils literal"><span class="pre">get_context_data</span></tt> returns a dictionary; in <tt class="docutils literal"><span class="pre">ContextMixin</span></tt> it simply returns its keyword arguments, but it is common to override this to add more members to the dictionary.</dd> </dl> </div> <div class="section" id="s-building-up-django-s-generic-class-based-views"> <span id="building-up-django-s-generic-class-based-views"></span><h2>Building up Django’s generic class-based views<a class="headerlink" href="#building-up-django-s-generic-class-based-views" title="Permalink to this headline">¶</a></h2> <p>Let’s look at how two of Django’s generic class-based views are built out of mixins providing discrete functionality. We’ll consider <a class="reference internal" href="../../ref/class-based-views/generic-display.html#django.views.generic.detail.DetailView" title="django.views.generic.detail.DetailView"><tt class="xref py py-class docutils literal"><span class="pre">DetailView</span></tt></a>, which renders a “detail” view of an object, and <a class="reference internal" href="../../ref/class-based-views/generic-display.html#django.views.generic.list.ListView" title="django.views.generic.list.ListView"><tt class="xref py py-class docutils literal"><span class="pre">ListView</span></tt></a>, which will render a list of objects, typically from a queryset, and optionally paginate them. This will introduce us to four mixins which between them provide useful functionality when working with either a single Django object, or multiple objects.</p> <p>There are also mixins involved in the generic edit views (<a class="reference internal" href="../../ref/class-based-views/generic-editing.html#django.views.generic.edit.FormView" title="django.views.generic.edit.FormView"><tt class="xref py py-class docutils literal"><span class="pre">FormView</span></tt></a>, and the model-specific views <a class="reference internal" href="../../ref/class-based-views/generic-editing.html#django.views.generic.edit.CreateView" title="django.views.generic.edit.CreateView"><tt class="xref py py-class docutils literal"><span class="pre">CreateView</span></tt></a>, <a class="reference internal" href="../../ref/class-based-views/generic-editing.html#django.views.generic.edit.UpdateView" title="django.views.generic.edit.UpdateView"><tt class="xref py py-class docutils literal"><span class="pre">UpdateView</span></tt></a> and <a class="reference internal" href="../../ref/class-based-views/generic-editing.html#django.views.generic.edit.DeleteView" title="django.views.generic.edit.DeleteView"><tt class="xref py py-class docutils literal"><span class="pre">DeleteView</span></tt></a>), and in the date-based generic views. These are covered in the <a class="reference internal" href="../../ref/class-based-views/mixins.html"><em>mixin reference documentation</em></a>.</p> <div class="section" id="s-detailview-working-with-a-single-django-object"> <span id="detailview-working-with-a-single-django-object"></span><h3>DetailView: working with a single Django object<a class="headerlink" href="#detailview-working-with-a-single-django-object" title="Permalink to this headline">¶</a></h3> <p>To show the detail of an object, we basically need to do two things: we need to look up the object and then we need to make a <a class="reference internal" href="../../ref/template-response.html#django.template.response.TemplateResponse" title="django.template.response.TemplateResponse"><tt class="xref py py-class docutils literal"><span class="pre">TemplateResponse</span></tt></a> with a suitable template, and that object as context.</p> <p>To get the object, <a class="reference internal" href="../../ref/class-based-views/generic-display.html#django.views.generic.detail.DetailView" title="django.views.generic.detail.DetailView"><tt class="xref py py-class docutils literal"><span class="pre">DetailView</span></tt></a> relies on <a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectMixin" title="django.views.generic.detail.SingleObjectMixin"><tt class="xref py py-class docutils literal"><span class="pre">SingleObjectMixin</span></tt></a>, which provides a <a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectMixin.get_object" title="django.views.generic.detail.SingleObjectMixin.get_object"><tt class="xref py py-meth docutils literal"><span class="pre">get_object()</span></tt></a> method that figures out the object based on the URL of the request (it looks for <tt class="docutils literal"><span class="pre">pk</span></tt> and <tt class="docutils literal"><span class="pre">slug</span></tt> keyword arguments as declared in the URLConf, and looks the object up either from the <a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectMixin.model" title="django.views.generic.detail.SingleObjectMixin.model"><tt class="xref py py-attr docutils literal"><span class="pre">model</span></tt></a> attribute on the view, or the <a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectMixin.queryset" title="django.views.generic.detail.SingleObjectMixin.queryset"><tt class="xref py py-attr docutils literal"><span class="pre">queryset</span></tt></a> attribute if that’s provided). <tt class="docutils literal"><span class="pre">SingleObjectMixin</span></tt> also overrides <a class="reference internal" href="../../ref/class-based-views/mixins-simple.html#django.views.generic.base.ContextMixin.get_context_data" title="django.views.generic.base.ContextMixin.get_context_data"><tt class="xref py py-meth docutils literal"><span class="pre">get_context_data()</span></tt></a>, which is used across all Django’s built in class-based views to supply context data for template renders.</p> <p>To then make a <a class="reference internal" href="../../ref/template-response.html#django.template.response.TemplateResponse" title="django.template.response.TemplateResponse"><tt class="xref py py-class docutils literal"><span class="pre">TemplateResponse</span></tt></a>, <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#DetailView" title="DetailView"><tt class="xref py py-class docutils literal"><span class="pre">DetailView</span></tt></a> uses <a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectTemplateResponseMixin" title="django.views.generic.detail.SingleObjectTemplateResponseMixin"><tt class="xref py py-class docutils literal"><span class="pre">SingleObjectTemplateResponseMixin</span></tt></a>, which extends <a class="reference internal" href="../../ref/class-based-views/mixins-simple.html#django.views.generic.base.TemplateResponseMixin" title="django.views.generic.base.TemplateResponseMixin"><tt class="xref py py-class docutils literal"><span class="pre">TemplateResponseMixin</span></tt></a>, overriding <a class="reference internal" href="../../ref/class-based-views/mixins-simple.html#django.views.generic.base.TemplateResponseMixin.get_template_names" title="django.views.generic.base.TemplateResponseMixin.get_template_names"><tt class="xref py py-meth docutils literal"><span class="pre">get_template_names()</span></tt></a> as discussed above. It actually provides a fairly sophisticated set of options, but the main one that most people are going to use is <tt class="docutils literal"><span class="pre"><app_label>/<object_name>_detail.html</span></tt>. The <tt class="docutils literal"><span class="pre">_detail</span></tt> part can be changed by setting <a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectTemplateResponseMixin.template_name_suffix" title="django.views.generic.detail.SingleObjectTemplateResponseMixin.template_name_suffix"><tt class="xref py py-attr docutils literal"><span class="pre">template_name_suffix</span></tt></a> on a subclass to something else. (For instance, the <a class="reference internal" href="generic-editing.html"><em>generic edit views</em></a> use <tt class="docutils literal"><span class="pre">_form</span></tt> for create and update views, and <tt class="docutils literal"><span class="pre">_confirm_delete</span></tt> for delete views.)</p> </div> <div class="section" id="s-listview-working-with-many-django-objects"> <span id="listview-working-with-many-django-objects"></span><h3>ListView: working with many Django objects<a class="headerlink" href="#listview-working-with-many-django-objects" title="Permalink to this headline">¶</a></h3> <p>Lists of objects follow roughly the same pattern: we need a (possibly paginated) list of objects, typically a <a class="reference internal" href="../../ref/models/querysets.html#django.db.models.query.QuerySet" title="django.db.models.query.QuerySet"><tt class="xref py py-class docutils literal"><span class="pre">QuerySet</span></tt></a>, and then we need to make a <a class="reference internal" href="../../ref/template-response.html#django.template.response.TemplateResponse" title="django.template.response.TemplateResponse"><tt class="xref py py-class docutils literal"><span class="pre">TemplateResponse</span></tt></a> with a suitable template using that list of objects.</p> <p>To get the objects, <a class="reference internal" href="../../ref/class-based-views/generic-display.html#django.views.generic.list.ListView" title="django.views.generic.list.ListView"><tt class="xref py py-class docutils literal"><span class="pre">ListView</span></tt></a> uses <a class="reference internal" href="../../ref/class-based-views/mixins-multiple-object.html#django.views.generic.list.MultipleObjectMixin" title="django.views.generic.list.MultipleObjectMixin"><tt class="xref py py-class docutils literal"><span class="pre">MultipleObjectMixin</span></tt></a>, which provides both <a class="reference internal" href="../../ref/class-based-views/mixins-multiple-object.html#django.views.generic.list.MultipleObjectMixin.get_queryset" title="django.views.generic.list.MultipleObjectMixin.get_queryset"><tt class="xref py py-meth docutils literal"><span class="pre">get_queryset()</span></tt></a> and <a class="reference internal" href="../../ref/class-based-views/mixins-multiple-object.html#django.views.generic.list.MultipleObjectMixin.paginate_queryset" title="django.views.generic.list.MultipleObjectMixin.paginate_queryset"><tt class="xref py py-meth docutils literal"><span class="pre">paginate_queryset()</span></tt></a>. Unlike with <a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectMixin" title="django.views.generic.detail.SingleObjectMixin"><tt class="xref py py-class docutils literal"><span class="pre">SingleObjectMixin</span></tt></a>, there’s no need to key off parts of the URL to figure out the queryset to work with, so the default just uses the <a class="reference internal" href="../../ref/class-based-views/mixins-multiple-object.html#django.views.generic.list.MultipleObjectMixin.queryset" title="django.views.generic.list.MultipleObjectMixin.queryset"><tt class="xref py py-attr docutils literal"><span class="pre">queryset</span></tt></a> or <a class="reference internal" href="../../ref/class-based-views/mixins-multiple-object.html#django.views.generic.list.MultipleObjectMixin.model" title="django.views.generic.list.MultipleObjectMixin.model"><tt class="xref py py-attr docutils literal"><span class="pre">model</span></tt></a> attribute on the view class. A common reason to override <a class="reference internal" href="../../ref/class-based-views/mixins-multiple-object.html#django.views.generic.list.MultipleObjectMixin.get_queryset" title="django.views.generic.list.MultipleObjectMixin.get_queryset"><tt class="xref py py-meth docutils literal"><span class="pre">get_queryset()</span></tt></a> here would be to dynamically vary the objects, such as depending on the current user or to exclude posts in the future for a blog.</p> <p><a class="reference internal" href="../../ref/class-based-views/mixins-multiple-object.html#django.views.generic.list.MultipleObjectMixin" title="django.views.generic.list.MultipleObjectMixin"><tt class="xref py py-class docutils literal"><span class="pre">MultipleObjectMixin</span></tt></a> also overrides <a class="reference internal" href="../../ref/class-based-views/mixins-simple.html#django.views.generic.base.ContextMixin.get_context_data" title="django.views.generic.base.ContextMixin.get_context_data"><tt class="xref py py-meth docutils literal"><span class="pre">get_context_data()</span></tt></a> to include appropriate context variables for pagination (providing dummies if pagination is disabled). It relies on <tt class="docutils literal"><span class="pre">object_list</span></tt> being passed in as a keyword argument, which <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#ListView" title="ListView"><tt class="xref py py-class docutils literal"><span class="pre">ListView</span></tt></a> arranges for it.</p> <p>To make a <a class="reference internal" href="../../ref/template-response.html#django.template.response.TemplateResponse" title="django.template.response.TemplateResponse"><tt class="xref py py-class docutils literal"><span class="pre">TemplateResponse</span></tt></a>, <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#ListView" title="ListView"><tt class="xref py py-class docutils literal"><span class="pre">ListView</span></tt></a> then uses <a class="reference internal" href="../../ref/class-based-views/mixins-multiple-object.html#django.views.generic.list.MultipleObjectTemplateResponseMixin" title="django.views.generic.list.MultipleObjectTemplateResponseMixin"><tt class="xref py py-class docutils literal"><span class="pre">MultipleObjectTemplateResponseMixin</span></tt></a>; as with <a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectTemplateResponseMixin" title="django.views.generic.detail.SingleObjectTemplateResponseMixin"><tt class="xref py py-class docutils literal"><span class="pre">SingleObjectTemplateResponseMixin</span></tt></a> above, this overrides <tt class="docutils literal"><span class="pre">get_template_names()</span></tt> to provide <a class="reference internal" href="../../ref/class-based-views/mixins-multiple-object.html#django.views.generic.list.MultipleObjectTemplateResponseMixin" title="django.views.generic.list.MultipleObjectTemplateResponseMixin"><tt class="xref py py-meth docutils literal"><span class="pre">a</span> <span class="pre">range</span> <span class="pre">of</span> <span class="pre">options</span></tt></a>, with the most commonly-used being <tt class="docutils literal"><span class="pre"><app_label>/<object_name>_list.html</span></tt>, with the <tt class="docutils literal"><span class="pre">_list</span></tt> part again being taken from the <a class="reference internal" href="../../ref/class-based-views/mixins-multiple-object.html#django.views.generic.list.MultipleObjectTemplateResponseMixin.template_name_suffix" title="django.views.generic.list.MultipleObjectTemplateResponseMixin.template_name_suffix"><tt class="xref py py-attr docutils literal"><span class="pre">template_name_suffix</span></tt></a> attribute. (The date based generic views use suffixes such as <tt class="docutils literal"><span class="pre">_archive</span></tt>, <tt class="docutils literal"><span class="pre">_archive_year</span></tt> and so on to use different templates for the various specialised date-based list views.)</p> </div> </div> <div class="section" id="s-using-django-s-class-based-view-mixins"> <span id="using-django-s-class-based-view-mixins"></span><h2>Using Django’s class-based view mixins<a class="headerlink" href="#using-django-s-class-based-view-mixins" title="Permalink to this headline">¶</a></h2> <p>Now we’ve seen how Django’s generic class-based views use the provided mixins, let’s look at other ways we can combine them. Of course we’re still going to be combining them with either built-in class-based views, or other generic class-based views, but there are a range of rarer problems you can solve than are provided for by Django out of the box.</p> <div class="admonition warning"> <p class="first admonition-title">Warning</p> <p>Not all mixins can be used together, and not all generic class based views can be used with all other mixins. Here we present a few examples that do work; if you want to bring together other functionality then you’ll have to consider interactions between attributes and methods that overlap between the different classes you’re using, and how <a class="reference external" href="http://www.python.org/download/releases/2.3/mro/">method resolution order</a> will affect which versions of the methods will be called in what order.</p> <p>The reference documentation for Django’s <a class="reference internal" href="../../ref/class-based-views/index.html"><em>class-based views</em></a> and <a class="reference internal" href="../../ref/class-based-views/mixins.html"><em>class-based view mixins</em></a> will help you in understanding which attributes and methods are likely to cause conflict between different classes and mixins.</p> <p class="last">If in doubt, it’s often better to back off and base your work on <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#View" title="View"><tt class="xref py py-class docutils literal"><span class="pre">View</span></tt></a> or <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#TemplateView" title="TemplateView"><tt class="xref py py-class docutils literal"><span class="pre">TemplateView</span></tt></a>, perhaps with <a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectMixin" title="django.views.generic.detail.SingleObjectMixin"><tt class="xref py py-class docutils literal"><span class="pre">SingleObjectMixin</span></tt></a> and <a class="reference internal" href="../../ref/class-based-views/mixins-multiple-object.html#django.views.generic.list.MultipleObjectMixin" title="django.views.generic.list.MultipleObjectMixin"><tt class="xref py py-class docutils literal"><span class="pre">MultipleObjectMixin</span></tt></a>. Although you will probably end up writing more code, it is more likely to be clearly understandable to someone else coming to it later, and with fewer interactions to worry about you will save yourself some thinking. (Of course, you can always dip into Django’s implementation of the generic class based views for inspiration on how to tackle problems.)</p> </div> <div class="section" id="s-using-singleobjectmixin-with-view"> <span id="using-singleobjectmixin-with-view"></span><h3>Using SingleObjectMixin with View<a class="headerlink" href="#using-singleobjectmixin-with-view" title="Permalink to this headline">¶</a></h3> <p>If we want to write a simple class-based view that responds only to <tt class="docutils literal"><span class="pre">POST</span></tt>, we’ll subclass <a class="reference internal" href="../../ref/class-based-views/base.html#django.views.generic.base.View" title="django.views.generic.base.View"><tt class="xref py py-class docutils literal"><span class="pre">View</span></tt></a> and write a <tt class="docutils literal"><span class="pre">post()</span></tt> method in the subclass. However if we want our processing to work on a particular object, identified from the URL, we’ll want the functionality provided by <a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectMixin" title="django.views.generic.detail.SingleObjectMixin"><tt class="xref py py-class docutils literal"><span class="pre">SingleObjectMixin</span></tt></a>.</p> <p>We’ll demonstrate this with the publisher modelling we used in the <a class="reference internal" href="generic-display.html"><em>generic class-based views introduction</em></a>.</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># views.py</span> <span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">HttpResponseForbidden</span><span class="p">,</span> <span class="n">HttpResponseRedirect</span> <span class="kn">from</span> <span class="nn">django.core.urlresolvers</span> <span class="kn">import</span> <span class="n">reverse</span> <span class="kn">from</span> <span class="nn">django.views.generic</span> <span class="kn">import</span> <span class="n">View</span> <span class="kn">from</span> <span class="nn">django.views.generic.detail</span> <span class="kn">import</span> <span class="n">SingleObjectMixin</span> <span class="kn">from</span> <span class="nn">books.models</span> <span class="kn">import</span> <span class="n">Author</span> <span class="k">class</span> <span class="nc">RecordInterest</span><span class="p">(</span><span class="n">View</span><span class="p">,</span> <span class="n">SingleObjectMixin</span><span class="p">):</span> <span class="sd">"""Records the current user's interest in an author."""</span> <span class="n">model</span> <span class="o">=</span> <span class="n">Author</span> <span class="k">def</span> <span class="nf">post</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">is_authenticated</span><span class="p">():</span> <span class="k">return</span> <span class="n">HttpResponseForbidden</span><span class="p">()</span> <span class="c"># Look up the author we're interested in.</span> <span class="bp">self</span><span class="o">.</span><span class="n">object</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_object</span><span class="p">()</span> <span class="c"># Actually record interest somehow here!</span> <span class="k">return</span> <span class="n">HttpResponseRedirect</span><span class="p">(</span><span class="n">reverse</span><span class="p">(</span><span class="s">'author-detail'</span><span class="p">,</span> <span class="n">kwargs</span><span class="o">=</span><span class="p">{</span><span class="s">'pk'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">object</span><span class="o">.</span><span class="n">pk</span><span class="p">}))</span> </pre></div> </div> <p>In practice you’d probably want to record the interest in a key-value store rather than in a relational database, so we’ve left that bit out. The only bit of the view that needs to worry about using <a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectMixin" title="django.views.generic.detail.SingleObjectMixin"><tt class="xref py py-class docutils literal"><span class="pre">SingleObjectMixin</span></tt></a> is where we want to look up the author we’re interested in, which it just does with a simple call to <tt class="docutils literal"><span class="pre">self.get_object()</span></tt>. Everything else is taken care of for us by the mixin.</p> <p>We can hook this into our URLs easily enough:</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># urls.py</span> <span class="kn">from</span> <span class="nn">books.views</span> <span class="kn">import</span> <span class="n">RecordInterest</span> <span class="n">urlpatterns</span> <span class="o">=</span> <span class="n">patterns</span><span class="p">(</span><span class="s">''</span><span class="p">,</span> <span class="c">#...</span> <span class="n">url</span><span class="p">(</span><span class="s">r'^author/(?P<pk>\d+)/interest/$'</span><span class="p">,</span> <span class="n">RecordInterest</span><span class="o">.</span><span class="n">as_view</span><span class="p">(),</span> <span class="n">name</span><span class="o">=</span><span class="s">'author-interest'</span><span class="p">),</span> <span class="p">)</span> </pre></div> </div> <p>Note the <tt class="docutils literal"><span class="pre">pk</span></tt> named group, which <a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectMixin.get_object" title="django.views.generic.detail.SingleObjectMixin.get_object"><tt class="xref py py-meth docutils literal"><span class="pre">get_object()</span></tt></a> uses to look up the <tt class="docutils literal"><span class="pre">Author</span></tt> instance. You could also use a slug, or any of the other features of <a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectMixin" title="django.views.generic.detail.SingleObjectMixin"><tt class="xref py py-class docutils literal"><span class="pre">SingleObjectMixin</span></tt></a>.</p> </div> <div class="section" id="s-using-singleobjectmixin-with-listview"> <span id="using-singleobjectmixin-with-listview"></span><h3>Using SingleObjectMixin with ListView<a class="headerlink" href="#using-singleobjectmixin-with-listview" title="Permalink to this headline">¶</a></h3> <p><a class="reference internal" href="../../ref/class-based-views/generic-display.html#django.views.generic.list.ListView" title="django.views.generic.list.ListView"><tt class="xref py py-class docutils literal"><span class="pre">ListView</span></tt></a> provides built-in pagination, but you might want to paginate a list of objects that are all linked (by a foreign key) to another object. In our publishing example, you might want to paginate through all the books by a particular publisher.</p> <p>One way to do this is to combine <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#ListView" title="ListView"><tt class="xref py py-class docutils literal"><span class="pre">ListView</span></tt></a> with <a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectMixin" title="django.views.generic.detail.SingleObjectMixin"><tt class="xref py py-class docutils literal"><span class="pre">SingleObjectMixin</span></tt></a>, so that the queryset for the paginated list of books can hang off the publisher found as the single object. In order to do this, we need to have two different querysets:</p> <dl class="docutils"> <dt><tt class="docutils literal"><span class="pre">Book</span></tt> queryset for use by <a class="reference internal" href="../../ref/class-based-views/generic-display.html#django.views.generic.list.ListView" title="django.views.generic.list.ListView"><tt class="xref py py-class docutils literal"><span class="pre">ListView</span></tt></a></dt> <dd>Since we have access to the <tt class="docutils literal"><span class="pre">Publisher</span></tt> whose books we want to list, we simply override <tt class="docutils literal"><span class="pre">get_queryset()</span></tt> and use the <tt class="docutils literal"><span class="pre">Publisher</span></tt>‘s <a class="reference internal" href="../db/queries.html#backwards-related-objects"><em>reverse foreign key manager</em></a>.</dd> <dt><tt class="docutils literal"><span class="pre">Publisher</span></tt> queryset for use in <a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectMixin.get_object" title="django.views.generic.detail.SingleObjectMixin.get_object"><tt class="xref py py-meth docutils literal"><span class="pre">get_object()</span></tt></a></dt> <dd>We’ll rely on the default implementation of <tt class="docutils literal"><span class="pre">get_object()</span></tt> to fetch the correct <tt class="docutils literal"><span class="pre">Publisher</span></tt> object. However, we need to explicitly pass a <tt class="docutils literal"><span class="pre">queryset</span></tt> argument because otherwise the default implementation of <tt class="docutils literal"><span class="pre">get_object()</span></tt> would call <tt class="docutils literal"><span class="pre">get_queryset()</span></tt> which we have overridden to return <tt class="docutils literal"><span class="pre">Book</span></tt> objects instead of <tt class="docutils literal"><span class="pre">Publisher</span></tt> ones.</dd> </dl> <div class="admonition note"> <p class="first admonition-title">Note</p> <p class="last">We have to think carefully about <tt class="docutils literal"><span class="pre">get_context_data()</span></tt>. Since both <a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectMixin" title="django.views.generic.detail.SingleObjectMixin"><tt class="xref py py-class docutils literal"><span class="pre">SingleObjectMixin</span></tt></a> and <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#ListView" title="ListView"><tt class="xref py py-class docutils literal"><span class="pre">ListView</span></tt></a> will put things in the context data under the value of <tt class="docutils literal"><span class="pre">context_object_name</span></tt> if it’s set, we’ll instead explictly ensure the <tt class="docutils literal"><span class="pre">Publisher</span></tt> is in the context data. <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#ListView" title="ListView"><tt class="xref py py-class docutils literal"><span class="pre">ListView</span></tt></a> will add in the suitable <tt class="docutils literal"><span class="pre">page_obj</span></tt> and <tt class="docutils literal"><span class="pre">paginator</span></tt> for us providing we remember to call <tt class="docutils literal"><span class="pre">super()</span></tt>.</p> </div> <p>Now we can write a new <tt class="docutils literal"><span class="pre">PublisherDetail</span></tt>:</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.views.generic</span> <span class="kn">import</span> <span class="n">ListView</span> <span class="kn">from</span> <span class="nn">django.views.generic.detail</span> <span class="kn">import</span> <span class="n">SingleObjectMixin</span> <span class="kn">from</span> <span class="nn">books.models</span> <span class="kn">import</span> <span class="n">Publisher</span> <span class="k">class</span> <span class="nc">PublisherDetail</span><span class="p">(</span><span class="n">SingleObjectMixin</span><span class="p">,</span> <span class="n">ListView</span><span class="p">):</span> <span class="n">paginate_by</span> <span class="o">=</span> <span class="mi">2</span> <span class="n">template_name</span> <span class="o">=</span> <span class="s">"books/publisher_detail.html"</span> <span class="k">def</span> <span class="nf">get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">object</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_object</span><span class="p">(</span><span class="n">queryset</span><span class="o">=</span><span class="n">Publisher</span><span class="o">.</span><span class="n">objects</span><span class="o">.</span><span class="n">all</span><span class="p">())</span> <span class="k">return</span> <span class="nb">super</span><span class="p">(</span><span class="n">PublisherDetail</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="k">def</span> <span class="nf">get_context_data</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="n">context</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">PublisherDetail</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">get_context_data</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="n">context</span><span class="p">[</span><span class="s">'publisher'</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">object</span> <span class="k">return</span> <span class="n">context</span> <span class="k">def</span> <span class="nf">get_queryset</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">object</span><span class="o">.</span><span class="n">book_set</span><span class="o">.</span><span class="n">all</span><span class="p">()</span> </pre></div> </div> <p>Notice how we set <tt class="docutils literal"><span class="pre">self.object</span></tt> within <tt class="docutils literal"><span class="pre">get()</span></tt> so we can use it again later in <tt class="docutils literal"><span class="pre">get_context_data()</span></tt> and <tt class="docutils literal"><span class="pre">get_queryset()</span></tt>. If you don’t set <tt class="docutils literal"><span class="pre">template_name</span></tt>, the template will default to the normal <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#ListView" title="ListView"><tt class="xref py py-class docutils literal"><span class="pre">ListView</span></tt></a> choice, which in this case would be <tt class="docutils literal"><span class="pre">"books/book_list.html"</span></tt> because it’s a list of books; <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#ListView" title="ListView"><tt class="xref py py-class docutils literal"><span class="pre">ListView</span></tt></a> knows nothing about <a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectMixin" title="django.views.generic.detail.SingleObjectMixin"><tt class="xref py py-class docutils literal"><span class="pre">SingleObjectMixin</span></tt></a>, so it doesn’t have any clue this view is anything to do with a <tt class="docutils literal"><span class="pre">Publisher</span></tt>.</p> <p>The <tt class="docutils literal"><span class="pre">paginate_by</span></tt> is deliberately small in the example so you don’t have to create lots of books to see the pagination working! Here’s the template you’d want to use:</p> <div class="highlight-html+django"><div class="highlight"><pre><span class="cp">{%</span> <span class="k">extends</span> <span class="s2">"base.html"</span> <span class="cp">%}</span> <span class="cp">{%</span> <span class="k">block</span> <span class="nv">content</span> <span class="cp">%}</span> <span class="nt"><h2></span>Publisher <span class="cp">{{</span> <span class="nv">publisher.name</span> <span class="cp">}}</span><span class="nt"></h2></span> <span class="nt"><ol></span> <span class="cp">{%</span> <span class="k">for</span> <span class="nv">book</span> <span class="k">in</span> <span class="nv">page_obj</span> <span class="cp">%}</span> <span class="nt"><li></span><span class="cp">{{</span> <span class="nv">book.title</span> <span class="cp">}}</span><span class="nt"></li></span> <span class="cp">{%</span> <span class="k">endfor</span> <span class="cp">%}</span> <span class="nt"></ol></span> <span class="nt"><div</span> <span class="na">class=</span><span class="s">"pagination"</span><span class="nt">></span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"step-links"</span><span class="nt">></span> <span class="cp">{%</span> <span class="k">if</span> <span class="nv">page_obj.has_previous</span> <span class="cp">%}</span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"?page=</span><span class="cp">{{</span> <span class="nv">page_obj.previous_page_number</span> <span class="cp">}}</span><span class="s">"</span><span class="nt">></span>previous<span class="nt"></a></span> <span class="cp">{%</span> <span class="k">endif</span> <span class="cp">%}</span> <span class="nt"><span</span> <span class="na">class=</span><span class="s">"current"</span><span class="nt">></span> Page <span class="cp">{{</span> <span class="nv">page_obj.number</span> <span class="cp">}}</span> of <span class="cp">{{</span> <span class="nv">paginator.num_pages</span> <span class="cp">}}</span>. <span class="nt"></span></span> <span class="cp">{%</span> <span class="k">if</span> <span class="nv">page_obj.has_next</span> <span class="cp">%}</span> <span class="nt"><a</span> <span class="na">href=</span><span class="s">"?page=</span><span class="cp">{{</span> <span class="nv">page_obj.next_page_number</span> <span class="cp">}}</span><span class="s">"</span><span class="nt">></span>next<span class="nt"></a></span> <span class="cp">{%</span> <span class="k">endif</span> <span class="cp">%}</span> <span class="nt"></span></span> <span class="nt"></div></span> <span class="cp">{%</span> <span class="k">endblock</span> <span class="cp">%}</span> </pre></div> </div> </div> </div> <div class="section" id="s-avoid-anything-more-complex"> <span id="avoid-anything-more-complex"></span><h2>Avoid anything more complex<a class="headerlink" href="#avoid-anything-more-complex" title="Permalink to this headline">¶</a></h2> <p>Generally you can use <a class="reference internal" href="../../ref/class-based-views/mixins-simple.html#django.views.generic.base.TemplateResponseMixin" title="django.views.generic.base.TemplateResponseMixin"><tt class="xref py py-class docutils literal"><span class="pre">TemplateResponseMixin</span></tt></a> and <a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectMixin" title="django.views.generic.detail.SingleObjectMixin"><tt class="xref py py-class docutils literal"><span class="pre">SingleObjectMixin</span></tt></a> when you need their functionality. As shown above, with a bit of care you can even combine <tt class="docutils literal"><span class="pre">SingleObjectMixin</span></tt> with <a class="reference internal" href="../../ref/class-based-views/generic-display.html#django.views.generic.list.ListView" title="django.views.generic.list.ListView"><tt class="xref py py-class docutils literal"><span class="pre">ListView</span></tt></a>. However things get increasingly complex as you try to do so, and a good rule of thumb is:</p> <div class="admonition hint"> <p class="first admonition-title">Hint</p> <p class="last">Each of your views should use only mixins or views from one of the groups of generic class-based views: <a class="reference internal" href="generic-display.html"><em>detail, list</em></a>, <a class="reference internal" href="generic-editing.html"><em>editing</em></a> and date. For example it’s fine to combine <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#TemplateView" title="TemplateView"><tt class="xref py py-class docutils literal"><span class="pre">TemplateView</span></tt></a> (built in view) with <a class="reference internal" href="../../ref/class-based-views/mixins-multiple-object.html#django.views.generic.list.MultipleObjectMixin" title="django.views.generic.list.MultipleObjectMixin"><tt class="xref py py-class docutils literal"><span class="pre">MultipleObjectMixin</span></tt></a> (generic list), but you’re likely to have problems combining <tt class="docutils literal"><span class="pre">SingleObjectMixin</span></tt> (generic detail) with <tt class="docutils literal"><span class="pre">MultipleObjectMixin</span></tt> (generic list).</p> </div> <p>To show what happens when you try to get more sophisticated, we show an example that sacrifices readability and maintainability when there is a simpler solution. First, let’s look at a naive attempt to combine <a class="reference internal" href="../../ref/class-based-views/generic-display.html#django.views.generic.detail.DetailView" title="django.views.generic.detail.DetailView"><tt class="xref py py-class docutils literal"><span class="pre">DetailView</span></tt></a> with <a class="reference internal" href="../../ref/class-based-views/mixins-editing.html#django.views.generic.edit.FormMixin" title="django.views.generic.edit.FormMixin"><tt class="xref py py-class docutils literal"><span class="pre">FormMixin</span></tt></a> to enable use to <tt class="docutils literal"><span class="pre">POST</span></tt> a Django <a class="reference internal" href="../../ref/forms/api.html#django.forms.Form" title="django.forms.Form"><tt class="xref py py-class docutils literal"><span class="pre">Form</span></tt></a> to the same URL as we’re displaying an object using <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#DetailView" title="DetailView"><tt class="xref py py-class docutils literal"><span class="pre">DetailView</span></tt></a>.</p> <div class="section" id="s-using-formmixin-with-detailview"> <span id="using-formmixin-with-detailview"></span><h3>Using FormMixin with DetailView<a class="headerlink" href="#using-formmixin-with-detailview" title="Permalink to this headline">¶</a></h3> <p>Think back to our earlier example of using <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#View" title="View"><tt class="xref py py-class docutils literal"><span class="pre">View</span></tt></a> and <a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectMixin" title="django.views.generic.detail.SingleObjectMixin"><tt class="xref py py-class docutils literal"><span class="pre">SingleObjectMixin</span></tt></a> together. We were recording a user’s interest in a particular author; say now that we want to let them leave a message saying why they like them. Again, let’s assume we’re not going to store this in a relational database but instead in something more esoteric that we won’t worry about here.</p> <p>At this point it’s natural to reach for a <a class="reference internal" href="../../ref/forms/api.html#django.forms.Form" title="django.forms.Form"><tt class="xref py py-class docutils literal"><span class="pre">Form</span></tt></a> to encapsulate the information sent from the user’s browser to Django. Say also that we’re heavily invested in <a class="reference external" href="http://en.wikipedia.org/wiki/Representational_state_transfer">REST</a>, so we want to use the same URL for displaying the author as for capturing the message from the user. Let’s rewrite our <tt class="docutils literal"><span class="pre">AuthorDetailView</span></tt> to do that.</p> <p>We’ll keep the <tt class="docutils literal"><span class="pre">GET</span></tt> handling from <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#DetailView" title="DetailView"><tt class="xref py py-class docutils literal"><span class="pre">DetailView</span></tt></a>, although we’ll have to add a <a class="reference internal" href="../../ref/forms/api.html#django.forms.Form" title="django.forms.Form"><tt class="xref py py-class docutils literal"><span class="pre">Form</span></tt></a> into the context data so we can render it in the template. We’ll also want to pull in form processing from <a class="reference internal" href="../../ref/class-based-views/mixins-editing.html#django.views.generic.edit.FormMixin" title="django.views.generic.edit.FormMixin"><tt class="xref py py-class docutils literal"><span class="pre">FormMixin</span></tt></a>, and write a bit of code so that on <tt class="docutils literal"><span class="pre">POST</span></tt> the form gets called appropriately.</p> <div class="admonition note"> <p class="first admonition-title">Note</p> <p class="last">We use <a class="reference internal" href="../../ref/class-based-views/mixins-editing.html#django.views.generic.edit.FormMixin" title="django.views.generic.edit.FormMixin"><tt class="xref py py-class docutils literal"><span class="pre">FormMixin</span></tt></a> and implement <tt class="docutils literal"><span class="pre">post()</span></tt> ourselves rather than try to mix <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#DetailView" title="DetailView"><tt class="xref py py-class docutils literal"><span class="pre">DetailView</span></tt></a> with <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#FormView" title="FormView"><tt class="xref py py-class docutils literal"><span class="pre">FormView</span></tt></a> (which provides a suitable <tt class="docutils literal"><span class="pre">post()</span></tt> already) because both of the views implement <tt class="docutils literal"><span class="pre">get()</span></tt>, and things would get much more confusing.</p> </div> <p>Our new <tt class="docutils literal"><span class="pre">AuthorDetail</span></tt> looks like this:</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># CAUTION: you almost certainly do not want to do this.</span> <span class="c"># It is provided as part of a discussion of problems you can</span> <span class="c"># run into when combining different generic class-based view</span> <span class="c"># functionality that is not designed to be used together.</span> <span class="kn">from</span> <span class="nn">django</span> <span class="kn">import</span> <span class="n">forms</span> <span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">HttpResponseForbidden</span> <span class="kn">from</span> <span class="nn">django.core.urlresolvers</span> <span class="kn">import</span> <span class="n">reverse</span> <span class="kn">from</span> <span class="nn">django.views.generic</span> <span class="kn">import</span> <span class="n">DetailView</span> <span class="kn">from</span> <span class="nn">django.views.generic.edit</span> <span class="kn">import</span> <span class="n">FormMixin</span> <span class="k">class</span> <span class="nc">AuthorInterestForm</span><span class="p">(</span><span class="n">forms</span><span class="o">.</span><span class="n">Form</span><span class="p">):</span> <span class="n">message</span> <span class="o">=</span> <span class="n">forms</span><span class="o">.</span><span class="n">CharField</span><span class="p">()</span> <span class="k">class</span> <span class="nc">AuthorDetail</span><span class="p">(</span><span class="n">DetailView</span><span class="p">,</span> <span class="n">FormMixin</span><span class="p">):</span> <span class="n">model</span> <span class="o">=</span> <span class="n">Author</span> <span class="n">form_class</span> <span class="o">=</span> <span class="n">AuthorInterestForm</span> <span class="k">def</span> <span class="nf">get_success_url</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">return</span> <span class="n">reverse</span><span class="p">(</span><span class="s">'author-detail'</span><span class="p">,</span> <span class="n">kwargs</span><span class="o">=</span><span class="p">{</span><span class="s">'pk'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">object</span><span class="o">.</span><span class="n">pk</span><span class="p">})</span> <span class="k">def</span> <span class="nf">get_context_data</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="n">context</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">AuthorDetail</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">get_context_data</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="n">form_class</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_form_class</span><span class="p">()</span> <span class="n">context</span><span class="p">[</span><span class="s">'form'</span><span class="p">]</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_form</span><span class="p">(</span><span class="n">form_class</span><span class="p">)</span> <span class="k">return</span> <span class="n">context</span> <span class="k">def</span> <span class="nf">post</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">is_authenticated</span><span class="p">():</span> <span class="k">return</span> <span class="n">HttpResponseForbidden</span><span class="p">()</span> <span class="bp">self</span><span class="o">.</span><span class="n">object</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_object</span><span class="p">()</span> <span class="n">form_class</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_form_class</span><span class="p">()</span> <span class="n">form</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_form</span><span class="p">(</span><span class="n">form_class</span><span class="p">)</span> <span class="k">if</span> <span class="n">form</span><span class="o">.</span><span class="n">is_valid</span><span class="p">():</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">form_valid</span><span class="p">(</span><span class="n">form</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">form_invalid</span><span class="p">(</span><span class="n">form</span><span class="p">)</span> <span class="k">def</span> <span class="nf">form_valid</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">form</span><span class="p">):</span> <span class="c"># Here, we would record the user's interest using the message</span> <span class="c"># passed in form.cleaned_data['message']</span> <span class="k">return</span> <span class="nb">super</span><span class="p">(</span><span class="n">AuthorDetail</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">form_valid</span><span class="p">(</span><span class="n">form</span><span class="p">)</span> </pre></div> </div> <p><tt class="docutils literal"><span class="pre">get_success_url()</span></tt> is just providing somewhere to redirect to, which gets used in the default implementation of <tt class="docutils literal"><span class="pre">form_valid()</span></tt>. We have to provide our own <tt class="docutils literal"><span class="pre">post()</span></tt> as noted earlier, and override <tt class="docutils literal"><span class="pre">get_context_data()</span></tt> to make the <a class="reference internal" href="../../ref/forms/api.html#django.forms.Form" title="django.forms.Form"><tt class="xref py py-class docutils literal"><span class="pre">Form</span></tt></a> available in the context data.</p> </div> <div class="section" id="s-a-better-solution"> <span id="a-better-solution"></span><h3>A better solution<a class="headerlink" href="#a-better-solution" title="Permalink to this headline">¶</a></h3> <p>It should be obvious that the number of subtle interactions between <a class="reference internal" href="../../ref/class-based-views/mixins-editing.html#django.views.generic.edit.FormMixin" title="django.views.generic.edit.FormMixin"><tt class="xref py py-class docutils literal"><span class="pre">FormMixin</span></tt></a> and <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#DetailView" title="DetailView"><tt class="xref py py-class docutils literal"><span class="pre">DetailView</span></tt></a> is already testing our ability to manage things. It’s unlikely you’d want to write this kind of class yourself.</p> <p>In this case, it would be fairly easy to just write the <tt class="docutils literal"><span class="pre">post()</span></tt> method yourself, keeping <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#DetailView" title="DetailView"><tt class="xref py py-class docutils literal"><span class="pre">DetailView</span></tt></a> as the only generic functionality, although writing <a class="reference internal" href="../../ref/forms/api.html#django.forms.Form" title="django.forms.Form"><tt class="xref py py-class docutils literal"><span class="pre">Form</span></tt></a> handling code involves a lot of duplication.</p> <p>Alternatively, it would still be easier than the above approach to have a separate view for processing the form, which could use <a class="reference internal" href="../../ref/class-based-views/generic-editing.html#django.views.generic.edit.FormView" title="django.views.generic.edit.FormView"><tt class="xref py py-class docutils literal"><span class="pre">FormView</span></tt></a> distinct from <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#DetailView" title="DetailView"><tt class="xref py py-class docutils literal"><span class="pre">DetailView</span></tt></a> without concerns.</p> </div> <div class="section" id="s-an-alternative-better-solution"> <span id="an-alternative-better-solution"></span><h3>An alternative better solution<a class="headerlink" href="#an-alternative-better-solution" title="Permalink to this headline">¶</a></h3> <p>What we’re really trying to do here is to use two different class based views from the same URL. So why not do just that? We have a very clear division here: <tt class="docutils literal"><span class="pre">GET</span></tt> requests should get the <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#DetailView" title="DetailView"><tt class="xref py py-class docutils literal"><span class="pre">DetailView</span></tt></a> (with the <a class="reference internal" href="../../ref/forms/api.html#django.forms.Form" title="django.forms.Form"><tt class="xref py py-class docutils literal"><span class="pre">Form</span></tt></a> added to the context data), and <tt class="docutils literal"><span class="pre">POST</span></tt> requests should get the <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#FormView" title="FormView"><tt class="xref py py-class docutils literal"><span class="pre">FormView</span></tt></a>. Let’s set up those views first.</p> <p>The <tt class="docutils literal"><span class="pre">AuthorDisplay</span></tt> view is almost the same as <a class="reference internal" href="generic-display.html#generic-views-extra-work"><em>when we first introduced AuthorDetail</em></a>; we have to write our own <tt class="docutils literal"><span class="pre">get_context_data()</span></tt> to make the <tt class="docutils literal"><span class="pre">AuthorInterestForm</span></tt> available to the template. We’ll skip the <tt class="docutils literal"><span class="pre">get_object()</span></tt> override from before for clarity.</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.views.generic</span> <span class="kn">import</span> <span class="n">DetailView</span> <span class="kn">from</span> <span class="nn">django</span> <span class="kn">import</span> <span class="n">forms</span> <span class="kn">from</span> <span class="nn">books.models</span> <span class="kn">import</span> <span class="n">Author</span> <span class="k">class</span> <span class="nc">AuthorInterestForm</span><span class="p">(</span><span class="n">forms</span><span class="o">.</span><span class="n">Form</span><span class="p">):</span> <span class="n">message</span> <span class="o">=</span> <span class="n">forms</span><span class="o">.</span><span class="n">CharField</span><span class="p">()</span> <span class="k">class</span> <span class="nc">AuthorDisplay</span><span class="p">(</span><span class="n">DetailView</span><span class="p">):</span> <span class="n">model</span> <span class="o">=</span> <span class="n">Author</span> <span class="k">def</span> <span class="nf">get_context_data</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="n">context</span> <span class="o">=</span> <span class="nb">super</span><span class="p">(</span><span class="n">AuthorDisplay</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">get_context_data</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="n">context</span><span class="p">[</span><span class="s">'form'</span><span class="p">]</span> <span class="o">=</span> <span class="n">AuthorInterestForm</span><span class="p">()</span> <span class="k">return</span> <span class="n">context</span> </pre></div> </div> <p>Then the <tt class="docutils literal"><span class="pre">AuthorInterest</span></tt> is a simple <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#FormView" title="FormView"><tt class="xref py py-class docutils literal"><span class="pre">FormView</span></tt></a>, but we have to bring in <a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectMixin" title="django.views.generic.detail.SingleObjectMixin"><tt class="xref py py-class docutils literal"><span class="pre">SingleObjectMixin</span></tt></a> so we can find the author we’re talking about, and we have to remember to set <tt class="docutils literal"><span class="pre">template_name</span></tt> to ensure that form errors will render the same template as <tt class="docutils literal"><span class="pre">AuthorDisplay</span></tt> is using on <tt class="docutils literal"><span class="pre">GET</span></tt>.</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.views.generic</span> <span class="kn">import</span> <span class="n">FormView</span> <span class="kn">from</span> <span class="nn">django.views.generic.detail</span> <span class="kn">import</span> <span class="n">SingleObjectMixin</span> <span class="k">class</span> <span class="nc">AuthorInterest</span><span class="p">(</span><span class="n">FormView</span><span class="p">,</span> <span class="n">SingleObjectMixin</span><span class="p">):</span> <span class="n">template_name</span> <span class="o">=</span> <span class="s">'books/author_detail.html'</span> <span class="n">form_class</span> <span class="o">=</span> <span class="n">AuthorInterestForm</span> <span class="n">model</span> <span class="o">=</span> <span class="n">Author</span> <span class="k">def</span> <span class="nf">post</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">request</span><span class="o">.</span><span class="n">user</span><span class="o">.</span><span class="n">is_authenticated</span><span class="p">():</span> <span class="k">return</span> <span class="n">HttpResponseForbidden</span><span class="p">()</span> <span class="bp">self</span><span class="o">.</span><span class="n">object</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">get_object</span><span class="p">()</span> <span class="k">return</span> <span class="nb">super</span><span class="p">(</span><span class="n">AuthorInterest</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">post</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="k">def</span> <span class="nf">get_success_url</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">return</span> <span class="n">reverse</span><span class="p">(</span><span class="s">'author-detail'</span><span class="p">,</span> <span class="n">kwargs</span><span class="o">=</span><span class="p">{</span><span class="s">'pk'</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">object</span><span class="o">.</span><span class="n">pk</span><span class="p">})</span> </pre></div> </div> <p>Finally we bring this together in a new <tt class="docutils literal"><span class="pre">AuthorDetail</span></tt> view. We already know that calling <a class="reference internal" href="../../ref/class-based-views/base.html#django.views.generic.base.View.as_view" title="django.views.generic.base.View.as_view"><tt class="xref py py-meth docutils literal"><span class="pre">as_view()</span></tt></a> on a class-based view gives us something that behaves exactly like a function based view, so we can do that at the point we choose between the two subviews.</p> <p>You can of course pass through keyword arguments to <a class="reference internal" href="../../ref/class-based-views/base.html#django.views.generic.base.View.as_view" title="django.views.generic.base.View.as_view"><tt class="xref py py-meth docutils literal"><span class="pre">as_view()</span></tt></a> in the same way you would in your URLconf, such as if you wanted the <tt class="docutils literal"><span class="pre">AuthorInterest</span></tt> behavior to also appear at another URL but using a different template.</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.views.generic</span> <span class="kn">import</span> <span class="n">View</span> <span class="k">class</span> <span class="nc">AuthorDetail</span><span class="p">(</span><span class="n">View</span><span class="p">):</span> <span class="k">def</span> <span class="nf">get</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="n">view</span> <span class="o">=</span> <span class="n">AuthorDisplay</span><span class="o">.</span><span class="n">as_view</span><span class="p">()</span> <span class="k">return</span> <span class="n">view</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="k">def</span> <span class="nf">post</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">):</span> <span class="n">view</span> <span class="o">=</span> <span class="n">AuthorInterest</span><span class="o">.</span><span class="n">as_view</span><span class="p">()</span> <span class="k">return</span> <span class="n">view</span><span class="p">(</span><span class="n">request</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> </pre></div> </div> <p>This approach can also be used with any other generic class-based views or your own class-based views inheriting directly from <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#View" title="View"><tt class="xref py py-class docutils literal"><span class="pre">View</span></tt></a> or <a class="reference internal" href="../../ref/class-based-views/flattened-index.html#TemplateView" title="TemplateView"><tt class="xref py py-class docutils literal"><span class="pre">TemplateView</span></tt></a>, as it keeps the different views as separate as possible.</p> </div> </div> <div class="section" id="s-more-than-just-html"> <span id="s-jsonresponsemixin-example"></span><span id="more-than-just-html"></span><span id="jsonresponsemixin-example"></span><h2>More than just HTML<a class="headerlink" href="#more-than-just-html" title="Permalink to this headline">¶</a></h2> <p>Where class based views shine is when you want to do the same thing many times. Suppose you’re writing an API, and every view should return JSON instead of rendered HTML.</p> <p>We can create a mixin class to use in all of our views, handling the conversion to JSON once.</p> <p>For example, a simple JSON mixin might look something like this:</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">import</span> <span class="nn">json</span> <span class="kn">from</span> <span class="nn">django.http</span> <span class="kn">import</span> <span class="n">HttpResponse</span> <span class="k">class</span> <span class="nc">JSONResponseMixin</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> A mixin that can be used to render a JSON response.</span> <span class="sd"> """</span> <span class="n">response_class</span> <span class="o">=</span> <span class="n">HttpResponse</span> <span class="k">def</span> <span class="nf">render_to_response</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">,</span> <span class="o">**</span><span class="n">response_kwargs</span><span class="p">):</span> <span class="sd">"""</span> <span class="sd"> Returns a JSON response, transforming 'context' to make the payload.</span> <span class="sd"> """</span> <span class="n">response_kwargs</span><span class="p">[</span><span class="s">'content_type'</span><span class="p">]</span> <span class="o">=</span> <span class="s">'application/json'</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.</span><span class="n">response_class</span><span class="p">(</span> <span class="bp">self</span><span class="o">.</span><span class="n">convert_context_to_json</span><span class="p">(</span><span class="n">context</span><span class="p">),</span> <span class="o">**</span><span class="n">response_kwargs</span> <span class="p">)</span> <span class="k">def</span> <span class="nf">convert_context_to_json</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span> <span class="s">"Convert the context dictionary into a JSON object"</span> <span class="c"># Note: This is *EXTREMELY* naive; in reality, you'll need</span> <span class="c"># to do much more complex handling to ensure that arbitrary</span> <span class="c"># objects -- such as Django model instances or querysets</span> <span class="c"># -- can be serialized as JSON.</span> <span class="k">return</span> <span class="n">json</span><span class="o">.</span><span class="n">dumps</span><span class="p">(</span><span class="n">context</span><span class="p">)</span> </pre></div> </div> <p>Now we mix this into the base TemplateView:</p> <div class="highlight-python"><div class="highlight"><pre><span class="kn">from</span> <span class="nn">django.views.generic</span> <span class="kn">import</span> <span class="n">TemplateView</span> <span class="k">class</span> <span class="nc">JSONView</span><span class="p">(</span><span class="n">JSONResponseMixin</span><span class="p">,</span> <span class="n">TemplateView</span><span class="p">):</span> <span class="k">pass</span> </pre></div> </div> <p>Equally we could use our mixin with one of the generic views. We can make our own version of <a class="reference internal" href="../../ref/class-based-views/generic-display.html#django.views.generic.detail.DetailView" title="django.views.generic.detail.DetailView"><tt class="xref py py-class docutils literal"><span class="pre">DetailView</span></tt></a> by mixing <tt class="docutils literal"><span class="pre">JSONResponseMixin</span></tt> with the <tt class="docutils literal"><span class="pre">django.views.generic.detail.BaseDetailView</span></tt> – (the <a class="reference internal" href="../../ref/class-based-views/generic-display.html#django.views.generic.detail.DetailView" title="django.views.generic.detail.DetailView"><tt class="xref py py-class docutils literal"><span class="pre">DetailView</span></tt></a> before template rendering behavior has been mixed in):</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">JSONDetailView</span><span class="p">(</span><span class="n">JSONResponseMixin</span><span class="p">,</span> <span class="n">BaseDetailView</span><span class="p">):</span> <span class="k">pass</span> </pre></div> </div> <p>This view can then be deployed in the same way as any other <a class="reference internal" href="../../ref/class-based-views/generic-display.html#django.views.generic.detail.DetailView" title="django.views.generic.detail.DetailView"><tt class="xref py py-class docutils literal"><span class="pre">DetailView</span></tt></a>, with exactly the same behavior – except for the format of the response.</p> <p>If you want to be really adventurous, you could even mix a <a class="reference internal" href="../../ref/class-based-views/generic-display.html#django.views.generic.detail.DetailView" title="django.views.generic.detail.DetailView"><tt class="xref py py-class docutils literal"><span class="pre">DetailView</span></tt></a> subclass that is able to return <em>both</em> HTML and JSON content, depending on some property of the HTTP request, such as a query argument or a HTTP header. Just mix in both the <tt class="docutils literal"><span class="pre">JSONResponseMixin</span></tt> and a <a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectTemplateResponseMixin" title="django.views.generic.detail.SingleObjectTemplateResponseMixin"><tt class="xref py py-class docutils literal"><span class="pre">SingleObjectTemplateResponseMixin</span></tt></a>, and override the implementation of <a class="reference internal" href="../../ref/class-based-views/mixins-simple.html#django.views.generic.base.TemplateResponseMixin.render_to_response" title="django.views.generic.base.TemplateResponseMixin.render_to_response"><tt class="xref py py-func docutils literal"><span class="pre">render_to_response()</span></tt></a> to defer to the appropriate subclass depending on the type of response that the user requested:</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">class</span> <span class="nc">HybridDetailView</span><span class="p">(</span><span class="n">JSONResponseMixin</span><span class="p">,</span> <span class="n">SingleObjectTemplateResponseMixin</span><span class="p">,</span> <span class="n">BaseDetailView</span><span class="p">):</span> <span class="k">def</span> <span class="nf">render_to_response</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">):</span> <span class="c"># Look for a 'format=json' GET argument</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">request</span><span class="o">.</span><span class="n">GET</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s">'format'</span><span class="p">,</span><span class="s">'html'</span><span class="p">)</span> <span class="o">==</span> <span class="s">'json'</span><span class="p">:</span> <span class="k">return</span> <span class="n">JSONResponseMixin</span><span class="o">.</span><span class="n">render_to_response</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="k">return</span> <span class="n">SingleObjectTemplateResponseMixin</span><span class="o">.</span><span class="n">render_to_response</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">context</span><span class="p">)</span> </pre></div> </div> <p>Because of the way that Python resolves method overloading, the local <tt class="docutils literal"><span class="pre">render_to_response()</span></tt> implementation will override the versions provided by <tt class="docutils literal"><span class="pre">JSONResponseMixin</span></tt> and <a class="reference internal" href="../../ref/class-based-views/mixins-single-object.html#django.views.generic.detail.SingleObjectTemplateResponseMixin" title="django.views.generic.detail.SingleObjectTemplateResponseMixin"><tt class="xref py py-class docutils literal"><span class="pre">SingleObjectTemplateResponseMixin</span></tt></a>.</p> </div> </div> </div> </div> </div> <div class="yui-b" id="sidebar"> <div class="sphinxsidebar"> <div class="sphinxsidebarwrapper"> <h3><a href="../../contents.html">Table Of Contents</a></h3> <ul> <li><a class="reference internal" href="#">Using mixins with class-based views</a><ul> <li><a class="reference internal" href="#context-and-template-responses">Context and template responses</a></li> <li><a class="reference internal" href="#building-up-django-s-generic-class-based-views">Building up Django’s generic class-based views</a><ul> <li><a class="reference internal" href="#detailview-working-with-a-single-django-object">DetailView: working with a single Django object</a></li> <li><a class="reference internal" href="#listview-working-with-many-django-objects">ListView: working with many Django objects</a></li> </ul> </li> <li><a class="reference internal" href="#using-django-s-class-based-view-mixins">Using Django’s class-based view mixins</a><ul> <li><a class="reference internal" href="#using-singleobjectmixin-with-view">Using SingleObjectMixin with View</a></li> <li><a class="reference internal" href="#using-singleobjectmixin-with-listview">Using SingleObjectMixin with ListView</a></li> </ul> </li> <li><a class="reference internal" href="#avoid-anything-more-complex">Avoid anything more complex</a><ul> <li><a class="reference internal" href="#using-formmixin-with-detailview">Using FormMixin with DetailView</a></li> <li><a class="reference internal" href="#a-better-solution">A better solution</a></li> <li><a class="reference internal" href="#an-alternative-better-solution">An alternative better solution</a></li> </ul> </li> <li><a class="reference internal" href="#more-than-just-html">More than just HTML</a></li> </ul> </li> </ul> <h3>Browse</h3> <ul> <li>Prev: <a href="generic-editing.html">Form handling with class-based views</a></li> <li>Next: <a href="../files.html">Managing files</a></li> </ul> <h3>You are here:</h3> <ul> <li> <a href="../../index.html">Django 1.5.8 documentation</a> <ul><li><a href="../index.html">Using Django</a> <ul><li><a href="index.html">Class-based views</a> <ul><li>Using mixins with class-based views</li></ul> </li></ul></li></ul> </li> </ul> <h3>This Page</h3> <ul class="this-page-menu"> <li><a href="../../_sources/topics/class-based-views/mixins.txt" rel="nofollow">Show Source</a></li> </ul> <div id="searchbox" style="display: none"> <h3>Quick search</h3> <form class="search" action="../../search.html" method="get"> <input type="text" name="q" /> <input type="submit" value="Go" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> <p class="searchtip" style="font-size: 90%"> Enter search terms or a module, class or function name. </p> </div> <script type="text/javascript">$('#searchbox').show(0);</script> </div> </div> <h3>Last update:</h3> <p class="topless">May 15, 2014</p> </div> </div> <div id="ft"> <div class="nav"> « <a href="generic-editing.html" title="Form handling with class-based views">previous</a> | <a href="../index.html" title="Using Django" accesskey="U">up</a> | <a href="../files.html" title="Managing files">next</a> »</div> </div> </div> <div class="clearer"></div> </div> </body> </html>