# Django 5.2.8 documentation

# Skriva synpunkter

En view-funktion, eller kort och gott view, är en Python-funktion som tar emot en webbförfrågan och returnerar ett webbsvar. Detta svar kan vara HTML-innehållet på en webbsida, eller en omdirigering, eller ett 404-fel, eller ett XML-dokument, eller en bild … eller vad som helst, egentligen. Själva vyn innehåller den godtyckliga logik som krävs för att returnera svaret. Denna kod kan leva var du vill, så länge den finns på din Python-sökväg. Det finns inga andra krav - ingen ”magi”, så att säga. För att lägga koden någonstans är konventionen att lägga vyer i en fil som heter `views.py`, placerad i din projekt- eller applikationskatalog.

## En enkel vy

Här är en vy som returnerar aktuellt datum och tid, som ett HTML-dokument:

    from django.http import HttpResponse
    import datetime

    def current_datetime(request):
        now = datetime.datetime.now()
        html = '<html lang="en"><body>It is now %s.</body></html>' % now
        return HttpResponse(html)

Låt oss gå igenom koden en rad i taget:

- Först importerar vi klassen `HttpResponse` från modulen `django.http`, tillsammans med Pythons bibliotek `datetime`.

- Därefter definierar vi en funktion som heter `current_datetime`. Detta är en vyfunktion. Varje view-funktion tar ett `HttpRequest`-objekt som sin första parameter, som vanligtvis heter `request`.

  Observera att namnet på vyfunktionen inte spelar någon roll; den behöver inte namnges på ett visst sätt för att Django ska känna igen den. Vi kallar den `current_datetime` här, eftersom det namnet tydligt anger vad den gör.

- Vyn returnerar ett `HttpResponse`-objekt som innehåller det genererade svaret. Varje vyfunktion är ansvarig för att returnera ett `HttpResponse`-objekt. (Det finns undantag, men dem kommer vi till senare)

Djangos tidszon

Django innehåller en `TIME_ZONE`-inställning som standard är `Amerika/Chicago`. Detta är förmodligen inte där du bor, så du kanske vill ändra det i din inställningsfil.

## Mappning av webbadresser till vyer

Sammanfattningsvis returnerar denna vyfunktion en HTML-sida som innehåller aktuellt datum och aktuell tid. Om du vill visa den här vyn på en viss URL måste du skapa en URLconf; se URL-distributör för instruktioner.

## Returnera fel

Django tillhandahåller hjälp för att returnera HTTP-felkoder. Det finns underklasser av `HttpResponse` för ett antal vanliga HTTP-statuskoder andra än 200 (vilket betyder ”OK”). Du kan hitta den fullständiga listan över tillgängliga underklasser i request/response-dokumentationen. Returnera en instans av en av dessa underklasser istället för en normal `HttpResponse` för att indikera ett fel. Till exempel:

    from django.http import HttpResponse, HttpResponseNotFound

    def my_view(request):
        # ...
        if foo:
            return HttpResponseNotFound("<h1>Page not found</h1>")
        else:
            return HttpResponse("<h1>Page was found</h1>")

Det finns inte en specialiserad underklass för varje möjlig HTTP-svarskod, eftersom många av dem inte kommer att vara så vanliga. Men som dokumenterat i `HttpResponse`-dokumentationen kan du också skicka HTTP-statuskoden till konstruktören för `HttpResponse` för att skapa en returklass för vilken statuskod du vill. Till exempel:

    from django.http import HttpResponse

    def my_view(request):
        # ...

        # Return a "created" (201) response code.
        return HttpResponse(status=201)

Eftersom 404-fel är det överlägset vanligaste HTTP-felet finns det ett enklare sätt att hantera dessa fel.

### Undantaget ”Http404

class django.http.Http404

När du returnerar ett fel som `HttpResponseNotFound`, är du ansvarig för att definiera HTML på den resulterande felsidan:

    return HttpResponseNotFound("<h1>Page not found</h1>")

För enkelhetens skull, och eftersom det är en bra idé att ha en konsekvent 404-felsida på hela webbplatsen, tillhandahåller Django ett undantag för `Http404`. Om du höjer `Http404` vid någon tidpunkt i en vyfunktion, kommer Django att fånga det och returnera standardfelsidan för din applikation, tillsammans med en HTTP-felkod 404.

Exempel på användning:

    from django.http import Http404
    from django.shortcuts import render
    from polls.models import Poll

    def detail(request, poll_id):
        try:
            p = Poll.objects.get(pk=poll_id)
        except Poll.DoesNotExist:
            raise Http404("Poll does not exist")
        return render(request, "polls/detail.html", {"poll": p})

För att visa anpassad HTML när Django returnerar en 404, kan du skapa en HTML-mall med namnet `404.html` och placera den på den översta nivån i ditt mallträd. Denna mall kommer sedan att visas när `DEBUG` är inställd på `False`.

När `DEBUG` är `True` kan du ange ett meddelande till `Http404` och det kommer att visas i standardmallen för 404 debug. Använd dessa meddelanden i felsökningssyfte; de är i allmänhet inte lämpliga att använda i en 404-mall för produktion.

## Anpassa felvyer

Standardfelvyerna i Django bör räcka för de flesta webbapplikationer, men kan enkelt åsidosättas om du behöver något anpassat beteende. Specificera hanterarna enligt nedan i din URLconf (att ställa in dem någon annanstans har ingen effekt).

Vyn `page_not_found()` åsidosätts av `handler404`:

    handler404 = "mysite.views.my_custom_page_not_found_view"

Vyn `server_error()` åsidosätts av `handler500`:

    handler500 = "mysite.views.my_custom_error_view"

Vyn `permission_denied()` åsidosätts av `handler403`:

    handler403 = "mysite.views.my_custom_permission_denied_view"

Vyn `bad_request()` åsidosätts av `handler400`:

    handler400 = "mysite.views.my_custom_bad_request_view"

Se även

Använd inställningen `CSRF_FAILURE_VIEW` för att åsidosätta CSRF-felvyn.

### Testa anpassade felvyer

Om du vill testa svaret från en anpassad felhanterare kan du skapa ett lämpligt undantag i en testvy. Till exempel:

    from django.core.exceptions import PermissionDenied
    from django.http import HttpResponse
    from django.test import SimpleTestCase, override_settings
    from django.urls import path

    def response_error_handler(request, exception=None):
        return HttpResponse("Error handler content", status=403)

    def permission_denied_view(request):
        raise PermissionDenied

    urlpatterns = [
        path("403/", permission_denied_view),
    ]

    handler403 = response_error_handler

    # ROOT_URLCONF must specify the module that contains handler403 = ...
    @override_settings(ROOT_URLCONF=__name__)
    class CustomErrorHandlerTests(SimpleTestCase):
        def test_handler_renders_template_response(self):
            response = self.client.get("/403/")
            # Make assertions on the response here. For example:
            self.assertContains(response, "Error handler content", status_code=403)

## Asynkrona vyer

Förutom att vara synkrona funktioner kan vyer också vara asynkrona (”async”) funktioner, normalt definierade med Pythons `async def` syntax. Django kommer automatiskt att upptäcka dessa och köra dem i ett asynkront sammanhang. Du måste dock använda en asynkron server baserad på ASGI för att få prestandafördelarna.

Här är ett exempel på en asynkron vy:

    import datetime
    from django.http import HttpResponse

    async def current_datetime(request):
        now = datetime.datetime.now()
        html = '<html lang="en"><body>It is now %s.</body></html>' % now
        return HttpResponse(html)

Du kan läsa mer om Djangos async-stöd, och hur du bäst använder async-vyer, i Asynkront stöd.