# Django 6.0.7 documentation

# Unicode-data

Django stöder Unicode-data överallt.

I det här dokumentet beskrivs vad du behöver veta om du skriver program som använder data eller mallar som är kodade i något annat än ASCII.

## Skapa databasen

Se till att din databas är konfigurerad för att kunna lagra godtyckliga strängdata. Normalt innebär detta att du ger den en kodning av UTF-8 eller UTF-16. Om du använder en mer restriktiv kodning, t.ex. latin1 (iso8859-1), kan du inte lagra vissa tecken i databasen och information går förlorad.

- MySQL-användare, se MySQL manual för detaljer om hur du ställer in eller ändrar databasens teckenuppsättningskodning.

- PostgreSQL-användare, se PostgreSQL-manualen för information om hur du skapar databaser med rätt kodning.

- Oracle-användare, se Oracle manual för detaljer om hur man ställer in (section 2) eller ändrar (section 11) databasens teckenuppsättningskodning.

- SQLite-användare, det finns inget du behöver göra. SQLite använder alltid UTF-8 för intern kodning.

Alla Djangos databasbackends konverterar automatiskt strängar till lämplig kodning för att prata med databasen. De konverterar också automatiskt strängar som hämtas från databasen till strängar. Du behöver inte ens tala om för Django vilken kodning din databas använder: det hanteras transparent.

Mer information finns i avsnittet ”Databas-API:et” nedan.

## Allmän stränghantering

När du använder strängar med Django - t.ex. i databasuppslagningar, mallrendering eller någon annanstans - har du två val för att koda dessa strängar. Du kan använda vanliga strängar eller bytestrings (som börjar med ett ’b’).

Varning

En bytestring bär inte med sig någon information om dess kodning. Av den anledningen måste vi göra ett antagande, och Django antar att alla bytestrings är i UTF-8.

Om du skickar en sträng till Django som har kodats i något annat format kommer saker och ting att gå fel på intressanta sätt. Vanligtvis kommer Django att höja ett `UnicodeDecodeError` vid någon tidpunkt.

Om din kod bara använder ASCII-data är det säkert att använda dina vanliga strängar och skicka runt dem som du vill, eftersom ASCII är en delmängd av UTF-8.

Låt dig inte luras att tro att om inställningen `DEFAULT_CHARSET` är satt till något annat än `'utf-8'` så kan du använda den andra kodningen i dina bytestrings! `DEFAULT_CHARSET` gäller endast för de strängar som genereras som resultat av mallrendering (och e-post). Django kommer alltid att anta UTF-8-kodning för interna bytestrings. Anledningen till detta är att `DEFAULT_CHARSET`-inställningen faktiskt inte är under din kontroll (om du är applikationsutvecklare). Den kontrolleras av den person som installerar och använder din applikation - och om den personen väljer en annan inställning måste din kod fortfarande fungera. Den kan alltså inte förlita sig på den inställningen.

I de flesta fall när Django hanterar strängar kommer den att konvertera dem till strängar innan den gör något annat. Så, som en allmän regel, om du skickar in en bytestring, var beredd på att få en sträng tillbaka i resultatet.

### Översatta strängar

Bortsett från strängar och bytestrings finns det en tredje typ av strängliknande objekt som du kan stöta på när du använder Django. Ramverkets internationaliseringsfunktioner introducerar konceptet ”lazy translation” - en sträng som har markerats som översatt men vars faktiska översättningsresultat inte bestäms förrän objektet används i en sträng. Denna funktion är användbar i fall där översättningslokalen är okänd tills strängen används, även om strängen ursprungligen kan ha skapats när koden först importerades.

Normalt sett behöver du inte oroa dig för lata översättningar. Var bara medveten om att om du undersöker ett objekt och det påstår sig vara ett `django.utils.functional.__proxy__`-objekt, är det en lat översättning. Om du anropar `str()` med den lata översättningen som argument kommer en sträng att genereras i den aktuella språkdräkten.

Mer information om lata översättningsobjekt finns i dokumentationen internationalisering.

### Användbara funktioner

Eftersom vissa strängoperationer dyker upp om och om igen levereras Django med några användbara funktioner som bör göra det lite enklare att arbeta med sträng- och bytestringobjekt.

#### Omvandlingsfunktioner

Modulen `django.utils.encoding` innehåller några funktioner som är praktiska för att konvertera fram och tillbaka mellan strängar och bytestrings.

- `smart_str(s, encoding='utf-8', strings_only=False, errors='strict')` konverterar indata till en sträng. Parametern `encoding` anger kodningen för indata. (Django använder till exempel detta internt vid bearbetning av formulärinmatningsdata, som kanske inte är UTF-8-kodade) Parametern `strings_only`, om den sätts till True, kommer att resultera i att Python-tal, booleaner och `None` inte konverteras till en sträng (de behåller sina ursprungliga typer). Parametern `errors` tar något av de värden som accepteras av Pythons funktion `str()` för dess felhantering.

- `force_str(s, encoding='utf-8', strings_only=False, errors='strict')` är identisk med `smart_str()` i nästan alla fall. Skillnaden är när det första argumentet är en lazy translation-instans. Medan `smart_str()` bevarar lata översättningar, tvingar `force_str()` dessa objekt till en sträng (vilket gör att översättningen sker). Normalt sett vill du använda `smart_str()`. Men `force_str()` är användbart i malltaggar och filter som absolut måste ha en sträng att arbeta med, inte bara något som kan konverteras till en sträng.

- `smart_bytes(s, encoding='utf-8', strings_only=False, errors='strict')` är i princip motsatsen till `smart_str()`. Den tvingar det första argumentet till en bytestring. Parametern `strings_only` har samma beteende som för `smart_str()` och `force_str()`. Detta är något annorlunda semantik från Pythons inbyggda `str()`-funktion, men skillnaden behövs på några ställen inom Djangos internals.

Normalt sett behöver du bara använda `force_str()`. Anropa den så tidigt som möjligt på alla indata som kan vara antingen en sträng eller en bytestring, och från och med då kan du behandla resultatet som att det alltid är en sträng.

#### URI- och IRI-hantering

Webbramverk måste hantera URL:er (som är en typ av IRI). Ett krav på URL:er är att de kodas med enbart ASCII-tecken. I en internationell miljö kan du dock behöva konstruera en URL från en IRI – mycket löst uttryckt, en URI som kan innehålla Unicode-tecken. Använd dessa funktioner för att citera och konvertera en IRI till en URI:

- The `django.utils.encoding.iri_to_uri()` function, which implements the conversion from IRI to URI as required by RFC 3987 Section 3.1.

- Funktionerna `urllib.parse.quote()` och `urllib.parse.quote_plus()` från Pythons standardbibliotek.

Dessa två grupper av funktioner har lite olika syften, och det är viktigt att hålla isär dem. Normalt sett använder du `quote()` på de enskilda delarna av IRI:n eller URI-sökvägen så att alla reserverade tecken som ’&’ eller ’%’ kodas korrekt. Sedan använder du `iri_to_uri()` på hela IRI:n och konverterar alla icke-ASCII-tecken till rätt kodade värden.

Observera

Tekniskt sett är det inte korrekt att säga att `iri_to_uri()` implementerar hela algoritmen i IRI-specifikationen. Den utför inte (ännu) den internationella domännamnskodningsdelen av algoritmen.

Funktionen `iri_to_uri()` ändrar inte ASCII-tecken som annars är tillåtna i en URL. Så till exempel kodas inte tecknet ’%’ ytterligare när det skickas till `iri_to_uri()`. Detta innebär att du kan skicka en fullständig URL till den här funktionen och den kommer inte att röra till frågesträngen eller något liknande.

Ett exempel skulle kunna förtydliga saken:

    >>> from urllib.parse import quote
    >>> from django.utils.encoding import iri_to_uri
    >>> quote("Paris & Orléans")
    'Paris%20%26%20Orl%C3%A9ans'
    >>> iri_to_uri("/favorites/François/%s" % quote("Paris & Orléans"))
    '/favorites/Fran%C3%A7ois/Paris%20%26%20Orl%C3%A9ans'

Om du tittar noga kan du se att den del som genererades av `quote()` i det andra exemplet inte var dubbelciterad när den skickades till `iri_to_uri()`. Detta är en mycket viktig och användbar funktion. Det innebär att du kan konstruera din IRI utan att oroa dig för om den innehåller icke-ASCII-tecken och sedan, precis i slutet, anropa `iri_to_uri()` på resultatet.

Similarly, Django provides `django.utils.encoding.uri_to_iri()` which implements the conversion from URI to IRI as per RFC 3987 Section 3.2.

Ett exempel för att visa:

    >>> from django.utils.encoding import uri_to_iri
    >>> uri_to_iri("/%E2%99%A5%E2%99%A5/?utf8=%E2%9C%93")
    '/♥♥/?utf8=✓'
    >>> uri_to_iri("%A9hello%3Fworld")
    '%A9hello%3Fworld'

I det första exemplet är UTF-8-tecken inte citerade. I det andra förblir procentkodningarna oförändrade eftersom de ligger utanför det giltiga UTF-8-intervallet eller representerar ett reserverat tecken.

Både funktionerna `iri_to_uri()` och `uri_to_iri()` är idempotenta, vilket innebär att följande alltid är sant:

    iri_to_uri(iri_to_uri(some_string)) == iri_to_uri(some_string)
    uri_to_iri(uri_to_iri(some_string)) == uri_to_iri(some_string)

Så du kan säkert anropa den flera gånger på samma URI/IRI utan att riskera problem med dubbelkvotering.

## Modeller

Eftersom alla strängar returneras från databasen som `str`-objekt, kommer modellfält som är teckenbaserade (CharField, TextField, URLField, etc.) att innehålla Unicode-värden när Django hämtar data från databasen. Detta är alltid fallet, även om data skulle kunna passa in i en ASCII-bytestring.

Du kan skicka in bytestrings när du skapar en modell eller fyller i ett fält, och Django konverterar det till strängar när det behövs.

### Ta hand om `get_absolute_url()`

Webbadresser kan bara innehålla ASCII-tecken. Om du konstruerar en URL från bitar av data som kan vara icke-ASCII, var noga med att koda resultaten på ett sätt som är lämpligt för en URL. Funktionen `reverse()` hanterar detta åt dig automatiskt.

Om du konstruerar en URL manuellt (dvs. inte använder funktionen `reverse()`), måste du själv ta hand om kodningen. I det här fallet använder du funktionerna `iri_to_uri()` och `quote()` som dokumenterades ovan. Till exempel:

    from urllib.parse import quote
    from django.utils.encoding import iri_to_uri

    def get_absolute_url(self):
        url = "/person/%s/?x=0&y=0" % quote(self.location)
        return iri_to_uri(url)

Denna funktion returnerar en korrekt kodad URL även om `self.location` är något i stil med ”Jack besökte Paris & Orléans”. (I själva verket är anropet `iri_to_uri()` inte nödvändigt i exemplet ovan, eftersom alla icke-ASCII-tecken skulle ha tagits bort vid citering i den första raden)

## Mallar

Använd strängar när du skapar mallar manuellt:

    from django.template import Template

    t2 = Template("This is a string template.")

But the common case is to read templates from the filesystem. If your template files are not stored with a UTF-8 encoding, adjust the `TEMPLATES` setting. The built-in `django` backend provides the `'file_charset'` option to change the encoding used to read files from disk.

Inställningen `DEFAULT_CHARSET` styr kodningen av renderade mallar. Den är inställd på UTF-8 som standard.

### Taggar och filter för mallar

Några tips att tänka på när du skriver dina egna malltaggar och filter:

- Returnera alltid strängar från en malltaggs `render()`-metod och från mallfilter.

- Använd `force_str()` i stället för `smart_str()` på dessa ställen. Rendering av taggar och filteranrop sker när mallen renderas, så det finns ingen fördel med att skjuta upp konverteringen av lazy translation-objekt till strängar. Det är lättare att arbeta enbart med strängar vid den tidpunkten.

## Filer

Om du tänker tillåta användare att ladda upp filer måste du se till att miljön som används för att köra Django är konfigurerad för att fungera med icke-ASCII-filnamn. Om din miljö inte är korrekt konfigurerad kommer du att stöta på `UnicodeEncodeError`-undantag när du sparar filer med filnamn eller innehåll som innehåller icke-ASCII-tecken.

Filsystemets stöd för UTF-8-filnamn varierar och kan bero på miljön. Kontrollera din aktuella konfiguration i ett interaktivt Python-skal genom att köra:

    import sys

    sys.getfilesystemencoding()

Utmatningen bör vara ”UTF-8”.

Miljövariabeln `LANG` är ansvarig för att ställa in den förväntade kodningen på Unix-plattformar. I dokumentationen för ditt operativsystem och din applikationsserver finns information om lämplig syntax och plats för att ange den här variabeln. Se Så här använder du Django med Apache och mod_wsgi för exempel.

I din utvecklingsmiljö kan du behöva lägga till en inställning i din `~.bashrc` som motsvarar:

    export LANG="en_US.UTF-8"

## Inlämning av formulär

Inlämning av HTML-formulär är ett knepigt område. Det finns ingen garanti för att inlämningen kommer att innehålla kodningsinformation, vilket innebär att ramverket kan behöva gissa sig till kodningen av inlämnade data.

Django använder ett ”lata” tillvägagångssätt för att avkoda formulärdata. Data i ett `HttpRequest`-objekt avkodas endast när du kommer åt det. Faktum är att de flesta data inte avkodas alls. Endast datastrukturerna `HttpRequest.GET` och `HttpRequest.POST` har någon avkodning tillämpad på dem. Dessa två fält kommer att returnera sina medlemmar som Unicode-data. Alla andra attribut och metoder i `HttpRequest` returnerar data exakt som de skickades av klienten.

Som standard används inställningen `DEFAULT_CHARSET` som den förmodade kodningen för formulärdata. Om du behöver ändra detta för ett visst formulär kan du ställa in attributet `encoding` på en `HttpRequest`-instans. Till exempel:

    def some_view(request):
        # We know that the data must be encoded as KOI8-R (for some reason).
        request.encoding = "koi8-r"
        ...

Du kan till och med ändra kodningen efter att ha använt `request.GET` eller `request.POST`, och alla efterföljande åtkomster kommer att använda den nya kodningen.

De flesta utvecklare behöver inte bekymra sig om att ändra formulärkodning, men det här är en användbar funktion för applikationer som pratar med äldre system vars kodning du inte kan kontrollera.

Django avkodar inte data från filuppladdningar, eftersom dessa data normalt behandlas som samlingar av bytes, snarare än strängar. Varje automatisk avkodning där skulle ändra betydelsen av strömmen av bytes.