{"title":"Introduktion till klassbaserade vyer","version":"6.0","locale":"sv","docname":"topics/class-based-views/intro","url":"/sv/6.0/topics/class-based-views/intro/","canonical":"https://djangodocs.dev/sv/6.0/topics/class-based-views/intro/","summary":"Klassbaserade vyer är ett alternativt sätt att implementera vyer som Python-objekt i stället för funktioner. De ersätter inte funktionsbaserade vyer, men har vissa…","html":"<h1>Introduktion till klassbaserade vyer<a class=\"heading-anchor\" href=\"#introduction-to-class-based-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Klassbaserade vyer är ett alternativt sätt att implementera vyer som Python-objekt i stället för funktioner. De ersätter inte funktionsbaserade vyer, men har vissa skillnader och fördelar jämfört med funktionsbaserade vyer:</p>\n<ul class=\"simple\">\n<li><p>Organisering av kod relaterad till specifika HTTP-metoder (<code class=\"docutils literal notranslate\"><span class=\"pre\">GET</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code>, etc.) kan hanteras med separata metoder istället för villkorlig förgrening.</p></li>\n<li><p>Objektorienterade tekniker som mixins (multiple inheritance) kan användas för att dela upp koden i återanvändbara komponenter.</p></li>\n</ul>\n<section id=\"the-relationship-and-history-of-generic-views-class-based-views-and-class-based-generic-views\">\n<h2>Förhållandet mellan och historien bakom generiska vyer, klassbaserade vyer och klassbaserade generiska vyer<a class=\"heading-anchor\" href=\"#the-relationship-and-history-of-generic-views-class-based-views-and-class-based-generic-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>I början fanns det bara view-funktionskontraktet, Django skickade din funktion en <a class=\"reference internal\" href=\"/sv/6.0/ref/request-response/#django.http.HttpRequest\" title=\"django.http.HttpRequest\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpRequest</span></code></a> och förväntade sig tillbaka en <a class=\"reference internal\" href=\"/sv/6.0/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a>. Detta var omfattningen av vad Django tillhandahöll.</p>\n<p>Redan tidigt insåg man att det fanns vanliga idiom och mönster i utvecklingen av vyer. Funktionsbaserade generiska vyer introducerades för att abstrahera dessa mönster och underlätta utvecklingen av vyer för de vanligaste fallen.</p>\n<p>Problemet med funktionsbaserade generiska vyer är att de visserligen täcker de enkla fallen väl, men att det inte finns något sätt att utöka eller anpassa dem utöver vissa konfigurationsalternativ, vilket begränsar deras användbarhet i många verkliga tillämpningar.</p>\n<p>Klassbaserade generiska vyer skapades med samma mål som funktionsbaserade generiska vyer, att göra det enklare att utveckla vyer. Det sätt på vilket lösningen implementeras, genom användning av mixins, ger dock en verktygslåda som resulterar i att klassbaserade generiska vyer är mer utbyggbara och flexibla än sina funktionsbaserade motsvarigheter.</p>\n<p>Om du tidigare har provat funktionsbaserade generiska vyer och funnit dem otillräckliga, bör du inte se klassbaserade generiska vyer som en klassbaserad motsvarighet, utan snarare som ett nytt sätt att lösa de ursprungliga problem som generiska vyer var avsedda att lösa.</p>\n<p>Verktygslådan med basklasser och mixins som Django använder för att bygga klassbaserade generiska vyer är byggd för maximal flexibilitet och har därför många hooks i form av standardmetoderealiseringar och attribut som du troligen inte kommer att bry dig om i de enklaste användningsfallen. I stället för att begränsa dig till ett klassbaserat attribut för <code class=\"docutils literal notranslate\"><span class=\"pre\">form_class</span></code> använder implementeringen till exempel en <code class=\"docutils literal notranslate\"><span class=\"pre\">get_form</span></code>-metod, som anropar en <code class=\"docutils literal notranslate\"><span class=\"pre\">get_form_class</span></code>-metod, som i sin standardimplementering returnerar klassens <code class=\"docutils literal notranslate\"><span class=\"pre\">form_class</span></code>-attribut. Detta ger dig flera alternativ för att ange vilket formulär som ska användas, från ett attribut till en helt dynamisk, anropsbar hook. Dessa alternativ verkar lägga till ihålig komplexitet för enkla situationer, men utan dem skulle mer avancerade mönster vara begränsade.</p>\n</section>\n<section id=\"using-class-based-views\">\n<h2>Använda klassbaserade vyer<a class=\"heading-anchor\" href=\"#using-class-based-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>I grunden innebär en klassbaserad vy att du kan svara på olika HTTP-begärandemetoder med olika klassinstansmetoder, istället för med villkorligt förgrenad kod i en enda vyfunktion.</p>\n<p>Så där koden för att hantera HTTP <code class=\"docutils literal notranslate\"><span class=\"pre\">GET</span></code> i en vyfunktion skulle se ut ungefär som:</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.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponse</span>\n\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_view</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"k\">if</span> <span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">method</span> <span class=\"o\">==</span> <span class=\"s2\">&quot;GET&quot;</span><span class=\"p\">:</span>\n        <span class=\"c1\"># &lt;view logic&gt;</span>\n        <span class=\"k\">return</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"s2\">&quot;result&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>I en klassbaserad vy skulle detta bli:</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.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponse</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">View</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyView</span><span class=\"p\">(</span><span class=\"n\">View</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </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>\n        <span class=\"c1\"># &lt;view logic&gt;</span>\n        <span class=\"k\">return</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"s2\">&quot;result&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Eftersom Djangos URL-resolver förväntar sig att skicka begäran och tillhörande argument till en anropbar funktion, inte en klass, har klassbaserade vyer en klassmetod <a class=\"reference internal\" href=\"/sv/6.0/ref/class-based-views/base/#django.views.generic.base.View.as_view\" title=\"django.views.generic.base.View.as_view\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_view()</span></code></a> som returnerar en funktion som kan anropas när en begäran kommer för en URL som matchar det associerade mönstret. Funktionen skapar en instans av klassen, anropar <a class=\"reference internal\" href=\"/sv/6.0/ref/class-based-views/base/#django.views.generic.base.View.setup\" title=\"django.views.generic.base.View.setup\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">setup()</span></code></a> för att initialisera dess attribut och anropar sedan dess <a class=\"reference internal\" href=\"/sv/6.0/ref/class-based-views/base/#django.views.generic.base.View.dispatch\" title=\"django.views.generic.base.View.dispatch\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">dispatch()</span></code></a>-metod. <code class=\"docutils literal notranslate\"><span class=\"pre\">dispatch</span></code> tittar på begäran för att avgöra om det är en <code class=\"docutils literal notranslate\"><span class=\"pre\">GET</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">POST</span></code>, etc, och vidarebefordrar begäran till en matchande metod om en sådan är definierad, eller ger upphov till <a class=\"reference internal\" href=\"/sv/6.0/ref/request-response/#django.http.HttpResponseNotAllowed\" title=\"django.http.HttpResponseNotAllowed\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponseNotAllowed</span></code></a> om inte:</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\">myapp.views</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">MyView</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;about/&quot;</span><span class=\"p\">,</span> <span class=\"n\">MyView</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>Det är värt att notera att det som din metod returnerar är identiskt med det som du returnerar från en funktionsbaserad vy, nämligen någon form av <a class=\"reference internal\" href=\"/sv/6.0/ref/request-response/#django.http.HttpResponse\" title=\"django.http.HttpResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">HttpResponse</span></code></a>. Detta innebär att <a class=\"reference internal\" href=\"/sv/6.0/topics/http/shortcuts/\"><span class=\"doc\">http shortcuts</span></a> eller <a class=\"reference internal\" href=\"/sv/6.0/ref/template-response/#django.template.response.TemplateResponse\" title=\"django.template.response.TemplateResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateResponse</span></code></a>-objekt är giltiga att använda i en klassbaserad vy.</p>\n<p>Även om en minimal klassbaserad vy inte kräver några klassattribut för att utföra sitt jobb, är klassattribut användbara i många klassbaserade designer, och det finns två sätt att konfigurera eller ange klassattribut.</p>\n<p>Den första är det vanliga Python-sättet att subklassa och åsidosätta attribut och metoder i subklassen. Så om din överordnade klass hade ett attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">greeting</span></code> så här:</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.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponse</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">View</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">GreetingView</span><span class=\"p\">(</span><span class=\"n\">View</span><span class=\"p\">):</span>\n    <span class=\"n\">greeting</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;Good Day&quot;</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </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>\n        <span class=\"k\">return</span> <span class=\"n\">HttpResponse</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">greeting</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Du kan åsidosätta det i en subklass:</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=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MorningGreetingView</span><span class=\"p\">(</span><span class=\"n\">GreetingView</span><span class=\"p\">):</span>\n    <span class=\"n\">greeting</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;Morning to ya&quot;</span>\n</code></pre></div>\n<p>Ett annat alternativ är att konfigurera klassattribut som nyckelordsargument till <a class=\"reference internal\" href=\"/sv/6.0/ref/class-based-views/base/#django.views.generic.base.View.as_view\" title=\"django.views.generic.base.View.as_view\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_view()</span></code></a>-anropet i URLconf:</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=\"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;about/&quot;</span><span class=\"p\">,</span> <span class=\"n\">GreetingView</span><span class=\"o\">.</span><span class=\"n\">as_view</span><span class=\"p\">(</span><span class=\"n\">greeting</span><span class=\"o\">=</span><span class=\"s2\">&quot;G&#39;day&quot;</span><span class=\"p\">)),</span>\n<span class=\"p\">]</span>\n</code></pre></div>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Observera</p>\n<p>Medan din klass instansieras för varje begäran som skickas till den, konfigureras klassattribut som anges via <a class=\"reference internal\" href=\"/sv/6.0/ref/class-based-views/base/#django.views.generic.base.View.as_view\" title=\"django.views.generic.base.View.as_view\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_view()</span></code></a>-ingångspunkten endast en gång vid den tidpunkt då dina webbadresser importeras.</p>\n</aside>\n</section>\n<section id=\"using-mixins\">\n<h2>Använda mixins<a class=\"heading-anchor\" href=\"#using-mixins\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Mixins är en form av multipel nedärvning där beteenden och attribut från flera överordnade klasser kan kombineras.</p>\n<p>Till exempel finns det i de generiska klassbaserade vyerna en mixin som heter <a class=\"reference internal\" href=\"/sv/6.0/ref/class-based-views/mixins-simple/#django.views.generic.base.TemplateResponseMixin\" title=\"django.views.generic.base.TemplateResponseMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateResponseMixin</span></code></a> vars primära syfte är att definiera metoden <a class=\"reference internal\" href=\"/sv/6.0/ref/class-based-views/mixins-simple/#django.views.generic.base.TemplateResponseMixin.render_to_response\" title=\"django.views.generic.base.TemplateResponseMixin.render_to_response\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">render_to_response()</span></code></a>. I kombination med beteendet i basklassen <a class=\"reference internal\" href=\"/sv/6.0/ref/class-based-views/base/#django.views.generic.base.View\" title=\"django.views.generic.base.View\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">View</span></code></a> blir resultatet en klass av typen <a class=\"reference internal\" href=\"/sv/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> som skickar förfrågningar till lämpliga matchningsmetoder (ett beteende som definieras i basklassen <code class=\"docutils literal notranslate\"><span class=\"pre\">View</span></code>) och som har en <a class=\"reference internal\" href=\"/sv/6.0/ref/class-based-views/mixins-simple/#django.views.generic.base.TemplateResponseMixin.render_to_response\" title=\"django.views.generic.base.TemplateResponseMixin.render_to_response\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">render_to_response()</span></code></a>-metoden som använder ett <a class=\"reference internal\" href=\"/sv/6.0/ref/class-based-views/mixins-simple/#django.views.generic.base.TemplateResponseMixin.template_name\" title=\"django.views.generic.base.TemplateResponseMixin.template_name\"><code class=\"xref py py-attr docutils literal notranslate\"><span class=\"pre\">template_name</span></code></a>-attribut för att returnera ett <a class=\"reference internal\" href=\"/sv/6.0/ref/template-response/#django.template.response.TemplateResponse\" title=\"django.template.response.TemplateResponse\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">TemplateResponse</span></code></a>-objekt (ett beteende som definieras i <code class=\"docutils literal notranslate\"><span class=\"pre\">TemplateResponseMixin</span></code>).</p>\n<p>Mixins är ett utmärkt sätt att återanvända kod i flera klasser, men de har ett visst pris. Ju mer din kod är utspridd bland mixins, desto svårare blir det att läsa en underordnad klass och veta exakt vad den gör, och desto svårare blir det att veta vilka metoder från vilka mixins som ska åsidosättas om du subklassar något som har ett djupt arvsträd.</p>\n<p>Observera också att du bara kan ärva från en generisk vy - det vill säga, bara en föräldraklass kan ärva från <a class=\"reference internal\" href=\"/sv/6.0/ref/class-based-views/base/#django.views.generic.base.View\" title=\"django.views.generic.base.View\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">View</span></code></a> och resten (om någon) bör vara mixins. Att försöka ärva från mer än en klass som ärver från <code class=\"docutils literal notranslate\"><span class=\"pre\">View</span></code> - till exempel att försöka använda ett formulär högst upp i en lista och kombinera <a class=\"reference internal\" href=\"/sv/6.0/ref/class-based-views/mixins-editing/#django.views.generic.edit.ProcessFormView\" title=\"django.views.generic.edit.ProcessFormView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ProcessFormView</span></code></a> och <a class=\"reference internal\" href=\"/sv/6.0/ref/class-based-views/generic-display/#django.views.generic.list.ListView\" title=\"django.views.generic.list.ListView\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ListView</span></code></a> - kommer inte att fungera som förväntat.</p>\n</section>\n<section id=\"handling-forms-with-class-based-views\">\n<h2>Hantera formulär med klassbaserade vyer<a class=\"heading-anchor\" href=\"#handling-forms-with-class-based-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>En grundläggande funktionsbaserad vy som hanterar formulär kan se ut ungefär så här:</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.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponseRedirect</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\">render</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">MyForm</span>\n\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">myview</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">):</span>\n    <span class=\"k\">if</span> <span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">method</span> <span class=\"o\">==</span> <span class=\"s2\">&quot;POST&quot;</span><span class=\"p\">:</span>\n        <span class=\"n\">form</span> <span class=\"o\">=</span> <span class=\"n\">MyForm</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">POST</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">():</span>\n            <span class=\"c1\"># &lt;process form cleaned data&gt;</span>\n            <span class=\"k\">return</span> <span class=\"n\">HttpResponseRedirect</span><span class=\"p\">(</span><span class=\"s2\">&quot;/success/&quot;</span><span class=\"p\">)</span>\n    <span class=\"k\">else</span><span class=\"p\">:</span>\n        <span class=\"n\">form</span> <span class=\"o\">=</span> <span class=\"n\">MyForm</span><span class=\"p\">(</span><span class=\"n\">initial</span><span class=\"o\">=</span><span class=\"p\">{</span><span class=\"s2\">&quot;key&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;value&quot;</span><span class=\"p\">})</span>\n\n    <span class=\"k\">return</span> <span class=\"n\">render</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"s2\">&quot;form_template.html&quot;</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s2\">&quot;form&quot;</span><span class=\"p\">:</span> <span class=\"n\">form</span><span class=\"p\">})</span>\n</code></pre></div>\n<p>En liknande klassbaserad vy kan se ut på följande sätt:</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.http</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">HttpResponseRedirect</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\">render</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.views</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">View</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.forms</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">MyForm</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyFormView</span><span class=\"p\">(</span><span class=\"n\">View</span><span class=\"p\">):</span>\n    <span class=\"n\">form_class</span> <span class=\"o\">=</span> <span class=\"n\">MyForm</span>\n    <span class=\"n\">initial</span> <span class=\"o\">=</span> <span class=\"p\">{</span><span class=\"s2\">&quot;key&quot;</span><span class=\"p\">:</span> <span class=\"s2\">&quot;value&quot;</span><span class=\"p\">}</span>\n    <span class=\"n\">template_name</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;form_template.html&quot;</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </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>\n        <span class=\"n\">form</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">form_class</span><span class=\"p\">(</span><span class=\"n\">initial</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">initial</span><span class=\"p\">)</span>\n        <span class=\"k\">return</span> <span class=\"n\">render</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">template_name</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s2\">&quot;form&quot;</span><span class=\"p\">:</span> <span class=\"n\">form</span><span class=\"p\">})</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </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>\n        <span class=\"n\">form</span> <span class=\"o\">=</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">form_class</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"o\">.</span><span class=\"n\">POST</span><span class=\"p\">)</span>\n        <span class=\"k\">if</span> <span class=\"n\">form</span><span class=\"o\">.</span><span class=\"n\">is_valid</span><span class=\"p\">():</span>\n            <span class=\"c1\"># &lt;process form cleaned data&gt;</span>\n            <span class=\"k\">return</span> <span class=\"n\">HttpResponseRedirect</span><span class=\"p\">(</span><span class=\"s2\">&quot;/success/&quot;</span><span class=\"p\">)</span>\n\n        <span class=\"k\">return</span> <span class=\"n\">render</span><span class=\"p\">(</span><span class=\"n\">request</span><span class=\"p\">,</span> <span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"n\">template_name</span><span class=\"p\">,</span> <span class=\"p\">{</span><span class=\"s2\">&quot;form&quot;</span><span class=\"p\">:</span> <span class=\"n\">form</span><span class=\"p\">})</span>\n</code></pre></div>\n<p>Detta är ett minimifall, men du kan se att du då skulle ha möjlighet att anpassa den här vyn genom att åsidosätta något av klassattributen, t.ex. <code class=\"docutils literal notranslate\"><span class=\"pre\">form_class</span></code>, via URLconf-konfiguration, eller subklassa och åsidosätta en eller flera av metoderna (eller båda!).</p>\n</section>\n<section id=\"decorating-class-based-views\">\n<h2>Dekorera klassbaserade vyer<a class=\"heading-anchor\" href=\"#decorating-class-based-views\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Utökningen av klassbaserade vyer är inte begränsad till att använda mixins. Du kan också använda dekoratorer. Eftersom klassbaserade vyer inte är funktioner fungerar dekorering av dem olika beroende på om du använder <code class=\"docutils literal notranslate\"><span class=\"pre\">as_view()</span></code> eller skapar en subklass.</p>\n<section id=\"decorating-in-urlconf\">\n<h3>Dekorera i URLconf<a class=\"heading-anchor\" href=\"#decorating-in-urlconf\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Du kan justera klassbaserade vyer genom att dekorera resultatet av <a class=\"reference internal\" href=\"/sv/6.0/ref/class-based-views/base/#django.views.generic.base.View.as_view\" title=\"django.views.generic.base.View.as_view\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">as_view()</span></code></a>-metoden. Det enklaste stället att göra detta är i URLconf där du distribuerar din 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=\"w\"> </span><span class=\"nn\">django.contrib.auth.decorators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">login_required</span><span class=\"p\">,</span> <span class=\"n\">permission_required</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\">TemplateView</span>\n\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.views</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">VoteView</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;about/&quot;</span><span class=\"p\">,</span> <span class=\"n\">login_required</span><span class=\"p\">(</span><span class=\"n\">TemplateView</span><span class=\"o\">.</span><span class=\"n\">as_view</span><span class=\"p\">(</span><span class=\"n\">template_name</span><span class=\"o\">=</span><span class=\"s2\">&quot;secret.html&quot;</span><span class=\"p\">))),</span>\n    <span class=\"n\">path</span><span class=\"p\">(</span><span class=\"s2\">&quot;vote/&quot;</span><span class=\"p\">,</span> <span class=\"n\">permission_required</span><span class=\"p\">(</span><span class=\"s2\">&quot;polls.can_vote&quot;</span><span class=\"p\">)(</span><span class=\"n\">VoteView</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>Denna metod tillämpar dekoratorn per instans. Om du vill att varje instans av en vy ska dekoreras måste du använda ett annat tillvägagångssätt.</p>\n</section>\n<section id=\"decorating-the-class\">\n<span id=\"id1\"></span><h3>Inredning av klassen<a class=\"heading-anchor\" href=\"#decorating-the-class\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>För att dekorera varje instans av en klassbaserad vy måste du dekorera själva klassdefinitionen. För att göra detta tillämpar du dekoratorn på klassens <a class=\"reference internal\" href=\"/sv/6.0/ref/class-based-views/base/#django.views.generic.base.View.dispatch\" title=\"django.views.generic.base.View.dispatch\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">dispatch()</span></code></a>-metod.</p>\n<p>En metod i en klass är inte riktigt samma sak som en fristående funktion, så du kan inte bara använda en funktionsdekorator på metoden - du måste först omvandla den till en metoddekorator. Dekoratorn <code class=\"docutils literal notranslate\"><span class=\"pre\">method_decorator</span></code> omvandlar en funktionsdekorator till en metoddekorator så att den kan användas på en instansmetod. Till exempel:</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.contrib.auth.decorators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">login_required</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.utils.decorators</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">method_decorator</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\">TemplateView</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">ProtectedView</span><span class=\"p\">(</span><span class=\"n\">TemplateView</span><span class=\"p\">):</span>\n    <span class=\"n\">template_name</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;secret.html&quot;</span>\n\n    <span class=\"nd\">@method_decorator</span><span class=\"p\">(</span><span class=\"n\">login_required</span><span class=\"p\">)</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">dispatch</span><span class=\"p\">(</span><span class=\"bp\">self</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>\n        <span class=\"k\">return</span> <span class=\"nb\">super</span><span class=\"p\">()</span><span class=\"o\">.</span><span class=\"n\">dispatch</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>\n</code></pre></div>\n<p>Eller, mer kortfattat, du kan dekorera klassen istället och skicka namnet på den metod som ska dekoreras som nyckelordsargumentet <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></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=\"nd\">@method_decorator</span><span class=\"p\">(</span><span class=\"n\">login_required</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s2\">&quot;dispatch&quot;</span><span class=\"p\">)</span>\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">ProtectedView</span><span class=\"p\">(</span><span class=\"n\">TemplateView</span><span class=\"p\">):</span>\n    <span class=\"n\">template_name</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;secret.html&quot;</span>\n</code></pre></div>\n<p>Om du har en uppsättning vanliga dekoratorer som används på flera ställen kan du definiera en lista eller tupel av dekoratorer och använda detta istället för att anropa <code class=\"docutils literal notranslate\"><span class=\"pre\">method_decorator()</span></code> flera gånger. Dessa två klasser är likvärdiga:</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=\"n\">decorators</span> <span class=\"o\">=</span> <span class=\"p\">[</span><span class=\"n\">never_cache</span><span class=\"p\">,</span> <span class=\"n\">login_required</span><span class=\"p\">]</span>\n\n\n<span class=\"nd\">@method_decorator</span><span class=\"p\">(</span><span class=\"n\">decorators</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s2\">&quot;dispatch&quot;</span><span class=\"p\">)</span>\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">ProtectedView</span><span class=\"p\">(</span><span class=\"n\">TemplateView</span><span class=\"p\">):</span>\n    <span class=\"n\">template_name</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;secret.html&quot;</span>\n\n\n<span class=\"nd\">@method_decorator</span><span class=\"p\">(</span><span class=\"n\">never_cache</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s2\">&quot;dispatch&quot;</span><span class=\"p\">)</span>\n<span class=\"nd\">@method_decorator</span><span class=\"p\">(</span><span class=\"n\">login_required</span><span class=\"p\">,</span> <span class=\"n\">name</span><span class=\"o\">=</span><span class=\"s2\">&quot;dispatch&quot;</span><span class=\"p\">)</span>\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">ProtectedView</span><span class=\"p\">(</span><span class=\"n\">TemplateView</span><span class=\"p\">):</span>\n    <span class=\"n\">template_name</span> <span class=\"o\">=</span> <span class=\"s2\">&quot;secret.html&quot;</span>\n</code></pre></div>\n<p>Dekoratörerna behandlar en begäran i den ordning som de skickas till dekoratören. I exemplet kommer <code class=\"docutils literal notranslate\"><span class=\"pre\">never_cache()</span></code> att bearbeta begäran före <code class=\"docutils literal notranslate\"><span class=\"pre\">login_required()</span></code>.</p>\n<p>I det här exemplet kommer varje instans av <code class=\"docutils literal notranslate\"><span class=\"pre\">ProtectedView</span></code> att ha inloggningsskydd. Dessa exempel använder <code class=\"docutils literal notranslate\"><span class=\"pre\">login_required</span></code>, men samma beteende kan erhållas genom att använda <a class=\"reference internal\" href=\"/sv/6.0/topics/auth/default/#django.contrib.auth.mixins.LoginRequiredMixin\" title=\"django.contrib.auth.mixins.LoginRequiredMixin\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">LoginRequiredMixin</span></code></a>.</p>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Observera</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">method_decorator</span></code> skickar <code class=\"docutils literal notranslate\"><span class=\"pre\">*args</span></code> och <code class=\"docutils literal notranslate\"><span class=\"pre\">**kwargs</span></code> som parametrar till den dekorerade metoden på klassen. Om din metod inte accepterar en kompatibel uppsättning parametrar kommer den att ge upphov till ett <code class=\"docutils literal notranslate\"><span class=\"pre\">TypeError</span></code> undantag.</p>\n</aside>\n</section>\n</section>","rootId":"introduction-to-class-based-views","toc":[{"title":"Förhållandet mellan och historien bakom generiska vyer, klassbaserade vyer och klassbaserade generiska vyer","anchor":"the-relationship-and-history-of-generic-views-class-based-views-and-class-based-generic-views","children":[]},{"title":"Använda klassbaserade vyer","anchor":"using-class-based-views","children":[]},{"title":"Använda mixins","anchor":"using-mixins","children":[]},{"title":"Hantera formulär med klassbaserade vyer","anchor":"handling-forms-with-class-based-views","children":[]},{"title":"Dekorera klassbaserade vyer","anchor":"decorating-class-based-views","children":[{"title":"Dekorera i URLconf","anchor":"decorating-in-urlconf","children":[]},{"title":"Inredning av klassen","anchor":"decorating-the-class","children":[]}]}],"breadcrumbs":[{"docname":"topics/index","title":"Använda Django","url":"/sv/6.0/topics/"},{"docname":"topics/class-based-views/index","title":"Klassbaserade åsikter","url":"/sv/6.0/topics/class-based-views/"}],"prev":{"docname":"topics/class-based-views/index","title":"Klassbaserade åsikter","url":"/sv/6.0/topics/class-based-views/"},"next":{"docname":"topics/class-based-views/generic-display","title":"Inbyggda klassbaserade generiska vyer","url":"/sv/6.0/topics/class-based-views/generic-display/"},"formats":{"html":"/sv/6.0/topics/class-based-views/intro/","markdown":"/sv/6.0/topics/class-based-views/intro.md","json":"/sv/6.0/topics/class-based-views/intro.json"},"source":"https://github.com/django/django/blob/stable/6.0.x/docs/topics/class-based-views/intro.txt","official":"https://docs.djangoproject.com/sv/6.0/topics/class-based-views/intro/","inVersions":["6.1","6.0","5.2"],"inLocales":["en","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}