{"title":"Inbyggda klassbaserade generiska vyer","version":"5.2","locale":"sv","docname":"topics/class-based-views/generic-display","url":"/sv/5.2/topics/class-based-views/generic-display/","canonical":"https://djangodocs.dev/sv/5.2/topics/class-based-views/generic-display/","summary":"Att skriva webbapplikationer kan vara enformigt, eftersom vi upprepar vissa mönster om och om igen.","html":"<h1>Inbyggda klassbaserade generiska vyer<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>Att skriva webbapplikationer kan vara enformigt, eftersom vi upprepar vissa mönster om och om igen. Django försöker ta bort en del av denna monotoni på modell- och mallnivåerna, men webbutvecklare upplever också denna tristess på vynivån.</p>\n<p>Djangos <em>generiska vyer</em> utvecklades för att lindra den smärtan. De tar vissa vanliga idiom och mönster som finns i vyutveckling och abstraherar dem så att du snabbt kan skriva vanliga vyer över data utan att behöva skriva för mycket kod.</p>\n<p>Vi kan känna igen vissa vanliga uppgifter, som att visa en lista med objekt, och skriva kod som visar en lista med <em>valfritt</em> objekt. Då kan modellen i fråga skickas som ett extra argument till URLconf.</p>\n<p>Django levereras med generiska vyer för att göra följande:</p>\n<ul class=\"simple\">\n<li><p>Visar list- och detaljsidor för ett enda objekt. Om vi skulle skapa en applikation för att hantera konferenser så skulle en <code class=\"docutils literal notranslate\">TalkListView</code> och en <code class=\"docutils literal notranslate\">RegisteredUserListView</code> vara exempel på listvyer. En enskild samtalssida är ett exempel på vad vi kallar en ”detalj”-vy.</p></li>\n<li><p>Presentera datumbaserade objekt på arkivsidor för år/månad/dag, tillhörande detalj- och ”senaste”-sidor.</p></li>\n<li><p>Tillåt användare att skapa, uppdatera och ta bort objekt - med eller utan behörighet.</p></li>\n</ul>\n<p>Sammantaget ger dessa vyer gränssnitt för att utföra de vanligaste uppgifterna som utvecklare stöter på.</p>\n<section id=\"extending-generic-views\">\n<h2>Förlängning av generiska vyer<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>Det råder ingen tvekan om att generiska vyer kan snabba upp utvecklingen avsevärt. I de flesta projekt kommer det dock ett ögonblick när de generiska vyerna inte längre räcker till. Den vanligaste frågan som ställs av nya Django-utvecklare är faktiskt hur man får generiska vyer att hantera ett bredare spektrum av situationer.</p>\n<p>Detta är en av anledningarna till att generiska vyer fick en ny design i 1.3-versionen - tidigare var de vyfunktioner med en förvirrande mängd alternativ; nu, i stället för att skicka in en stor mängd konfiguration i URLconf, är det rekommenderade sättet att utöka generiska vyer att underklassa dem och åsidosätta deras attribut eller metoder.</p>\n<p>Med detta sagt har generiska vyer en gräns. Om du har svårt att implementera din vy som en underklass till en generisk vy kan det vara mer effektivt att bara skriva den kod du behöver med hjälp av dina egna klassbaserade eller funktionella vyer.</p>\n<p>Fler exempel på generiska vyer finns i vissa tredjepartsapplikationer, eller så kan du skriva dina egna efter behov.</p>\n</section>\n<section id=\"generic-views-of-objects\">\n<h2>Generiska vyer av objekt<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=\"/sv/5.2/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\">TemplateView</code></a> är förvisso användbar, men Djangos generiska vyer briljerar verkligen när det gäller att presentera vyer av ditt databasinnehåll. Eftersom det är en så vanlig uppgift kommer Django med en handfull inbyggda generiska vyer för att hjälpa till att generera list- och detaljvyer av objekt.</p>\n<p>Låt oss börja med att titta på några exempel på hur man visar en lista med objekt eller ett enskilt objekt.</p>\n<p>Vi kommer att använda dessa modeller:</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=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Publisher</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">30</span><span class=\"p\">)</span>\n    address <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">50</span><span class=\"p\">)</span>\n    city <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">60</span><span class=\"p\">)</span>\n    state_province <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">30</span><span class=\"p\">)</span>\n    country <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">50</span><span class=\"p\">)</span>\n    website <span class=\"o\">=</span> models<span class=\"o\">.</span>URLField<span class=\"p\">()</span>\n\n    <span class=\"k\">class</span> <span class=\"nc\">Meta</span><span class=\"p\">:</span>\n        ordering <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=\"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>name\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Author</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    salutation <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">)</span>\n    name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">200</span><span class=\"p\">)</span>\n    email <span class=\"o\">=</span> models<span class=\"o\">.</span>EmailField<span class=\"p\">()</span>\n    headshot <span class=\"o\">=</span> models<span class=\"o\">.</span>ImageField<span class=\"p\">(</span>upload_to<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=\"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>name\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Book</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    title <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">100</span><span class=\"p\">)</span>\n    authors <span class=\"o\">=</span> models<span class=\"o\">.</span>ManyToManyField<span class=\"p\">(</span><span class=\"s2\">&quot;Author&quot;</span><span class=\"p\">)</span>\n    publisher <span class=\"o\">=</span> models<span class=\"o\">.</span>ForeignKey<span class=\"p\">(</span>Publisher<span class=\"p\">,</span> on_delete<span class=\"o\">=</span>models<span class=\"o\">.</span>CASCADE<span class=\"p\">)</span>\n    publication_date <span class=\"o\">=</span> models<span class=\"o\">.</span>DateField<span class=\"p\">()</span>\n</code></pre></div>\n<p>Nu måste vi definiera en vy:</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=\"nn\">django.views.generic</span> <span class=\"kn\">import</span> ListView\n<span class=\"kn\">from</span> <span class=\"nn\">books.models</span> <span class=\"kn\">import</span> Publisher\n\n\n<span class=\"k\">class</span> <span class=\"nc\">PublisherListView</span><span class=\"p\">(</span>ListView<span class=\"p\">):</span>\n    model <span class=\"o\">=</span> Publisher\n</code></pre></div>\n<p>Koppla slutligen den vyn till dina webbadresser:</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=\"nn\">django.urls</span> <span class=\"kn\">import</span> path\n<span class=\"kn\">from</span> <span class=\"nn\">books.views</span> <span class=\"kn\">import</span> PublisherListView\n\nurlpatterns <span class=\"o\">=</span> <span class=\"p\">[</span>\n    path<span class=\"p\">(</span><span class=\"s2\">&quot;publishers/&quot;</span><span class=\"p\">,</span> PublisherListView<span class=\"o\">.</span>as_view<span class=\"p\">()),</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>Det är all Python-kod vi behöver skriva. Vi behöver dock fortfarande skriva en mall. Vi kan uttryckligen berätta för vyn vilken mall som ska användas genom att lägga till ett <code class=\"docutils literal notranslate\">template_name</code>-attribut till vyn, men i avsaknad av en uttrycklig mall kommer Django att härleda en från objektets namn. I det här fallet kommer den härledda mallen att vara <code class=\"docutils literal notranslate\">&quot;books/publisher_list.html&quot;</code> - ”books”-delen kommer från namnet på appen som definierar modellen, medan ”publisher”-biten är den gemena versionen av modellens namn.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Observera</p>\n<p>Således, när (till exempel) alternativet <code class=\"docutils literal notranslate\">APP_DIRS</code> för en <code class=\"docutils literal notranslate\">DjangoTemplates</code> backend är inställt på True i <a class=\"reference internal\" href=\"/sv/5.2/ref/settings/#std-setting-TEMPLATES\"><code class=\"xref std std-setting docutils literal notranslate\">TEMPLATES</code></a>, kan en mallplats vara: /path/to/project/books/templates/books/publisher_list.html</p>\n</aside>\n<p>Denna mall kommer att renderas mot ett sammanhang som innehåller en variabel som heter <code class=\"docutils literal notranslate\">object_list</code> som innehåller alla utgivarobjekt. En mall kan se ut så här:</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>Det är verkligen allt det är. Alla de häftiga funktionerna i generiska vyer kommer från att ändra de attribut som ställts in på den generiska vyn. I <a class=\"reference internal\" href=\"/sv/5.2/ref/class-based-views/\"><span class=\"doc\">generic views reference</span></a> dokumenteras alla generiska vyer och deras alternativ i detalj; resten av det här dokumentet kommer att behandla några av de vanligaste sätten du kan anpassa och utöka generiska vyer.</p>\n<section id=\"making-friendly-template-contexts\">\n<h3>Skapa ”vänliga” mallkontexter<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>Du kanske har lagt märke till att vår mall för förlagslistan lagrar alla förlag i en variabel med namnet ”object_list”. Även om detta fungerar bra är det inte så ”vänligt” mot mallförfattare: de måste ”bara veta” att de har att göra med utgivare här.</p>\n<p>Tja, om du har att göra med ett modellobjekt är detta redan gjort åt dig. När du har att göra med ett objekt eller en queryset kan Django fylla i kontexten med den gemena versionen av modellklassens namn. Detta tillhandahålls utöver standardposten <code class=\"docutils literal notranslate\">object_list</code>, men innehåller exakt samma data, dvs. <code class=\"docutils literal notranslate\">publisher_list</code>.</p>\n<p>Om detta fortfarande inte är en bra matchning kan du manuellt ställa in namnet på kontextvariabeln. Attributet <code class=\"docutils literal notranslate\">context_object_name</code> på en generisk vy anger vilken kontextvariabel som ska användas:</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=\"nn\">django.views.generic</span> <span class=\"kn\">import</span> ListView\n<span class=\"kn\">from</span> <span class=\"nn\">books.models</span> <span class=\"kn\">import</span> Publisher\n\n\n<span class=\"k\">class</span> <span class=\"nc\">PublisherListView</span><span class=\"p\">(</span>ListView<span class=\"p\">):</span>\n    model <span class=\"o\">=</span> Publisher\n    context_object_name <span class=\"o\">=</span> <span class=\"s2\">&quot;my_favorite_publishers&quot;</span>\n</code></pre></div>\n<p>Att tillhandahålla ett användbart <code class=\"docutils literal notranslate\">context_object_name</code> är alltid en bra idé. Dina kollegor som designar mallar kommer att tacka dig.</p>\n</section>\n<section id=\"adding-extra-context\">\n<span id=\"id1\"></span><h3>Lägga till extra sammanhang<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>Ofta behöver du presentera lite extra information utöver den som tillhandahålls av den generiska vyn. Tänk till exempel på att visa en lista över alla böcker på varje förlags detaljsida. Den generiska vyn <a class=\"reference internal\" href=\"/sv/5.2/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\">DetailView</code></a> ger utgivaren till sammanhanget, men hur får vi ytterligare information i den mallen?</p>\n<p>Svaret är att underordna <a class=\"reference internal\" href=\"/sv/5.2/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\">DetailView</code></a> och tillhandahålla din egen implementering av metoden <code class=\"docutils literal notranslate\">get_context_data</code>. Standardimplementeringen lägger till objektet som visas i mallen, men du kan åsidosätta den för att skicka mer:</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=\"nn\">django.views.generic</span> <span class=\"kn\">import</span> DetailView\n<span class=\"kn\">from</span> <span class=\"nn\">books.models</span> <span class=\"kn\">import</span> Book<span class=\"p\">,</span> Publisher\n\n\n<span class=\"k\">class</span> <span class=\"nc\">PublisherDetailView</span><span class=\"p\">(</span>DetailView<span class=\"p\">):</span>\n    model <span class=\"o\">=</span> Publisher\n\n    <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>kwargs<span class=\"p\">):</span>\n        <span class=\"c1\"># Call the base implementation first to get a context</span>\n        context <span class=\"o\">=</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span>get_context_data<span class=\"p\">(</span><span class=\"o\">**</span>kwargs<span class=\"p\">)</span>\n        <span class=\"c1\"># Add in a QuerySet of all the books</span>\n        context<span class=\"p\">[</span><span class=\"s2\">&quot;book_list&quot;</span><span class=\"p\">]</span> <span class=\"o\">=</span> Book<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()</span>\n        <span class=\"k\">return</span> context\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Observera</p>\n<p>I allmänhet kommer <code class=\"docutils literal notranslate\">get_context_data</code> att sammanfoga kontextdata för alla överordnade klasser med den aktuella klassens data. För att bevara detta beteende i dina egna klasser där du vill ändra kontexten, bör du se till att anropa <code class=\"docutils literal notranslate\">get_context_data</code> på superklassen. När inga två klasser försöker definiera samma nyckel kommer detta att ge de förväntade resultaten. Men om någon klass försöker åsidosätta en nyckel efter att föräldraklasserna har ställt in den (efter anropet till super), måste alla barn till den klassen också uttryckligen ställa in den efter super om de vill vara säkra på att åsidosätta alla föräldrar. Om du har problem kan du se över metodupplösningsordningen för din vy.</p>\n<p>Ett annat övervägande är att kontextdata från klassbaserade generiska vyer kommer att åsidosätta data som tillhandahålls av kontextprocessorer; se <a class=\"reference internal\" href=\"/sv/5.2/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\">get_context_data()</code></a> för ett exempel.</p>\n</aside>\n</section>\n<section id=\"viewing-subsets-of-objects\">\n<span id=\"generic-views-list-subsets\"></span><h3>Visning av delmängder av objekt<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>Låt oss nu ta en närmare titt på argumentet <code class=\"docutils literal notranslate\">model</code> som vi har använt hela tiden. Argumentet <code class=\"docutils literal notranslate\">model</code>, som anger den databasmodell som vyn ska arbeta med, är tillgängligt för alla generiska vyer som arbetar med ett enda objekt eller en samling objekt. Argumentet <code class=\"docutils literal notranslate\">model</code> är dock inte det enda sättet att ange de objekt som vyn ska arbeta med - du kan också ange listan över objekt med argumentet <code class=\"docutils literal notranslate\">queryset</code>:</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=\"nn\">django.views.generic</span> <span class=\"kn\">import</span> DetailView\n<span class=\"kn\">from</span> <span class=\"nn\">books.models</span> <span class=\"kn\">import</span> Publisher\n\n\n<span class=\"k\">class</span> <span class=\"nc\">PublisherDetailView</span><span class=\"p\">(</span>DetailView<span class=\"p\">):</span>\n    context_object_name <span class=\"o\">=</span> <span class=\"s2\">&quot;publisher&quot;</span>\n    queryset <span class=\"o\">=</span> Publisher<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()</span>\n</code></pre></div>\n<p>Att ange <code class=\"docutils literal notranslate\">model = Publisher</code> är en förkortning för att säga <code class=\"docutils literal notranslate\">queryset = Publisher.objects.all()</code>. Men genom att använda <code class=\"docutils literal notranslate\">queryset</code> för att definiera en filtrerad lista över objekt kan du vara mer specifik om de objekt som kommer att synas i vyn (se <a class=\"reference internal\" href=\"/sv/5.2/topics/db/queries/\"><span class=\"doc\">Göra förfrågningar</span></a> för mer information om <a class=\"reference internal\" href=\"/sv/5.2/ref/models/querysets/#django.db.models.query.QuerySet\" title=\"django.db.models.query.QuerySet\"><code class=\"xref py py-class docutils literal notranslate\">QuerySet</code></a>-objekt, och se <a class=\"reference internal\" href=\"/sv/5.2/ref/class-based-views/\"><span class=\"doc\">class-based views reference</span></a> för fullständiga detaljer).</p>\n<p>För att ta ett exempel kanske vi vill sortera en lista med böcker efter utgivningsdatum, med den senaste först:</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=\"nn\">django.views.generic</span> <span class=\"kn\">import</span> ListView\n<span class=\"kn\">from</span> <span class=\"nn\">books.models</span> <span class=\"kn\">import</span> Book\n\n\n<span class=\"k\">class</span> <span class=\"nc\">BookListView</span><span class=\"p\">(</span>ListView<span class=\"p\">):</span>\n    queryset <span class=\"o\">=</span> Book<span class=\"o\">.</span>objects<span class=\"o\">.</span>order_by<span class=\"p\">(</span><span class=\"s2\">&quot;-publication_date&quot;</span><span class=\"p\">)</span>\n    context_object_name <span class=\"o\">=</span> <span class=\"s2\">&quot;book_list&quot;</span>\n</code></pre></div>\n<p>Det är ett ganska minimalt exempel, men det illustrerar idén på ett bra sätt. Du vill vanligtvis göra mer än att bara ordna om objekt. Om du vill presentera en lista över böcker från ett visst förlag kan du använda samma teknik:</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=\"nn\">django.views.generic</span> <span class=\"kn\">import</span> ListView\n<span class=\"kn\">from</span> <span class=\"nn\">books.models</span> <span class=\"kn\">import</span> Book\n\n\n<span class=\"k\">class</span> <span class=\"nc\">AcmeBookListView</span><span class=\"p\">(</span>ListView<span class=\"p\">):</span>\n    context_object_name <span class=\"o\">=</span> <span class=\"s2\">&quot;book_list&quot;</span>\n    queryset <span class=\"o\">=</span> Book<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>publisher__name<span class=\"o\">=</span><span class=\"s2\">&quot;ACME Publishing&quot;</span><span class=\"p\">)</span>\n    template_name <span class=\"o\">=</span> <span class=\"s2\">&quot;books/acme_list.html&quot;</span>\n</code></pre></div>\n<p>Lägg märke till att vi tillsammans med ett filtrerat <code class=\"docutils literal notranslate\">queryset</code> också använder ett anpassat mallnamn. Om vi inte gjorde det skulle den generiska vyn använda samma mall som ”vanilj”-objektlistan, vilket kanske inte är vad vi vill.</p>\n<p>Observera också att det här inte är ett särskilt elegant sätt att göra förlagsspecifika böcker. Om vi vill lägga till ytterligare en förlagssida skulle vi behöva ytterligare en handfull rader i URLconf, och mer än ett fåtal förlag skulle bli orimliga. Vi tar itu med det här problemet i nästa avsnitt.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Observera</p>\n<p>Om du får en 404 när du begär <code class=\"docutils literal notranslate\">/books/acme/</code>, kontrollera att du faktiskt har ett förlag med namnet ’ACME Publishing’.  Generiska vyer har en <code class=\"docutils literal notranslate\">allow_empty</code> parameter för detta fall.  Se <a class=\"reference internal\" href=\"/sv/5.2/ref/class-based-views/\"><span class=\"doc\">class-based-views reference</span></a> för mer information.</p>\n</aside>\n</section>\n<section id=\"dynamic-filtering\">\n<h3>Dynamisk filtrering<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>Ett annat vanligt behov är att filtrera ner objekten som ges på en listsida efter någon nyckel i URL:en. Tidigare hårdkodade vi förlagsnamnet i URLconf, men tänk om vi ville skriva en vy som visade alla böcker från ett godtyckligt förlag?</p>\n<p>Praktiskt nog har <code class=\"docutils literal notranslate\">ListView</code> en <a class=\"reference internal\" href=\"/sv/5.2/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\">get_queryset()</code></a>-metod som vi kan åsidosätta. Som standard returnerar den värdet på attributet <code class=\"docutils literal notranslate\">queryset</code>, men vi kan använda det för att lägga till mer logik.</p>\n<p>Den viktigaste delen för att få detta att fungera är att när klassbaserade vyer anropas lagras olika användbara saker på <code class=\"docutils literal notranslate\">self</code>; förutom begäran (<code class=\"docutils literal notranslate\">self.request</code>) inkluderar detta de positionella (<code class=\"docutils literal notranslate\">self.args</code>) och namnbaserade (<code class=\"docutils literal notranslate\">self.kwargs</code>) argumenten som fångas enligt URLconf.</p>\n<p>Här har vi en URLconf med en enda fångad grupp:</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=\"nn\">django.urls</span> <span class=\"kn\">import</span> path\n<span class=\"kn\">from</span> <span class=\"nn\">books.views</span> <span class=\"kn\">import</span> PublisherBookListView\n\nurlpatterns <span class=\"o\">=</span> <span class=\"p\">[</span>\n    path<span class=\"p\">(</span><span class=\"s2\">&quot;books/&lt;publisher&gt;/&quot;</span><span class=\"p\">,</span> PublisherBookListView<span class=\"o\">.</span>as_view<span class=\"p\">()),</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<p>Nu ska vi skriva själva vyn <code class=\"docutils literal notranslate\">PublisherBookListView</code>:</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=\"nn\">django.shortcuts</span> <span class=\"kn\">import</span> get_object_or_404\n<span class=\"kn\">from</span> <span class=\"nn\">django.views.generic</span> <span class=\"kn\">import</span> ListView\n<span class=\"kn\">from</span> <span class=\"nn\">books.models</span> <span class=\"kn\">import</span> Book<span class=\"p\">,</span> Publisher\n\n\n<span class=\"k\">class</span> <span class=\"nc\">PublisherBookListView</span><span class=\"p\">(</span>ListView<span class=\"p\">):</span>\n    template_name <span class=\"o\">=</span> <span class=\"s2\">&quot;books/books_by_publisher.html&quot;</span>\n\n    <span class=\"k\">def</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>publisher <span class=\"o\">=</span> get_object_or_404<span class=\"p\">(</span>Publisher<span class=\"p\">,</span> name<span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span>kwargs<span class=\"p\">[</span><span class=\"s2\">&quot;publisher&quot;</span><span class=\"p\">])</span>\n        <span class=\"k\">return</span> Book<span class=\"o\">.</span>objects<span class=\"o\">.</span>filter<span class=\"p\">(</span>publisher<span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span>publisher<span class=\"p\">)</span>\n</code></pre></div>\n<p>Att använda <code class=\"docutils literal notranslate\">get_queryset</code> för att lägga till logik i queryset-urvalet är lika bekvämt som det är kraftfullt. Om vi till exempel vill kan vi använda <code class=\"docutils literal notranslate\">self.request.user</code> för att filtrera med hjälp av den aktuella användaren eller annan mer komplex logik.</p>\n<p>Vi kan också lägga till utgivaren i sammanhanget samtidigt, så att vi kan använda den i mallen:</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=\"nf\">get_context_data</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">):</span>\n    <span class=\"c1\"># Call the base implementation first to get a context</span>\n    context <span class=\"o\">=</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span>get_context_data<span class=\"p\">(</span><span class=\"o\">**</span>kwargs<span class=\"p\">)</span>\n    <span class=\"c1\"># Add in the publisher</span>\n    context<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>publisher\n    <span class=\"k\">return</span> context\n</code></pre></div>\n</section>\n<section id=\"performing-extra-work\">\n<span id=\"generic-views-extra-work\"></span><h3>Utföra extra arbete<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>Det sista vanliga mönstret vi ska titta på innebär att man gör lite extra arbete före eller efter anropet av den generiska vyn.</p>\n<p>Tänk dig att vi hade ett <code class=\"docutils literal notranslate\">last_accessed</code> fält på vår <code class=\"docutils literal notranslate\">Author</code> modell som vi använde för att hålla reda på den sista gången någon tittade på den författaren:</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=\"nn\">django.db</span> <span class=\"kn\">import</span> models\n\n\n<span class=\"k\">class</span> <span class=\"nc\">Author</span><span class=\"p\">(</span>models<span class=\"o\">.</span>Model<span class=\"p\">):</span>\n    salutation <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">10</span><span class=\"p\">)</span>\n    name <span class=\"o\">=</span> models<span class=\"o\">.</span>CharField<span class=\"p\">(</span>max_length<span class=\"o\">=</span><span class=\"mi\">200</span><span class=\"p\">)</span>\n    email <span class=\"o\">=</span> models<span class=\"o\">.</span>EmailField<span class=\"p\">()</span>\n    headshot <span class=\"o\">=</span> models<span class=\"o\">.</span>ImageField<span class=\"p\">(</span>upload_to<span class=\"o\">=</span><span class=\"s2\">&quot;author_headshots&quot;</span><span class=\"p\">)</span>\n    last_accessed <span class=\"o\">=</span> models<span class=\"o\">.</span>DateTimeField<span class=\"p\">()</span>\n</code></pre></div>\n<p>Den generiska klassen <code class=\"docutils literal notranslate\">DetailView</code> vet ingenting om det här fältet, men återigen kan vi skriva en anpassad vy för att hålla fältet uppdaterat.</p>\n<p>Först måste vi lägga till en författardetaljbit i URLconf för att peka på en anpassad vy:</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=\"nn\">django.urls</span> <span class=\"kn\">import</span> path\n<span class=\"kn\">from</span> <span class=\"nn\">books.views</span> <span class=\"kn\">import</span> AuthorDetailView\n\nurlpatterns <span class=\"o\">=</span> <span class=\"p\">[</span>\n    <span class=\"c1\"># ...</span>\n    path<span class=\"p\">(</span><span class=\"s2\">&quot;authors/&lt;int:pk&gt;/&quot;</span><span class=\"p\">,</span> AuthorDetailView<span class=\"o\">.</span>as_view<span class=\"p\">(),</span> name<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>Sedan skriver vi vår nya vy – <code class=\"docutils literal notranslate\">get_object</code> är den metod som hämtar objektet – så vi åsidosätter den och omsluter anropet:</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=\"nn\">django.utils</span> <span class=\"kn\">import</span> timezone\n<span class=\"kn\">from</span> <span class=\"nn\">django.views.generic</span> <span class=\"kn\">import</span> DetailView\n<span class=\"kn\">from</span> <span class=\"nn\">books.models</span> <span class=\"kn\">import</span> Author\n\n\n<span class=\"k\">class</span> <span class=\"nc\">AuthorDetailView</span><span class=\"p\">(</span>DetailView<span class=\"p\">):</span>\n    queryset <span class=\"o\">=</span> Author<span class=\"o\">.</span>objects<span class=\"o\">.</span>all<span class=\"p\">()</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">get_object</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        obj <span class=\"o\">=</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span>get_object<span class=\"p\">()</span>\n        <span class=\"c1\"># Record the last accessed date</span>\n        obj<span class=\"o\">.</span>last_accessed <span class=\"o\">=</span> timezone<span class=\"o\">.</span>now<span class=\"p\">()</span>\n        obj<span class=\"o\">.</span>save<span class=\"p\">()</span>\n        <span class=\"k\">return</span> obj\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Observera</p>\n<p>URLconf här använder den namngivna gruppen <code class=\"docutils literal notranslate\">pk</code> - detta namn är det standardnamn som <code class=\"docutils literal notranslate\">DetailView</code> använder för att hitta värdet på den primära nyckel som används för att filtrera frågeuppsättningen.</p>\n<p>Om du vill kalla gruppen något annat kan du ställa in <a class=\"reference internal\" href=\"/sv/5.2/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\">pk_url_kwarg</code></a> på vyn.</p>\n</aside>\n</section>\n</section>","rootId":"built-in-class-based-generic-views","toc":[{"title":"Förlängning av generiska vyer","anchor":"extending-generic-views","children":[]},{"title":"Generiska vyer av objekt","anchor":"generic-views-of-objects","children":[{"title":"Skapa ”vänliga” mallkontexter","anchor":"making-friendly-template-contexts","children":[]},{"title":"Lägga till extra sammanhang","anchor":"adding-extra-context","children":[]},{"title":"Visning av delmängder av objekt","anchor":"viewing-subsets-of-objects","children":[]},{"title":"Dynamisk filtrering","anchor":"dynamic-filtering","children":[]},{"title":"Utföra extra arbete","anchor":"performing-extra-work","children":[]}]}],"breadcrumbs":[{"docname":"topics/index","title":"Använda Django","url":"/sv/5.2/topics/"},{"docname":"topics/class-based-views/index","title":"Klassbaserade åsikter","url":"/sv/5.2/topics/class-based-views/"}],"prev":{"docname":"topics/class-based-views/intro","title":"Introduktion till klassbaserade vyer","url":"/sv/5.2/topics/class-based-views/intro/"},"next":{"docname":"topics/class-based-views/generic-editing","title":"Formulärhantering med klassbaserade vyer","url":"/sv/5.2/topics/class-based-views/generic-editing/"},"formats":{"html":"/sv/5.2/topics/class-based-views/generic-display/","markdown":"/sv/5.2/topics/class-based-views/generic-display.md","json":"/sv/5.2/topics/class-based-views/generic-display.json"},"source":"https://github.com/django/django/blob/stable/5.2.x/docs/topics/class-based-views/generic-display.txt","official":"https://docs.djangoproject.com/sv/5.2/topics/class-based-views/generic-display/","inVersions":["6.1","6.0","5.2"],"inLocales":["en","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}