---
title: "Anpassa autentiseringen i Django"
version: 6.1
locale: sv
source: https://docs.djangoproject.com/sv/6.1/topics/auth/customizing/
canonical: https://djangodocs.dev/sv/6.1/topics/auth/customizing/
---
# Anpassa autentiseringen i Django

Den autentisering som följer med Django är tillräckligt bra för de flesta vanliga fall, men du kan ha behov som inte uppfylls av standardinställningarna. Att anpassa autentiseringen i dina projekt kräver förståelse för vilka punkter i det tillhandahållna systemet som är utbyggbara eller utbytbara. Detta dokument ger detaljer om hur autentiseringssystemet kan anpassas.

[Authentication backends](#authentication-backends) tillhandahåller ett utbyggbart system för när ett användarnamn och lösenord som lagras med användarmodellen behöver autentiseras mot en annan tjänst än Djangos standard.

Du kan ge dina modeller [custom permissions](#custom-permissions) som kan kontrolleras genom Djangos auktoriseringssystem.

Du kan [utöka](#extending-user) standardmodellen `User`, eller [ersätta](#auth-custom-user) en helt anpassad modell.

## Andra autentiseringskällor

Det kan finnas tillfällen då du behöver ansluta till en annan autentiseringskälla - det vill säga en annan källa med användarnamn och lösenord eller autentiseringsmetoder.

Ditt företag kanske redan har en LDAP-installation som lagrar ett användarnamn och lösenord för varje anställd. Det skulle vara krångligt för både nätverksadministratören och användarna själva om användarna hade separata konton i LDAP och de Django-baserade applikationerna.

För att hantera situationer som denna låter Djangos autentiseringssystem dig koppla in andra autentiseringskällor. Du kan åsidosätta Djangos standarddatabasbaserade system, eller så kan du använda standardsystemet i kombination med andra system.

Se [authentication backend reference](/sv/6.1/ref/contrib/auth/#authentication-backends-reference) för information om de autentiseringsbackends som ingår i Django.

### Ange backend för autentisering

Behind the scenes, Django maintains a list of ”authentication backends” that it
checks for authentication. When somebody calls
[`django.contrib.auth.authenticate()`](/sv/6.1/topics/auth/default/#django.contrib.auth.authenticate) – as described in [How to log
a user in](/sv/6.1/topics/auth/default/#how-to-log-a-user-in) – Django tries authenticating across
all of its authentication backends. If the first authentication method fails,
Django tries the second one, and so on, until all backends have been attempted.

Listan över autentiseringsbackends som ska användas anges i inställningen [`AUTHENTICATION_BACKENDS`](/sv/6.1/ref/settings/#std-setting-AUTHENTICATION_BACKENDS). Detta bör vara en lista med Python-sökvägsnamn som pekar på Python-klasser som vet hur man autentiserar. Dessa klasser kan finnas var som helst på din Python-sökväg.

Som standard är [`AUTHENTICATION_BACKENDS`](/sv/6.1/ref/settings/#std-setting-AUTHENTICATION_BACKENDS) inställd på:

```
["django.contrib.auth.backends.ModelBackend"]
```

Det är den grundläggande autentiseringsbackend som kontrollerar Djangos användardatabas och frågar efter de inbyggda behörigheterna. Det ger inte skydd mot brute force-attacker via någon hastighetsbegränsningsmekanism. Du kan antingen implementera din egen hastighetsbegränsningsmekanism i en anpassad autentiseringsbackend eller använda de mekanismer som tillhandahålls av de flesta webbservrar.

Ordningen på [`AUTHENTICATION_BACKENDS`](/sv/6.1/ref/settings/#std-setting-AUTHENTICATION_BACKENDS) spelar roll, så om samma användarnamn och lösenord är giltigt i flera backends kommer Django att stoppa bearbetningen vid den första positiva matchningen.

Om en backend ger upphov till ett [`PermissionDenied`](/sv/6.1/ref/exceptions/#django.core.exceptions.PermissionDenied) undantag, kommer autentiseringen omedelbart att misslyckas. Django kommer inte att kontrollera de backends som följer.

> **Note**
>
> När en användare har autentiserat lagrar Django vilken backend som användes för att autentisera användaren i användarens session, och återanvänder samma backend under hela sessionen när åtkomst till den aktuella autentiserade användaren behövs. Detta innebär i praktiken att autentiseringskällor cachelagras per session, så om du ändrar [`AUTHENTICATION_BACKENDS`](/sv/6.1/ref/settings/#std-setting-AUTHENTICATION_BACKENDS) måste du rensa bort sessionsdata om du vill tvinga användare att autentisera sig på nytt med olika metoder. Ett enkelt sätt att göra det är att köra `Session.objects.all().delete()`.

### Skriva en backend för autentisering

En autentiseringsbackend är en klass som implementerar två obligatoriska metoder: `get_user(user_id)` och `authenticate(request, **credentials)`, samt en uppsättning valfria behörighetsrelaterade [auktoriseringsmetoder](#authorization-methods).

Metoden `get_user` tar ett `user_id` \- som kan vara ett användarnamn, databas-ID eller vad som helst, men som måste vara primärnyckeln i ditt användarobjekt - och returnerar ett användarobjekt eller `None`.

Metoden `authenticate` tar ett `request`-argument och referenser som nyckelordsargument. För det mesta kommer det att se ut så här:

```
from django.contrib.auth.backends import BaseBackend

class MyBackend(BaseBackend):
    def authenticate(self, request, username=None, password=None):
        # Check the username/password and return a user.
        ...
```

Men det kan också autentisera en token, så här:

```
from django.contrib.auth.backends import BaseBackend

class MyBackend(BaseBackend):
    def authenticate(self, request, token=None):
        # Check the token and return a user.
        ...
```

I vilket fall som helst bör `authenticate()` kontrollera de autentiseringsuppgifter den får och returnera ett användarobjekt som matchar dessa autentiseringsuppgifter om autentiseringsuppgifterna är giltiga. Om de inte är giltiga bör den returnera `None`.

`request` är en [`HttpRequest`](/sv/6.1/ref/request-response/#django.http.HttpRequest) och kan vara `None` om den inte tillhandahölls till [`authenticate()`](/sv/6.1/topics/auth/default/#django.contrib.auth.authenticate) (som skickar den vidare till backend).

Djangos admin är tätt kopplad till Djangos [User-objekt](/sv/6.1/topics/auth/default/#user-objects). För att en användare ska få åtkomst till admin måste till exempel [`User.is_staff`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User.is_staff) och [`User.is_active`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User.is_active) vara `True` (se [`AdminSite.has_permission()`](/sv/6.1/ref/contrib/admin/#django.contrib.admin.AdminSite.has_permission) för detaljer).

Det bästa sättet att hantera detta är att skapa ett Django `User`-objekt för varje användare som finns för din backend (t.ex. i din LDAP-katalog, din externa SQL-databas etc.) Du kan antingen skriva ett skript för att göra detta i förväg, eller så kan din `authenticate`-metod göra det första gången en användare loggar in.

Här är ett exempel på en backend som autentiserar mot en användarnamn- och lösenordsvariabel som definieras i din `settings.py`-fil och skapar ett Django `User`-objekt första gången en användare autentiserar. I det här exemplet är det skapade Django `User`-objektet en superanvändare som kommer att ha full tillgång till admin:

```
from django.conf import settings
from django.contrib.auth.backends import BaseBackend
from django.contrib.auth.hashers import check_password
from django.contrib.auth.models import User

class SettingsBackend(BaseBackend):
    """
    Authenticate against the settings ADMIN_LOGIN and ADMIN_PASSWORD.

    Use the login name and a hash of the password. For example:

    ADMIN_LOGIN = 'admin'
    ADMIN_PASSWORD = 'pbkdf2_sha256$30000$Vo0VlMnkR4Bk$qEvtdyZRWTcOsCnI/oQ7fVOu1XAURIZYoOZ3iq8Dr4M='
    """

    def authenticate(self, request, username=None, password=None):
        login_valid = settings.ADMIN_LOGIN == username
        pwd_valid = check_password(password, settings.ADMIN_PASSWORD)
        if login_valid and pwd_valid:
            try:
                user = User.objects.get(username=username)
            except User.DoesNotExist:
                # Create a new user. There's no need to set a password
                # because only the password from settings.py is checked.
                user = User(username=username)  # is_active defaults to True.
                user.is_staff = True
                user.is_superuser = True
                user.save()
            return user
        return None

    def get_user(self, user_id):
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None
```

### Hantering av auktorisering i anpassade backends

Anpassade auth-backends kan ge sina egna behörigheter.

The user model and its manager will delegate permission lookup functions
([`get_user_permissions()`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User.get_user_permissions),
[`get_group_permissions()`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User.get_group_permissions),
[`get_all_permissions()`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User.get_all_permissions),
[`has_perm()`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User.has_perm),
[`has_module_perms()`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User.has_module_perms), and
[`with_perm()`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.UserManager.with_perm)) to any
authentication backend that implements these functions.

De behörigheter som ges till användaren kommer att vara superset av alla behörigheter som returneras av alla backends. Det vill säga, Django ger en behörighet till en användare som vilken backend som helst ger.

If a backend raises a [`PermissionDenied`](/sv/6.1/ref/exceptions/#django.core.exceptions.PermissionDenied)
exception in [`has_perm()`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User.has_perm) or
[`has_module_perms()`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User.has_module_perms), the authorization
will immediately fail and Django won’t check the backends that follow.

En backend kan implementera behörigheter för den magiska administratören på följande sätt:

```
from django.contrib.auth.backends import BaseBackend

class MagicAdminBackend(BaseBackend):
    def has_perm(self, user_obj, perm, obj=None):
        return user_obj.username == settings.ADMIN_LOGIN
```

Detta ger full behörighet till den användare som beviljats åtkomst i exemplet ovan. Observera att förutom samma argument som ges till de associerade [`django.contrib.auth.models.User`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User)-funktionerna, tar alla auth-funktioner i backend användarobjektet, som kan vara en anonym användare, som ett argument.

En fullständig auktoriseringsimplementering finns i klassen `ModelBackend` i [django/contrib/auth/backends.py](https://github.com/django/django/blob/stable/6.1.x/django/contrib/auth/backends.py), som är standardbackend och frågar tabellen `auth_permission` för det mesta.

#### Behörighet för anonyma användare

En anonym användare är en användare som inte är autentiserad, dvs. som inte har angett några giltiga autentiseringsuppgifter. Det behöver dock inte betyda att de inte har behörighet att göra någonting. På den mest grundläggande nivån tillåter de flesta webbplatser anonyma användare att surfa på större delen av webbplatsen, och många tillåter anonyma inlägg av kommentarer etc.

Djangos behörighetsramverk har ingen plats för att lagra behörigheter för anonyma användare. Användarobjektet som skickas till en autentiseringsbackend kan dock vara ett [`django.contrib.auth.models.AnonymousUser`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.AnonymousUser)-objekt, vilket gör att backend kan ange anpassat auktoriseringsbeteende för anonyma användare. Detta är särskilt användbart för författare av återanvändbara appar, som kan delegera alla frågor om auktorisering till auth-backend, i stället för att behöva inställningar, till exempel för att kontrollera anonym åtkomst.

#### Behörighet för inaktiva användare

En inaktiv användare är en användare som har fältet [`is_active`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User.is_active) inställt på `False`. Autentiseringsbackends [`ModelBackend`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.backends.ModelBackend) och [`RemoteUserBackend`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.backends.RemoteUserBackend) förbjuder dessa användare från att autentisera. Om en anpassad användarmodell inte har ett fält [`is_active`](#django.contrib.auth.models.CustomUser.is_active) tillåts alla användare att autentisera sig.

Du kan använda [`AllowAllUsersModelBackend`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.backends.AllowAllUsersModelBackend) eller [`AllowAllUsersRemoteUserBackend`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.backends.AllowAllUsersRemoteUserBackend) om du vill tillåta inaktiva användare att autentisera sig.

Stödet för anonyma användare i behörighetssystemet gör det möjligt att skapa ett scenario där anonyma användare har behörighet att göra något medan inaktiva autentiserade användare inte har det.

Glöm inte att testa för attributet `is_active` för användaren i dina egna behörighetsmetoder i backend.

#### Hantering av objektbehörigheter

Djangos behörighetsramverk har en grund för objektbehörigheter, även om det inte finns någon implementering för det i kärnan. Det innebär att kontroll av objektbehörigheter alltid kommer att returnera `False` eller en tom lista (beroende på vilken kontroll som utförs). En autentiseringsbackend tar emot nyckelordsparametrarna `obj` och `user_obj` för varje objektrelaterad auktoriseringsmetod och kan returnera objektnivåbehörigheten på lämpligt sätt.

## Anpassade behörigheter

För att skapa anpassade behörigheter för ett visst modellobjekt använder du `permissions` [model Meta attribute](/sv/6.1/topics/db/models/#meta-options).

Detta exempel på en `Task`-modell skapar två anpassade behörigheter, dvs. åtgärder som användare kan eller inte kan göra med `Task`-instanser, som är specifika för din applikation:

```
class Task(models.Model):
    ...

    class Meta:
        permissions = [
            ("change_task_status", "Can change the status of tasks"),
            ("close_task", "Can remove a task by setting its status as closed"),
        ]
```

Det enda detta gör är att skapa dessa extra behörigheter när du kör [`manage.py migrate`](/sv/6.1/ref/django-admin/#django-admin-migrate) (funktionen som skapar behörigheter är kopplad till [`post_migrate`](/sv/6.1/ref/signals/#django.db.models.signals.post_migrate)-signalen). Din kod ansvarar för att kontrollera värdet på dessa behörigheter när en användare försöker komma åt den funktionalitet som tillhandahålls av applikationen (ändra status för uppgifter eller stänga uppgifter.) Om vi fortsätter med exemplet ovan kontrollerar följande om en användare kan stänga uppgifter:

```
user.has_perm("app.close_task")
```

## Utökning av den befintliga `User`-modellen

Det finns två sätt att utöka standardmodellen [`User`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User) utan att ersätta den med en egen modell. Om de ändringar du behöver är rent beteendemässiga och inte kräver någon ändring av vad som lagras i databasen kan du skapa en [proxymodell](/sv/6.1/topics/db/models/#proxy-models) baserad på [`User`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User). Detta möjliggör alla de funktioner som erbjuds av proxymodeller, inklusive standardbeställning, anpassade chefer eller anpassade modellmetoder.

Om du vill lagra information som är relaterad till `User` kan du använda en [`OneToOneField`](/sv/6.1/ref/models/fields/#django.db.models.OneToOneField) till en modell som innehåller fälten för ytterligare information. Denna en-till-en-modell kallas ofta en profilmodell, eftersom den kan lagra icke-auth-relaterad information om en webbplatsanvändare. Du kan till exempel skapa en Employee-modell:

```
from django.contrib.auth.models import User

class Employee(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    department = models.CharField(max_length=100)
```

Om vi utgår från en befintlig anställd Fred Smith som har både en användar- och en anställdmodell kan du komma åt den relaterade informationen med hjälp av Djangos standardkonventioner för relaterade modeller:

```pycon
>>> u = User.objects.get(username="fsmith")
>>> freds_department = u.employee.department
```

För att lägga till en profilmodells fält på användarsidan i admin, definiera en [`InlineModelAdmin`](/sv/6.1/ref/contrib/admin/#django.contrib.admin.InlineModelAdmin) (för detta exempel använder vi en [`StackedInline`](/sv/6.1/ref/contrib/admin/#django.contrib.admin.StackedInline)) i din apps ```admin.py` och lägg till den i en ``UserAdmin```-klass som är registrerad med [`User`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User)-klassen:

```
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.models import User

from my_user_profile_app.models import Employee

# Define an inline admin descriptor for Employee model
# which acts a bit like a singleton
class EmployeeInline(admin.StackedInline):
    model = Employee
    can_delete = False
    verbose_name_plural = "employee"

# Define a new User admin
class UserAdmin(BaseUserAdmin):
    inlines = [EmployeeInline]

# Re-register UserAdmin
admin.site.unregister(User)
admin.site.register(User, UserAdmin)
```

Dessa profilmodeller är inte speciella på något sätt - de är bara Django-modeller som råkar ha en en-till-en-länk med en användarmodell. Som sådana skapas de inte automatiskt när en användare skapas, men en [`django.db.models.signals.post_save`](/sv/6.1/ref/signals/#django.db.models.signals.post_save) kan användas för att skapa eller uppdatera relaterade modeller på lämpligt sätt.

Att använda relaterade modeller resulterar i ytterligare frågor eller joins för att hämta de relaterade uppgifterna. Beroende på dina behov kan en anpassad användarmodell som innehåller de relaterade fälten vara ett bättre alternativ, men befintliga relationer till standardanvändarmodellen i projektets appar kan motivera den extra databasbelastningen.

## Ersätta en anpassad `User`-modell

Vissa typer av projekt kan ha autentiseringskrav för vilka Djangos inbyggda [`User`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User)-modell inte alltid är lämplig. På vissa webbplatser är det till exempel mer meningsfullt att använda en e-postadress som din identifieringstoken istället för ett användarnamn.

Django låter dig åsidosätta standardanvändarmodellen genom att tillhandahålla ett värde för inställningen [`AUTH_USER_MODEL`](/sv/6.1/ref/settings/#std-setting-AUTH_USER_MODEL) som refererar till en anpassad modell:

```
AUTH_USER_MODEL = "myapp.MyUser"
```

Detta prickade par beskriver [`label`](/sv/6.1/ref/applications/#django.apps.AppConfig.label) för Django-appen (som måste finnas i din [`INSTALLED_APPS`](/sv/6.1/ref/settings/#std-setting-INSTALLED_APPS)) och namnet på den Django-modell som du vill använda som din användarmodell.

### Använda en anpassad användarmodell när du startar ett projekt

Om du startar ett nytt projekt kan du ställa in en anpassad användarmodell som beter sig identiskt med standardanvändarmodellen genom att underklassa [`AbstractUser`](#django.contrib.auth.models.AbstractUser):

```
from django.contrib.auth.models import AbstractUser

class User(AbstractUser):
    pass
```

Glöm inte att peka [`AUTH_USER_MODEL`](/sv/6.1/ref/settings/#std-setting-AUTH_USER_MODEL) till den. Gör detta innan du skapar några migreringar eller kör `manage.py migrate` för första gången.

Registrera också modellen i appens `admin.py`:

```
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from .models import User

admin.site.register(User, UserAdmin)
```

### Byte till en anpassad användarmodell mitt i projektet

Det är möjligt att ändra [`AUTH_USER_MODEL`](/sv/6.1/ref/settings/#std-setting-AUTH_USER_MODEL) efter att du har skapat databastabeller, men det kan vara komplicerat eftersom det påverkar t.ex. utländska nycklar och många-till-många-relationer.

Den här ändringen kan inte göras automatiskt och kräver att du manuellt fixar ditt schema, flyttar dina data från den gamla användartabellen och eventuellt manuellt tillämpar vissa migreringar igen. Se [#25313](https://code.djangoproject.com/ticket/25313) för en översikt över stegen.

På grund av begränsningar i Djangos dynamiska beroendefunktion för utbytbara modeller måste den modell som refereras till av [`AUTH_USER_MODEL`](/sv/6.1/ref/settings/#std-setting-AUTH_USER_MODEL) skapas i den första migreringen av dess app (vanligtvis kallad `0001_initial`); annars får du beroendeproblem.

Dessutom kan du stöta på ett `CircularDependencyError` när du kör dina migreringar eftersom Django inte automatiskt kan bryta beroendeslingan på grund av det dynamiska beroendet. Om du ser det här felet bör du bryta slingan genom att flytta de modeller som din användarmodell är beroende av till en andra migrering. (Du kan prova att skapa två normala modeller som har en `ForeignKey` till varandra och se hur `makemigrations` löser det cirkulära beroendet om du vill se hur det vanligtvis görs)

### Återanvändbara appar och `AUTH_USER_MODEL`

Återanvändbara appar bör inte implementera en anpassad användarmodell. Ett projekt kan använda många appar, och två återanvändbara appar som implementerade en anpassad användarmodell kunde inte användas tillsammans. Om du behöver lagra information per användare i din app, använd en [`ForeignKey`](/sv/6.1/ref/models/fields/#django.db.models.ForeignKey) eller [`OneToOneField`](/sv/6.1/ref/models/fields/#django.db.models.OneToOneField) till `settings.AUTH_USER_MODEL` enligt beskrivningen nedan.

### Hänvisning till modellen `User`

Om du refererar till [`User`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User) direkt (t.ex. genom att hänvisa till den i en främmande nyckel), kommer din kod inte att fungera i projekt där [`AUTH_USER_MODEL`](/sv/6.1/ref/settings/#std-setting-AUTH_USER_MODEL) har ändrats till en annan användarmodell.

#### `get_user_model()`

Istället för att referera till [`User`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User) direkt, bör du referera till användarmodellen med `django.contrib.auth.get_user_model()`. Denna metod returnerar den för närvarande aktiva användarmodellen - den anpassade användarmodellen om en sådan anges, eller [`User`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User) annars.

När du definierar en främmande nyckel eller många-till-många-relationer till användarmodellen bör du ange den anpassade modellen med hjälp av inställningen [`AUTH_USER_MODEL`](/sv/6.1/ref/settings/#std-setting-AUTH_USER_MODEL). Till exempel:

```
from django.conf import settings
from django.db import models

class Article(models.Model):
    author = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
    )
```

När du ansluter till signaler som skickas av användarmodellen bör du ange den anpassade modellen med hjälp av inställningen [`AUTH_USER_MODEL`](/sv/6.1/ref/settings/#std-setting-AUTH_USER_MODEL). Till exempel:

```
from django.conf import settings
from django.db.models.signals import post_save

def post_save_receiver(sender, instance, created, **kwargs):
    pass

post_save.connect(post_save_receiver, sender=settings.AUTH_USER_MODEL)
```

Generellt sett är det enklast att hänvisa till användarmodellen med inställningen [`AUTH_USER_MODEL`](/sv/6.1/ref/settings/#std-setting-AUTH_USER_MODEL) i kod som körs vid importtillfället, men det är också möjligt att anropa `get_user_model()` medan Django importerar modeller, så du kan använda `models.ForeignKey(get_user_model(), ...)`.

Om din app testas med flera användarmodeller, till exempel med hjälp av `@override_settings(AUTH_USER_MODEL=...)` och du cachar resultatet av `get_user_model()` i en variabel på modulnivå, kan du behöva lyssna på [`setting_changed`](/sv/6.1/ref/signals/#django.test.signals.setting_changed)-signalen för att rensa cacheminnet. Till exempel:

```
from django.apps import apps
from django.contrib.auth import get_user_model
from django.core.signals import setting_changed
from django.dispatch import receiver

@receiver(setting_changed)
def user_model_swapped(*, setting, **kwargs):
    if setting == "AUTH_USER_MODEL":
        apps.clear_cache()
        from myapp import some_module

        some_module.UserModel = get_user_model()
```

### Ange en anpassad användarmodell

När du börjar ditt projekt med en anpassad användarmodell bör du fundera på om det är rätt val för ditt projekt.

Om du samlar all användarrelaterad information i en modell behöver du inte göra fler eller mer komplexa databasfrågor för att hämta relaterade modeller. Å andra sidan kan det vara mer lämpligt att lagra appspecifik användarinformation i en modell som har en relation till din anpassade användarmodell. Det gör att varje app kan specificera sina egna krav på användardata utan att potentiellt motverka eller bryta mot antaganden från andra appar. Det innebär också att du håller din användarmodell så enkel som möjligt, fokuserad på autentisering och följer de minimikrav som Django förväntar sig att anpassade användarmodeller ska uppfylla.

Om du använder standardbackend för autentisering måste din modell ha ett enda unikt fält som kan användas för identifiering. Detta kan vara ett användarnamn, en e-postadress eller något annat unikt attribut. Ett icke-unikt användarnamnsfält är tillåtet om du använder en anpassad autentiseringsbackend som kan stödja det.

Det enklaste sättet att konstruera en kompatibel anpassad användarmodell är att ärva från [`AbstractBaseUser`](#django.contrib.auth.models.AbstractBaseUser). [`AbstractBaseUser`](#django.contrib.auth.models.AbstractBaseUser) tillhandahåller kärnimplementeringen av en användarmodell, inklusive hashade lösenord och tokeniserade lösenordsåterställningar. Du måste sedan tillhandahålla några viktiga implementeringsdetaljer:

#### `class models.CustomUser`

#### `USERNAME_FIELD`

En sträng som beskriver namnet på det fält i användarmodellen som används som unik identifierare. Detta är vanligtvis ett användarnamn av något slag, men det kan också vara en e-postadress eller någon annan unik identifierare. Fältet *måste* vara unikt (t.ex. ha `unique=True` inställt i sin definition), såvida du inte använder en anpassad autentiseringsbackend som kan stödja icke-unika användarnamn.

I följande exempel används fältet `identifier` som identifieringsfält:

```
class MyUser(AbstractBaseUser):
    identifier = models.CharField(max_length=40, unique=True)
    ...
    USERNAME_FIELD = "identifier"
```

#### `EMAIL_FIELD`

En sträng som beskriver namnet på e-postfältet i modellen `User`. Detta värde returneras av [`get_email_field_name()`](#django.contrib.auth.models.AbstractBaseUser.get_email_field_name).

#### `REQUIRED_FIELDS`

En lista över de fältnamn som kommer att efterfrågas när en användare skapas via hanteringskommandot [`createsuperuser`](/sv/6.1/ref/django-admin/#django-admin-createsuperuser). Användaren kommer att uppmanas att ange ett värde för vart och ett av dessa fält. Det måste inkludera alla fält för vilka [`blank`](/sv/6.1/ref/models/fields/#django.db.models.Field.blank) är `False` eller odefinierat och kan inkludera ytterligare fält som du vill bli ombedd att ange när en användare skapas interaktivt. `REQUIRED_FIELDS` har ingen effekt i andra delar av Django, som att skapa en användare i admin.

Här är till exempel den partiella definitionen för en användarmodell som definierar två obligatoriska fält - födelsedatum och längd:

```
class MyUser(AbstractBaseUser):
    ...
    date_of_birth = models.DateField()
    height = models.FloatField()
    ...
    REQUIRED_FIELDS = ["date_of_birth", "height"]
```

> **Note**
>
> `REQUIRED_FIELDS` måste innehålla alla obligatoriska fält i din användarmodell, men bör *inte* innehålla `USERNAME_FIELD` eller `password` eftersom dessa fält alltid kommer att efterfrågas.

#### `is_active`

A boolean attribute that indicates whether the user is considered
”active”. This attribute is provided as an attribute on
`AbstractBaseUser` defaulting to `True`. How you choose to
implement it will depend on the details of your chosen auth backends.
See the documentation of the [`is_active attribute on the built-in
user model`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User.is_active) for details.

#### `get_full_name()`

Valfritt. En längre formell identifierare för användaren, t.ex. deras fullständiga namn. Om det implementeras visas detta tillsammans med användarnamnet i ett objekts historik i [`django.contrib.admin`](/sv/6.1/ref/contrib/admin/#module-django.contrib.admin).

#### `get_short_name()`

Valfritt. En kort, informell identifierare för användaren, t.ex. användarens förnamn. Om det implementeras ersätter detta användarnamnet i hälsningen till användaren i rubriken för [`django.contrib.admin`](/sv/6.1/ref/contrib/admin/#module-django.contrib.admin).

> **Importera AbstractBaseUser**
>
> `AbstractBaseUser` och `BaseUserManager` är importerbara från `django.contrib.auth.base_user` så att de kan importeras utan att inkludera `django.contrib.auth` i [`INSTALLED_APPS`](/sv/6.1/ref/settings/#std-setting-INSTALLED_APPS).

Följande attribut och metoder är tillgängliga för alla subklasser av [`AbstractBaseUser`](#django.contrib.auth.models.AbstractBaseUser):

#### `class models.AbstractBaseUser`

#### `get_username()`

Returnerar värdet på det fält som anges av `USERNAME_FIELD`.

#### `clean()`

Normaliserar användarnamnet genom att anropa [`normalize_username()`](#django.contrib.auth.models.AbstractBaseUser.normalize_username). Om du åsidosätter den här metoden, se till att anropa `super()` för att behålla normaliseringen.

#### `classmethod get_email_field_name()`

Returnerar namnet på det e-postfält som anges av attributet [`EMAIL_FIELD`](#django.contrib.auth.models.CustomUser.EMAIL_FIELD). Standardvärdet är `'email'` om `EMAIL_FIELD` inte har angetts.

#### `classmethod normalize_username(username)`

Tillämpar NFKC Unicode-normalisering på användarnamn så att visuellt identiska tecken med olika Unicode-kodpunkter betraktas som identiska.

#### `is_authenticated`

Skrivskyddat attribut som alltid är `True` (i motsats till `AnonymousUser.is_authenticated` som alltid är `False`). Det här är ett sätt att se om användaren har autentiserats. Det innebär inte några behörigheter och kontrollerar inte om användaren är aktiv eller har en giltig session. Även om du normalt kommer att kontrollera detta attribut på `request.user` för att ta reda på om det har fyllts i av [`AuthenticationMiddleware`](/sv/6.1/ref/middleware/#django.contrib.auth.middleware.AuthenticationMiddleware) (som representerar den för närvarande inloggade användaren), bör du veta att detta attribut är `True` för alla [`User`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User)-instanser.

#### `is_anonymous`

Skrivskyddat attribut som alltid är `False`. Detta är ett sätt att skilja mellan objekten [`User`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User) och [`AnonymousUser`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.AnonymousUser). Generellt sett bör du föredra att använda [`is_authenticated`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User.is_authenticated) framför detta attribut.

#### `set_password(raw_password)`

Ställer in användarens lösenord till den angivna råsträngen och tar hand om lösenordshashningen. Sparar inte [`AbstractBaseUser`](#django.contrib.auth.models.AbstractBaseUser)-objektet.

When the raw\_password is `None`, the password will be set to an
unusable password, as if
[`set_unusable_password()`](#django.contrib.auth.models.AbstractBaseUser.set_unusable_password)
were used.

#### `check_password(raw_password)`

#### `acheck_password(raw_password)`

*Asynkron version*: `acheck_password()`

Returnerar `True` om den angivna råsträngen är rätt lösenord för användaren. (Detta tar hand om lösenordets hashing vid jämförelsen.)

#### `set_unusable_password()`

Marks the user as having no password set. This isn’t the same as
having a blank string for a password.
[`check_password()`](#django.contrib.auth.models.AbstractBaseUser.check_password) for
this user will never return `True`. Doesn’t save the
[`AbstractBaseUser`](#django.contrib.auth.models.AbstractBaseUser) object.

Du kan behöva detta om autentiseringen för din applikation sker mot en befintlig extern källa, t.ex. en LDAP-katalog.

#### `has_usable_password()`

Returns `False` if
[`set_unusable_password()`](#django.contrib.auth.models.AbstractBaseUser.set_unusable_password)
has been called for this user.

#### `get_session_auth_hash()`

Returnerar en HMAC för lösenordsfältet. Används för [Inaktivering av session vid byte av lösenord](/sv/6.1/topics/auth/default/#session-invalidation-on-password-change).

#### `get_session_auth_fallback_hash()`

Ger HMAC för lösenordsfältet med hjälp av [`SECRET_KEY_FALLBACKS`](/sv/6.1/ref/settings/#std-setting-SECRET_KEY_FALLBACKS). Används av `get_user()`.

[`AbstractUser`](#django.contrib.auth.models.AbstractUser) subclasses [`AbstractBaseUser`](#django.contrib.auth.models.AbstractBaseUser):

#### `class models.AbstractUser`

#### `clean()`

Normaliserar e-postmeddelandet genom att anropa [`BaseUserManager.normalize_email()`](#django.contrib.auth.models.BaseUserManager.normalize_email). Om du åsidosätter den här metoden, se till att anropa `super()` för att behålla normaliseringen.

### Skriva en manager för en anpassad användarmodell

Du bör också definiera en anpassad manager för din användarmodell. Om din användarmodell definierar fälten `username`, `email`, `is_staff`, `is_active`, `is_superuser`, `last_login` och `date_joined` på samma sätt som Djangos standardanvändare, kan du installera Djangos [`UserManager`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.UserManager); men om din användarmodell definierar olika fält måste du definiera en anpassad manager som utökar [`BaseUserManager`](#django.contrib.auth.models.BaseUserManager) med ytterligare två metoder:

#### `class models.CustomUserManager`

#### `create_user(username_field, password=None, **other_fields)`

Prototypen för `create_user()` bör acceptera användarnamnsfältet plus alla obligatoriska fält som argument. Om din användarmodell till exempel använder `email` som användarnamnsfält och har `date_of_birth` som ett obligatoriskt fält, bör `create_user` definieras som:

```
def create_user(self, email, date_of_birth, password=None):
    # create user here
    ...
```

#### `create_superuser(username_field, password=None, **other_fields)`

Prototypen för `create_superuser()` bör acceptera användarnamnsfältet plus alla obligatoriska fält som argument. Om din användarmodell till exempel använder `email` som användarnamnsfält och har `date_of_birth` som ett obligatoriskt fält, bör `create_superuser` definieras som:

```
def create_superuser(self, email, date_of_birth, password=None):
    # create superuser here
    ...
```

För en [`ForeignKey`](/sv/6.1/ref/models/fields/#django.db.models.ForeignKey) i [`USERNAME_FIELD`](#django.contrib.auth.models.CustomUser.USERNAME_FIELD) eller [`REQUIRED_FIELDS`](#django.contrib.auth.models.CustomUser.REQUIRED_FIELDS) får dessa metoder värdet av [`to_field`](/sv/6.1/ref/models/fields/#django.db.models.ForeignKey.to_field) (standard [`primary_key`](/sv/6.1/ref/models/fields/#django.db.models.Field.primary_key)) i en befintlig instans.

[`BaseUserManager`](#django.contrib.auth.models.BaseUserManager) tillhandahåller följande verktygsmetoder:

#### `class models.BaseUserManager`

#### `classmethod normalize_email(email)`

Normaliserar e-postadresser genom att skriva domändelen av e-postadressen med liten bokstav.

#### `get_by_natural_key(username)`

#### `aget_by_natural_key(username)`

*Asynkron version*: `aget_by_natural_key()`

Hämtar en användarinstans med hjälp av innehållet i det fält som anges av `USERNAME_FIELD`.

### Utökning av Djangos förvalda `User`

Om du är helt nöjd med Djangos [`User`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User)-modell, men du vill lägga till ytterligare profilinformation, kan du underordna [`django.contrib.auth.models.AbstractUser`](#django.contrib.auth.models.AbstractUser) och lägga till dina egna profilfält, även om vi rekommenderar en separat modell som beskrivs i [Ange en anpassad användarmodell](#specifying-custom-user-model). `AbstractUser` ger den fullständiga implementeringen av standard [`User`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User) som en [abstrakt modell](/sv/6.1/topics/db/models/#abstract-base-classes).

### Anpassade användare och de inbyggda autentiseringsformulären

Djangos inbyggda [forms](/sv/6.1/topics/auth/default/#built-in-auth-forms) och [views](/sv/6.1/topics/auth/default/#built-in-auth-views) gör vissa antaganden om den användarmodell som de arbetar med.

Följande formulär är kompatibla med alla underklasser av [`AbstractBaseUser`](#django.contrib.auth.models.AbstractBaseUser):

- [`AuthenticationForm`](/sv/6.1/topics/auth/default/#django.contrib.auth.forms.AuthenticationForm): Använder användarnamnsfältet som anges av [`USERNAME_FIELD`](#django.contrib.auth.models.CustomUser.USERNAME_FIELD).
- [`SetPasswordForm`](/sv/6.1/topics/auth/default/#django.contrib.auth.forms.SetPasswordForm)
- [`PasswordChangeForm`](/sv/6.1/topics/auth/default/#django.contrib.auth.forms.PasswordChangeForm)
- [`AdminPasswordChangeForm`](/sv/6.1/topics/auth/default/#django.contrib.auth.forms.AdminPasswordChangeForm)

Följande formulär innehåller antaganden om användarmodellen och kan användas som de är om dessa antaganden uppfylls:

- [`PasswordResetForm`](/sv/6.1/topics/auth/default/#django.contrib.auth.forms.PasswordResetForm): Antar att användarmodellen har ett fält som lagrar användarens e-postadress med det namn som returneras av [`get_email_field_name()`](#django.contrib.auth.models.AbstractBaseUser.get_email_field_name) (`email` som standard) som kan användas för att identifiera användaren och ett booleskt fält med namnet `is_active` för att förhindra återställning av lösenord för inaktiva användare.

Slutligen är följande formulär knutna till [`User`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User) och måste skrivas om eller utökas för att fungera med en anpassad användarmodell:

- [`UserCreationForm`](/sv/6.1/topics/auth/default/#django.contrib.auth.forms.UserCreationForm)
- [`UserChangeForm`](/sv/6.1/topics/auth/default/#django.contrib.auth.forms.UserChangeForm)

Om din anpassade användarmodell är en underklass till `AbstractUser` kan du utöka dessa formulär på följande sätt:

```
from django.contrib.auth.forms import UserCreationForm
from myapp.models import CustomUser

class CustomUserCreationForm(UserCreationForm):
    class Meta(UserCreationForm.Meta):
        model = CustomUser
        fields = UserCreationForm.Meta.fields + ("custom_field",)
```

### Anpassade användare och [`django.contrib.admin`](/sv/6.1/ref/contrib/admin/#module-django.contrib.admin)

Om du vill att din anpassade användarmodell även ska fungera med administratören måste din användarmodell definiera ytterligare några attribut och metoder. Dessa metoder gör det möjligt för administratören att kontrollera användarens åtkomst till administratörsinnehåll:

#### `class models.CustomUser`

#### `is_staff`

Returnerar `True` om användaren har rätt att få åtkomst till administratörssidan.

#### `is_active`

Returnerar `True` om användarkontot för närvarande är aktivt.

#### `has_perm(perm, obj=None):`

Returnerar `True` om användaren har den angivna behörigheten. Om `obj` anges måste behörigheten kontrolleras mot en specifik objektinstans.

#### `has_module_perms(app_label):`

Returnerar `True` om användaren har behörighet att komma åt modeller i den angivna appen.

Du måste också registrera din anpassade användarmodell hos administratören. Om din anpassade användarmodell utökar `django.contrib.auth.models.AbstractUser` kan du använda Djangos befintliga `django.contrib.auth.admin.UserAdmin`-klass. Men om din användarmodell utökar `` AbstractBaseUser` ``, måste du definiera en anpassad `ModelAdmin` klass. Det kan vara möjligt att underordna standardklassen `django.contrib.auth.admin.UserAdmin`; du måste dock åsidosätta alla definitioner som hänvisar till fält på `django.contrib.auth.models.AbstractUser` som inte finns i din anpassade användarklass.

> **Note**
>
> Om du använder en anpassad `ModelAdmin` som är en underklass av `django.contrib.auth.admin.UserAdmin`, måste du lägga till dina anpassade fält till `fieldsets` (för fält som ska användas vid redigering av användare) och till `add_fieldsets` (för fält som ska användas när du skapar en användare). Till exempel:
>
> ```
> from django.contrib.auth.admin import UserAdmin
>
>
> class CustomUserAdmin(UserAdmin):
>     ...
>     fieldsets = UserAdmin.fieldsets + ((None, {"fields": ["custom_field"]}),)
>     add_fieldsets = UserAdmin.add_fieldsets + ((None, {"fields": ["custom_field"]}),)
> ```
>
> Se [ett fullständigt exempel](#custom-users-admin-full-example) för mer information.

### Anpassade användare och behörigheter

För att göra det enkelt att inkludera Djangos behörighetsramverk i din egen användarklass tillhandahåller Django [`PermissionsMixin`](#django.contrib.auth.models.PermissionsMixin). Detta är en abstrakt modell som du kan inkludera i klasshierarkin för din användarmodell, vilket ger dig alla metoder och databasfält som krävs för att stödja Djangos behörighetsmodell.

[`PermissionsMixin`](#django.contrib.auth.models.PermissionsMixin) tillhandahåller följande metoder och attribut:

#### `class models.PermissionsMixin`

#### `is_superuser`

Boolesk. Anger att den här användaren har alla behörigheter utan att uttryckligen ha tilldelats dem.

#### `get_user_permissions(obj=None)`

Returnerar en uppsättning behörighetssträngar som användaren har direkt.

Om `obj` anges returneras endast användarrättigheterna för detta specifika objekt.

#### `get_group_permissions(obj=None)`

Returnerar en uppsättning behörighetssträngar som användaren har via sina grupper.

Om `obj` anges returneras endast gruppbehörigheterna för detta specifika objekt.

#### `get_all_permissions(obj=None)`

Returnerar en uppsättning behörighetssträngar som användaren har, både genom grupp- och användarbehörigheter.

Om `obj` anges returneras endast behörigheterna för detta specifika objekt.

#### `has_perm(perm, obj=None)`

Returnerar `True` om användaren har den angivna behörigheten, där `perm` är i formatet `"<app label>.<permission codename>"` (se permissions \<topic-authorization\>\`). Om [`User.is_active`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User.is_active) och [`is_superuser`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User.is_superuser) båda är `True` returnerar denna metod alltid `True`.

Om `obj` skickas in kommer denna metod inte att söka efter en behörighet för modellen, utan för detta specifika objekt.

#### `has_perms(perm_list, obj=None)`

Returnerar `True` om användaren har alla de angivna behörigheterna, där varje behörighet är i formatet `"<app label>.<permission codename>"`. Om [`User.is_active`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User.is_active) och [`is_superuser`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User.is_superuser) båda är `True` returnerar denna metod alltid `True`.

Om `obj` anges kommer den här metoden inte att kontrollera behörigheter för modellen, utan för det specifika objektet.

#### `has_module_perms(package_name)`

Returnerar `True` om användaren har några behörigheter i det angivna paketet (Django-appens etikett). Om [`User.is_active`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User.is_active) och [`is_superuser`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User.is_superuser) båda är `True`, returnerar denna metod alltid `True`.

> **PermissionsMixin och ModelBackend**
>
> Om du inte inkluderar [`PermissionsMixin`](#django.contrib.auth.models.PermissionsMixin), måste du se till att du inte anropar behörighetsmetoderna på `ModelBackend`. `ModelBackend` förutsätter att vissa fält är tillgängliga i din användarmodell. Om din användarmodell inte tillhandahåller dessa fält kommer du att få databasfel när du kontrollerar behörigheter.

### Anpassade användare och proxymodeller

En begränsning med anpassade användarmodeller är att installation av en anpassad användarmodell kommer att bryta alla proxymodeller som utökar [`User`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User). Proxymodeller måste baseras på en konkret basklass; genom att definiera en anpassad användarmodell tar du bort Djangos förmåga att på ett tillförlitligt sätt identifiera basklassen.

Om ditt projekt använder proxymodeller måste du antingen ändra proxyn för att utöka den användarmodell som används i ditt projekt, eller slå samman din proxys beteende i din [`User`](/sv/6.1/ref/contrib/auth/#django.contrib.auth.models.User)-underklass.

### Ett fullständigt exempel

Här är ett exempel på en anpassad användarapp som är kompatibel med administratörer. Denna användarmodell använder en e-postadress som användarnamn och har ett obligatoriskt födelsedatum; den ger ingen behörighetskontroll utöver en `admin`-flagga på användarkontot. Den här modellen skulle vara kompatibel med alla inbyggda auth-formulär och -vyer, förutom formulären för att skapa användare. Detta exempel illustrerar hur de flesta komponenterna fungerar tillsammans, men är inte avsett att kopieras direkt till projekt för produktionsanvändning.

Denna kod skulle alla leva i en `models.py`-fil för en anpassad autentiseringsapp:

```
from django.db import models
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser

class MyUserManager(BaseUserManager):
    def create_user(self, email, date_of_birth, password=None):
        """
        Creates and saves a User with the given email, date of
        birth and password.
        """
        if not email:
            raise ValueError("Users must have an email address")

        user = self.model(
            email=self.normalize_email(email),
            date_of_birth=date_of_birth,
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, date_of_birth, password=None):
        """
        Creates and saves a superuser with the given email, date of
        birth and password.
        """
        user = self.create_user(
            email,
            password=password,
            date_of_birth=date_of_birth,
        )
        user.is_admin = True
        user.save(using=self._db)
        return user

class MyUser(AbstractBaseUser):
    email = models.EmailField(
        verbose_name="email address",
        max_length=255,
        unique=True,
    )
    date_of_birth = models.DateField()
    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    objects = MyUserManager()

    USERNAME_FIELD = "email"
    REQUIRED_FIELDS = ["date_of_birth"]

    def __str__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

    def has_module_perms(self, app_label):
        "Does the user have permissions to view the app `app_label`?"
        # Simplest possible answer: Yes, always
        return True

    @property
    def is_staff(self):
        "Is the user a member of staff?"
        # Simplest possible answer: All admins are staff
        return self.is_admin
```

För att sedan registrera denna anpassade användarmodell med Djangos admin krävs följande kod i appens fil `admin.py`:

```
from django import forms
from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.core.exceptions import ValidationError

from customauth.models import MyUser

class UserCreationForm(forms.ModelForm):
    """A form for creating new users. Includes all the required
    fields, plus a repeated password."""

    password1 = forms.CharField(label="Password", widget=forms.PasswordInput)
    password2 = forms.CharField(
        label="Password confirmation", widget=forms.PasswordInput
    )

    class Meta:
        model = MyUser
        fields = ["email", "date_of_birth"]

    def clean_password2(self):
        # Check that the two password entries match
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise ValidationError("Passwords don't match")
        return password2

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super().save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user

class UserChangeForm(forms.ModelForm):
    """A form for updating users. Includes all the fields on
    the user, but replaces the password field with admin's
    disabled password hash display field.
    """

    password = ReadOnlyPasswordHashField()

    class Meta:
        model = MyUser
        fields = ["email", "password", "date_of_birth", "is_active", "is_admin"]

class UserAdmin(BaseUserAdmin):
    # The forms to add and change user instances
    form = UserChangeForm
    add_form = UserCreationForm

    # The fields to be used in displaying the User model.
    # These override the definitions on the base UserAdmin
    # that reference specific fields on auth.User.
    list_display = ["email", "date_of_birth", "is_admin"]
    list_filter = ["is_admin"]
    fieldsets = [
        (None, {"fields": ["email", "password"]}),
        ("Personal info", {"fields": ["date_of_birth"]}),
        ("Permissions", {"fields": ["is_admin"]}),
    ]
    # add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
    # overrides get_fieldsets to use this attribute when creating a user.
    add_fieldsets = [
        (
            None,
            {
                "classes": ["wide"],
                "fields": ["email", "date_of_birth", "password1", "password2"],
            },
        ),
    ]
    search_fields = ["email"]
    ordering = ["email"]
    filter_horizontal = []

# Now register the new UserAdmin...
admin.site.register(MyUser, UserAdmin)
# ... and, since we're not using Django's built-in permissions,
# unregister the Group model from admin.
admin.site.unregister(Group)
```

Slutligen anger du den anpassade modellen som standardanvändarmodell för ditt projekt med hjälp av inställningen [`AUTH_USER_MODEL`](/sv/6.1/ref/settings/#std-setting-AUTH_USER_MODEL) i din `settings.py`:

```
AUTH_USER_MODEL = "customauth.MyUser"
```

#### Lägga till ett async-gränssnitt

För att optimera prestanda när den anropas från en asynkron kontextautentisering kan backends implementera asynkrona versioner av varje funktion - `aget_user(user_id)` och `aauthenticate(request, **credentials)`. När en autentiseringsbackend utökar `BaseBackend` och async-versioner av dessa funktioner inte tillhandahålls, kommer de automatiskt att syntetiseras med `sync_to_async`. Detta har [performance penalties](/sv/6.1/topics/async/#async-performance).

Medan ett asynkront gränssnitt är valfritt, krävs alltid ett synkront gränssnitt. Det finns ingen automatisk syntes för ett synkront gränssnitt om ett asynkront gränssnitt är implementerat.

Djangos out-of-the-box autentiseringsbackends har inbyggt async-stöd. Om dessa inbyggda backends utökas, var särskilt noga med att se till att async-versionerna av modifierade funktioner också modifieras.
