{"title":"Built-in class-based generic views","version":"6.0","locale":"en","docname":"topics/class-based-views/generic-display","url":"/en/6.0/topics/class-based-views/generic-display/","canonical":"https://djangodocs.dev/en/6.0/topics/class-based-views/generic-display/","summary":"Writing web applications can be monotonous, because we repeat certain patterns again and again. Django tries to take away some of that monotony at the model and…","html":"<h1>Built-in class-based generic views<a class=\"heading-anchor\" href=\"#built-in-class-based-generic-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Writing web applications can be monotonous, because we repeat certain patterns\nagain and again. Django tries to take away some of that monotony at the model\nand template layers, but web developers also experience this boredom at the\nview level.</p>\n<p>Django’s <em>generic views</em> were developed to ease that pain. They take certain\ncommon idioms and patterns found in view development and abstract them so that\nyou can quickly write common views of data without having to write too much\ncode.</p>\n<p>We can recognize certain common tasks, like displaying a list of objects, and\nwrite code that displays a list of <em>any</em> object. Then the model in question can\nbe passed as an extra argument to the URLconf.</p>\n<p>Django ships with generic views to do the following:</p>\n<ul class=\"simple\">\n<li><p>Display list and detail pages for a single object. If we were creating an\napplication to manage conferences then a <code class=\"docutils literal notranslate\"><span class=\"pre\">TalkListView</span></code> and a\n<code class=\"docutils literal notranslate\"><span class=\"pre\">RegisteredUserListView</span></code> would be examples of list views. A single\ntalk page is an example of what we call a “detail” view.</p></li>\n<li><p>Present date-based objects in year/month/day archive pages,\nassociated detail, and “latest” pages.</p></li>\n<li><p>Allow users to create, update, and delete objects – with or\nwithout authorization.</p></li>\n</ul>\n<p>Taken together, these views provide interfaces to perform the most common tasks\ndevelopers encounter.</p>\n<section id=\"extending-generic-views\">\n<h2>Extending generic views<a class=\"heading-anchor\" href=\"#extending-generic-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>There’s no question that using generic views can speed up development\nsubstantially. In most projects, however, there comes a moment when the\ngeneric views no longer suffice. Indeed, the most common question asked by new\nDjango developers is how to make generic views handle a wider array of\nsituations.</p>\n<p>This is one of the reasons generic views were redesigned for the 1.3 release -\npreviously, they were view functions with a bewildering array of options; now,\nrather than passing in a large amount of configuration in the URLconf, the\nrecommended way to extend generic views is to subclass them, and override their\nattributes or methods.</p>\n<p>That said, generic views will have a limit. If you find you’re struggling to\nimplement your view as a subclass of a generic view, then you may find it more\neffective to write just the code you need, using your own class-based or\nfunctional views.</p>\n<p>More examples of generic views are available in some third party applications,\nor you could write your own as needed.</p>\n</section>\n<section id=\"generic-views-of-objects\">\n<h2>Generic views of objects<a class=\"heading-anchor\" href=\"#generic-views-of-objects\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p><a class=\"reference internal\" href=\"/en/6.0/ref/class-based-views/base/#django.views.generic.base.TemplateView\" title=\"django.views.generic.base.TemplateView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateView</span></code></a> certainly is useful, but\nDjango’s generic views really shine when it comes to presenting views of your\ndatabase content. Because it’s such a common task, Django comes with a handful\nof built-in generic views to help generate list and detail views of objects.</p>\n<p>Let’s start by looking at some examples of showing a list of objects or an\nindividual object.</p>\n<p>We’ll be using these models:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># models.py</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">models</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Publisher</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">30</span><span class=\"p\">)</span>\n    <span class=\"n\">address</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">50</span><span class=\"p\">)</span>\n    <span class=\"n\">city</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">60</span><span class=\"p\">)</span>\n    <span class=\"n\">state_province</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">30</span><span class=\"p\">)</span>\n    <span class=\"n\">country</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">50</span><span class=\"p\">)</span>\n    <span class=\"n\">website</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">URLField</span><span class=\"p\">()</span>\n\n    <span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        <span class=\"n\">ordering</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"s2\">&quot;-name&quot;</span><span class=\"p\">]</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__str__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">name</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Author</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">salutation</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">)</span>\n    <span class=\"n\">name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">200</span><span class=\"p\">)</span>\n    <span class=\"n\">email</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">EmailField</span><span class=\"p\">()</span>\n    <span class=\"n\">headshot</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">ImageField</span><span class=\"p\">(</span><span class=\"n\">upload_to</span><span class=\"o\">=</span><span class=\"s2\">&quot;author_headshots&quot;</span><span class=\"p\">)</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__str__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"k\">return</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">name</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Book</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">title</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n    <span class=\"n\">authors</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">ManyToManyField</span><span class=\"p\">(</span><span class=\"s2\">&quot;Author&quot;</span><span class=\"p\">)</span>\n    <span class=\"n\">publisher</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">ForeignKey</span><span class=\"p\">(</span><span class=\"n\">Publisher</span><span class=\"p\">,</span> <span class=\"n\">on_delete</span><span class=\"o\">=</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CASCADE</span><span class=\"p\">)</span>\n    <span class=\"n\">publication_date</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">DateField</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>Now we need to define a view:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># views.py</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ListView</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Publisher</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">PublisherListView</span><span class=\"p\">(</span><span class=\"n\">ListView</span><span class=\"p\">):</span>\n    <span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">Publisher</span>\n</code></pre></div>\n<p>Finally hook that view into your urls:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># urls.py</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.urls</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">path</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.views</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">PublisherListView</span>\n\n<span class=\"n\">urlpatterns</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"n\">path</span><span class=\"p\">(</span><span class=\"s2\">&quot;publishers/&quot;</span><span class=\"p\">,</span> <span class=\"n\">PublisherListView</span><span class=\"o\">.</span><span class=\"n\">as_view</span><span class=\"p\">()),</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>That’s all the Python code we need to write. We still need to write a template,\nhowever. We could explicitly tell the view which template to use by adding a\n<code class=\"docutils literal notranslate\"><span class=\"pre\">template_name</span></code> attribute to the view, but in the absence of an explicit\ntemplate Django will infer one from the object’s name. In this case, the\ninferred template will be <code class=\"docutils literal notranslate\"><span class=\"pre\">&quot;books/publisher_list.html&quot;</span></code> – the “books” part\ncomes from the name of the app that defines the model, while the “publisher”\nbit is the lowercased version of the model’s name.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Thus, when (for example) the <code class=\"docutils literal notranslate\"><span class=\"pre\">APP_DIRS</span></code> option of a <code class=\"docutils literal notranslate\"><span class=\"pre\">DjangoTemplates</span></code>\nbackend is set to True in <a class=\"reference internal\" href=\"/en/6.0/ref/settings/#std-setting-TEMPLATES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">TEMPLATES</span></code></a>, a template location could\nbe: /path/to/project/books/templates/books/publisher_list.html</p>\n</aside>\n<p>This template will be rendered against a context containing a variable called\n<code class=\"docutils literal notranslate\"><span class=\"pre\">object_list</span></code> that contains all the publisher objects. A template might look\nlike this:</p>\n<div class=\"code-block\" data-language=\"html+django\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Django template</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Django template code\"><code><span class=\"cp\">{%</span> <span class=\"k\">extends</span> <span class=\"s2\">&quot;base.html&quot;</span> <span class=\"cp\">%}</span>\n\n<span class=\"cp\">{%</span> <span class=\"k\">block</span> <span class=\"nv\">content</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>Publishers<span class=\"p\">&lt;/</span><span class=\"nt\">h2</span><span class=\"p\">&gt;</span>\n    <span class=\"p\">&lt;</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n        <span class=\"cp\">{%</span> <span class=\"k\">for</span> <span class=\"nv\">publisher</span> <span class=\"k\">in</span> <span class=\"nv\">object_list</span> <span class=\"cp\">%}</span>\n            <span class=\"p\">&lt;</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span><span class=\"cp\">{{</span> <span class=\"nv\">publisher.name</span> <span class=\"cp\">}}</span><span class=\"p\">&lt;/</span><span class=\"nt\">li</span><span class=\"p\">&gt;</span>\n        <span class=\"cp\">{%</span> <span class=\"k\">endfor</span> <span class=\"cp\">%}</span>\n    <span class=\"p\">&lt;/</span><span class=\"nt\">ul</span><span class=\"p\">&gt;</span>\n<span class=\"cp\">{%</span> <span class=\"k\">endblock</span> <span class=\"cp\">%}</span>\n</code></pre></div>\n<p>That’s really all there is to it. All the cool features of generic views come\nfrom changing the attributes set on the generic view. The\n<a class=\"reference internal\" href=\"/en/6.0/ref/class-based-views/\"><span class=\"doc\">generic views reference</span></a> documents all the\ngeneric views and their options in detail; the rest of this document will\nconsider some of the common ways you might customize and extend generic views.</p>\n<section id=\"making-friendly-template-contexts\">\n<h3>Making “friendly” template contexts<a class=\"heading-anchor\" href=\"#making-friendly-template-contexts\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>You might have noticed that our sample publisher list template stores all the\npublishers in a variable named <code class=\"docutils literal notranslate\"><span class=\"pre\">object_list</span></code>. While this works just fine, it\nisn’t all that “friendly” to template authors: they have to “just know” that\nthey’re dealing with publishers here.</p>\n<p>Well, if you’re dealing with a model object, this is already done for you. When\nyou are dealing with an object or queryset, Django is able to populate the\ncontext using the lowercased version of the model class’ name. This is provided\nin addition to the default <code class=\"docutils literal notranslate\"><span class=\"pre\">object_list</span></code> entry, but contains exactly the same\ndata, i.e. <code class=\"docutils literal notranslate\"><span class=\"pre\">publisher_list</span></code>.</p>\n<p>If this still isn’t a good match, you can manually set the name of the\ncontext variable. The <code class=\"docutils literal notranslate\"><span class=\"pre\">context_object_name</span></code> attribute on a generic view\nspecifies the context variable to use:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># views.py</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ListView</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Publisher</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">PublisherListView</span><span class=\"p\">(</span><span class=\"n\">ListView</span><span class=\"p\">):</span>\n    <span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">Publisher</span>\n    <span class=\"n\">context_object_name</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;my_favorite_publishers&quot;</span>\n</code></pre></div>\n<p>Providing a useful <code class=\"docutils literal notranslate\"><span class=\"pre\">context_object_name</span></code> is always a good idea. Your\ncoworkers who design templates will thank you.</p>\n</section>\n<section id=\"adding-extra-context\">\n<span id=\"id1\"></span><h3>Adding extra context<a class=\"heading-anchor\" href=\"#adding-extra-context\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Often you need to present some extra information beyond that provided by the\ngeneric view. For example, think of showing a list of all the books on each\npublisher detail page. The <a class=\"reference internal\" href=\"/en/6.0/ref/class-based-views/generic-display/#django.views.generic.detail.DetailView\" title=\"django.views.generic.detail.DetailView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DetailView</span></code></a>\ngeneric view provides the publisher to the context, but how do we get\nadditional information in that template?</p>\n<p>The answer is to subclass <a class=\"reference internal\" href=\"/en/6.0/ref/class-based-views/generic-display/#django.views.generic.detail.DetailView\" title=\"django.views.generic.detail.DetailView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">DetailView</span></code></a>\nand provide your own implementation of the <code class=\"docutils literal notranslate\"><span class=\"pre\">get_context_data</span></code> method.\nThe default implementation adds the object being displayed to the template, but\nyou can override it to send more:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">DetailView</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Book</span><span class=\"p\">,</span> <span class=\"n\">Publisher</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">PublisherDetailView</span><span class=\"p\">(</span><span class=\"n\">DetailView</span><span class=\"p\">):</span>\n    <span class=\"n\">model</span> <span class=\"o\">=</span> <span class=\"n\">Publisher</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </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>\n        <span class=\"c1\"># Call the base implementation first to get a context</span>\n        <span class=\"n\">context</span> <span class=\"o\">=</span> <span class=\"nb\">super</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>\n        <span class=\"c1\"># Add in a QuerySet of all the books</span>\n        <span class=\"n\">context</span><span class=\"p\">[</span><span class=\"s2\">&quot;book_list&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span>\n        <span class=\"k\">return</span> <span class=\"n\">context</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Generally, <code class=\"docutils literal notranslate\"><span class=\"pre\">get_context_data</span></code> will merge the context data of all parent\nclasses with those of the current class. To preserve this behavior in your\nown classes where you want to alter the context, you should be sure to call\n<code class=\"docutils literal notranslate\"><span class=\"pre\">get_context_data</span></code> on the super class. When no two classes try to define\nthe same key, this will give the expected results. However if any class\nattempts to override a key after parent classes have set it (after the call\nto super), any children of that class will also need to explicitly set it\nafter super if they want to be sure to override all parents. If you’re\nhaving trouble, review the method resolution order of your view.</p>\n<p>Another consideration is that the context data from class-based generic\nviews will override data provided by context processors; see\n<a class=\"reference internal\" href=\"/en/6.0/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin.get_context_data\" title=\"django.views.generic.detail.SingleObjectMixin.get_context_data\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_context_data()</span></code></a> for\nan example.</p>\n</aside>\n</section>\n<section id=\"viewing-subsets-of-objects\">\n<span id=\"generic-views-list-subsets\"></span><h3>Viewing subsets of objects<a class=\"heading-anchor\" href=\"#viewing-subsets-of-objects\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Now let’s take a closer look at the <code class=\"docutils literal notranslate\"><span class=\"pre\">model</span></code> argument we’ve been\nusing all along. The <code class=\"docutils literal notranslate\"><span class=\"pre\">model</span></code> argument, which specifies the database\nmodel that the view will operate upon, is available on all the\ngeneric views that operate on a single object or a collection of\nobjects. However, the <code class=\"docutils literal notranslate\"><span class=\"pre\">model</span></code> argument is not the only way to\nspecify the objects that the view will operate upon – you can also\nspecify the list of objects using the <code class=\"docutils literal notranslate\"><span class=\"pre\">queryset</span></code> argument:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">DetailView</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Publisher</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">PublisherDetailView</span><span class=\"p\">(</span><span class=\"n\">DetailView</span><span class=\"p\">):</span>\n    <span class=\"n\">context_object_name</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;publisher&quot;</span>\n    <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>\n</code></pre></div>\n<p>Specifying <code class=\"docutils literal notranslate\"><span class=\"pre\">model</span> <span class=\"pre\">=</span> <span class=\"pre\">Publisher</span></code> is shorthand for saying <code class=\"docutils literal notranslate\"><span class=\"pre\">queryset</span> <span class=\"pre\">=</span>\n<span class=\"pre\">Publisher.objects.all()</span></code>. However, by using <code class=\"docutils literal notranslate\"><span class=\"pre\">queryset</span></code> to define a filtered\nlist of objects you can be more specific about the objects that will be visible\nin the view (see <a class=\"reference internal\" href=\"/en/6.0/topics/db/queries/\"><span class=\"doc\">Making queries</span></a> for more information about\n<a class=\"reference internal\" href=\"/en/6.0/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code></a> objects, and see the\n<a class=\"reference internal\" href=\"/en/6.0/ref/class-based-views/\"><span class=\"doc\">class-based views reference</span></a> for the\ncomplete details).</p>\n<p>To pick an example, we might want to order a list of books by publication date,\nwith the most recent first:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ListView</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Book</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">BookListView</span><span class=\"p\">(</span><span class=\"n\">ListView</span><span class=\"p\">):</span>\n    <span class=\"n\">queryset</span> <span class=\"o\">=</span> <span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">order_by</span><span class=\"p\">(</span><span class=\"s2\">&quot;-publication_date&quot;</span><span class=\"p\">)</span>\n    <span class=\"n\">context_object_name</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;book_list&quot;</span>\n</code></pre></div>\n<p>That’s a pretty minimal example, but it illustrates the idea nicely. You’ll\nusually want to do more than just reorder objects. If you want to present a\nlist of books by a particular publisher, you can use the same technique:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ListView</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Book</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">AcmeBookListView</span><span class=\"p\">(</span><span class=\"n\">ListView</span><span class=\"p\">):</span>\n    <span class=\"n\">context_object_name</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;book_list&quot;</span>\n    <span class=\"n\">queryset</span> <span class=\"o\">=</span> <span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">publisher__name</span><span class=\"o\">=</span><span class=\"s2\">&quot;ACME Publishing&quot;</span><span class=\"p\">)</span>\n    <span class=\"n\">template_name</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;books/acme_list.html&quot;</span>\n</code></pre></div>\n<p>Notice that along with a filtered <code class=\"docutils literal notranslate\"><span class=\"pre\">queryset</span></code>, we’re also using a custom\ntemplate name. If we didn’t, the generic view would use the same template as\nthe “vanilla” object list, which might not be what we want.</p>\n<p>Also notice that this isn’t a very elegant way of doing publisher-specific\nbooks. If we want to add another publisher page, we’d need another handful of\nlines in the URLconf, and more than a few publishers would get unreasonable.\nWe’ll deal with this problem in the next section.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>If you get a 404 when requesting <code class=\"docutils literal notranslate\"><span class=\"pre\">/books/acme/</span></code>, check to ensure you\nactually have a Publisher with the name ‘ACME Publishing’. Generic\nviews have an <code class=\"docutils literal notranslate\"><span class=\"pre\">allow_empty</span></code> parameter for this case. See the\n<a class=\"reference internal\" href=\"/en/6.0/ref/class-based-views/\"><span class=\"doc\">class-based-views reference</span></a> for more\ndetails.</p>\n</aside>\n</section>\n<section id=\"dynamic-filtering\">\n<h3>Dynamic filtering<a class=\"heading-anchor\" href=\"#dynamic-filtering\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Another common need is to filter down the objects given in a list page by some\nkey in the URL. Earlier we hardcoded the publisher’s name in the URLconf, but\nwhat if we wanted to write a view that displayed all the books by some\narbitrary publisher?</p>\n<p>Handily, the <code class=\"docutils literal notranslate\"><span class=\"pre\">ListView</span></code> has a\n<a class=\"reference internal\" href=\"/en/6.0/ref/class-based-views/mixins-multiple-object/#django.views.generic.list.MultipleObjectMixin.get_queryset\" title=\"django.views.generic.list.MultipleObjectMixin.get_queryset\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">get_queryset()</span></code></a> method we\ncan override. By default, it returns the value of the <code class=\"docutils literal notranslate\"><span class=\"pre\">queryset</span></code> attribute,\nbut we can use it to add more logic.</p>\n<p>The key part to making this work is that when class-based views are called,\nvarious useful things are stored on <code class=\"docutils literal notranslate\"><span class=\"pre\">self</span></code>; as well as the request\n(<code class=\"docutils literal notranslate\"><span class=\"pre\">self.request</span></code>) this includes the positional (<code class=\"docutils literal notranslate\"><span class=\"pre\">self.args</span></code>) and name-based\n(<code class=\"docutils literal notranslate\"><span class=\"pre\">self.kwargs</span></code>) arguments captured according to the URLconf.</p>\n<p>Here, we have a URLconf with a single captured group:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># urls.py</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.urls</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">path</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.views</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">PublisherBookListView</span>\n\n<span class=\"n\">urlpatterns</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"n\">path</span><span class=\"p\">(</span><span class=\"s2\">&quot;books/&lt;publisher&gt;/&quot;</span><span class=\"p\">,</span> <span class=\"n\">PublisherBookListView</span><span class=\"o\">.</span><span class=\"n\">as_view</span><span class=\"p\">()),</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>Next, we’ll write the <code class=\"docutils literal notranslate\"><span class=\"pre\">PublisherBookListView</span></code> view itself:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># views.py</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.shortcuts</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">get_object_or_404</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">ListView</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Book</span><span class=\"p\">,</span> <span class=\"n\">Publisher</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">PublisherBookListView</span><span class=\"p\">(</span><span class=\"n\">ListView</span><span class=\"p\">):</span>\n    <span class=\"n\">template_name</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;books/books_by_publisher.html&quot;</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_queryset</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">publisher</span> <span class=\"o\">=</span> <span class=\"n\">get_object_or_404</span><span class=\"p\">(</span><span class=\"n\">Publisher</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">kwargs</span><span class=\"p\">[</span><span class=\"s2\">&quot;publisher&quot;</span><span class=\"p\">])</span>\n        <span class=\"k\">return</span> <span class=\"n\">Book</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">filter</span><span class=\"p\">(</span><span class=\"n\">publisher</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">publisher</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Using <code class=\"docutils literal notranslate\"><span class=\"pre\">get_queryset</span></code> to add logic to the queryset selection is as convenient\nas it is powerful. For instance, if we wanted, we could use\n<code class=\"docutils literal notranslate\"><span class=\"pre\">self.request.user</span></code> to filter using the current user, or other more complex\nlogic.</p>\n<p>We can also add the publisher into the context at the same time, so we can\nuse it in the template:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># ...</span>\n\n\n<span class=\"k\">def</span><span class=\"w\"> </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>\n    <span class=\"c1\"># Call the base implementation first to get a context</span>\n    <span class=\"n\">context</span> <span class=\"o\">=</span> <span class=\"nb\">super</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>\n    <span class=\"c1\"># Add in the publisher</span>\n    <span class=\"n\">context</span><span class=\"p\">[</span><span class=\"s2\">&quot;publisher&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">publisher</span>\n    <span class=\"k\">return</span> <span class=\"n\">context</span>\n</code></pre></div>\n</section>\n<section id=\"performing-extra-work\">\n<span id=\"generic-views-extra-work\"></span><h3>Performing extra work<a class=\"heading-anchor\" href=\"#performing-extra-work\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>The last common pattern we’ll look at involves doing some extra work before\nor after calling the generic view.</p>\n<p>Imagine we had a <code class=\"docutils literal notranslate\"><span class=\"pre\">last_accessed</span></code> field on our <code class=\"docutils literal notranslate\"><span class=\"pre\">Author</span></code> model that we were\nusing to keep track of the last time anybody looked at that author:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"c1\"># models.py</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">models</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">Author</span><span class=\"p\">(</span><span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">Model</span><span class=\"p\">):</span>\n    <span class=\"n\">salutation</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">)</span>\n    <span class=\"n\">name</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">CharField</span><span class=\"p\">(</span><span class=\"n\">max_length</span><span class=\"o\">=</span><span class=\"mi\">200</span><span class=\"p\">)</span>\n    <span class=\"n\">email</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">EmailField</span><span class=\"p\">()</span>\n    <span class=\"n\">headshot</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">ImageField</span><span class=\"p\">(</span><span class=\"n\">upload_to</span><span class=\"o\">=</span><span class=\"s2\">&quot;author_headshots&quot;</span><span class=\"p\">)</span>\n    <span class=\"n\">last_accessed</span> <span class=\"o\">=</span> <span class=\"n\">models</span><span class=\"o\">.</span><span class=\"n\">DateTimeField</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>The generic <code class=\"docutils literal notranslate\"><span class=\"pre\">DetailView</span></code> class wouldn’t know anything about this field, but\nonce again we could write a custom view to keep that field updated.</p>\n<p>First, we’d need to add an author detail bit in the URLconf to point to a\ncustom view:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.urls</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">path</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.views</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">AuthorDetailView</span>\n\n<span class=\"n\">urlpatterns</span> <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"c1\"># ...</span>\n    <span class=\"n\">path</span><span class=\"p\">(</span><span class=\"s2\">&quot;authors/&lt;int:pk&gt;/&quot;</span><span class=\"p\">,</span> <span class=\"n\">AuthorDetailView</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=\"s2\">&quot;author-detail&quot;</span><span class=\"p\">),</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>Then we’d write our new view – <code class=\"docutils literal notranslate\"><span class=\"pre\">get_object</span></code> is the method that retrieves the\nobject – so we override it and wrap the call:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.utils</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">timezone</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views.generic</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">DetailView</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">books.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Author</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">AuthorDetailView</span><span class=\"p\">(</span><span class=\"n\">DetailView</span><span class=\"p\">):</span>\n    <span class=\"n\">queryset</span> <span class=\"o\">=</span> <span class=\"n\">Author</span><span class=\"o\">.</span><span class=\"n\">objects</span><span class=\"o\">.</span><span class=\"n\">all</span><span class=\"p\">()</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">get_object</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">obj</span> <span class=\"o\">=</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">get_object</span><span class=\"p\">()</span>\n        <span class=\"c1\"># Record the last accessed date</span>\n        <span class=\"n\">obj</span><span class=\"o\">.</span><span class=\"n\">last_accessed</span> <span class=\"o\">=</span> <span class=\"n\">timezone</span><span class=\"o\">.</span><span class=\"n\">now</span><span class=\"p\">()</span>\n        <span class=\"n\">obj</span><span class=\"o\">.</span><span class=\"n\">save</span><span class=\"p\">()</span>\n        <span class=\"k\">return</span> <span class=\"n\">obj</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>The URLconf here uses the named group <code class=\"docutils literal notranslate\"><span class=\"pre\">pk</span></code> - this name is the default\nname that <code class=\"docutils literal notranslate\"><span class=\"pre\">DetailView</span></code> uses to find the value of the primary key used to\nfilter the queryset.</p>\n<p>If you want to call the group something else, you can set\n<a class=\"reference internal\" href=\"/en/6.0/ref/class-based-views/mixins-single-object/#django.views.generic.detail.SingleObjectMixin.pk_url_kwarg\" title=\"django.views.generic.detail.SingleObjectMixin.pk_url_kwarg\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">pk_url_kwarg</span></code></a>\non the view.</p>\n</aside>\n</section>\n</section>","rootId":"built-in-class-based-generic-views","toc":[{"title":"Extending generic views","anchor":"extending-generic-views","children":[]},{"title":"Generic views of objects","anchor":"generic-views-of-objects","children":[{"title":"Making “friendly” template contexts","anchor":"making-friendly-template-contexts","children":[]},{"title":"Adding extra context","anchor":"adding-extra-context","children":[]},{"title":"Viewing subsets of objects","anchor":"viewing-subsets-of-objects","children":[]},{"title":"Dynamic filtering","anchor":"dynamic-filtering","children":[]},{"title":"Performing extra work","anchor":"performing-extra-work","children":[]}]}],"breadcrumbs":[{"docname":"topics/index","title":"Using Django","url":"/en/6.0/topics/"},{"docname":"topics/class-based-views/index","title":"Class-based views","url":"/en/6.0/topics/class-based-views/"}],"prev":{"docname":"topics/class-based-views/intro","title":"Introduction to class-based views","url":"/en/6.0/topics/class-based-views/intro/"},"next":{"docname":"topics/class-based-views/generic-editing","title":"Form handling with class-based views","url":"/en/6.0/topics/class-based-views/generic-editing/"},"formats":{"html":"/en/6.0/topics/class-based-views/generic-display/","markdown":"/en/6.0/topics/class-based-views/generic-display.md","json":"/en/6.0/topics/class-based-views/generic-display.json"},"source":"https://github.com/django/django/blob/stable/6.0.x/docs/topics/class-based-views/generic-display.txt","official":"https://docs.djangoproject.com/en/6.0/topics/class-based-views/generic-display/","inVersions":["dev","6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10","1.9","1.8"],"inLocales":["en","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}