---
title: "Filuppladdning"
version: 5.2
locale: sv
source: https://docs.djangoproject.com/sv/5.2/topics/http/file-uploads/
canonical: https://djangodocs.dev/sv/5.2/topics/http/file-uploads/
---
# Filuppladdning

När Django hanterar en filuppladdning placeras filinformationen i [`request.FILES`](/sv/5.2/ref/request-response/#django.http.HttpRequest.FILES) (för mer information om objektet `request` se dokumentationen för [request and response objects](/sv/5.2/ref/request-response/)). I det här dokumentet förklaras hur filer lagras på disk och i minne och hur du anpassar standardbeteendet.

> **Warning**
>
> Det finns säkerhetsrisker om du accepterar uppladdat innehåll från icke betrodda användare! Se säkerhetsguidens ämne om [Innehåll som laddats upp av användare](/sv/5.2/topics/security/#user-uploaded-content-security) för mer information om begränsning.

## Grundläggande filuppladdningar

Tänk dig ett formulär som innehåller en [`FileField`](/sv/5.2/ref/forms/fields/#django.forms.FileField):

*`forms.py`*

```python
from django import forms

class UploadFileForm(forms.Form):
    title = forms.CharField(max_length=50)
    file = forms.FileField()
```

En vy som hanterar detta formulär kommer att få filinformationen i [`request.FILES`](/sv/5.2/ref/request-response/#django.http.HttpRequest.FILES), som är en ordbok som innehåller en nyckel för varje [`FileField`](/sv/5.2/ref/forms/fields/#django.forms.FileField) (eller [`ImageField`](/sv/5.2/ref/forms/fields/#django.forms.ImageField), eller annan [`FileField`](/sv/5.2/ref/forms/fields/#django.forms.FileField) subklass) i formuläret. Så data från ovanstående formulär skulle vara tillgängliga som `request.FILES['file']`.

Observera att `` request.FILES <django.http.HttpRequest.FILES>` `` endast kommer att innehålla data om förfrågningsmetoden var `POST`, minst ett filfält faktiskt postades och `<form>` som postade förfrågan har attributet `enctype="multipart/form-data"`. Annars kommer `request.FILES` att vara tomt.

För det mesta kommer du att skicka filinformationen från `request` till formuläret enligt beskrivningen i [Binder uppladdade filer till ett formulär](/sv/5.2/ref/forms/api/#binding-uploaded-files). Detta skulle se ut ungefär som:

*`Vyer.py`*

```python
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import UploadFileForm

# Imaginary function to handle an uploaded file.
from somewhere import handle_uploaded_file

def upload_file(request):
    if request.method == "POST":
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            handle_uploaded_file(request.FILES["file"])
            return HttpResponseRedirect("/success/url/")
    else:
        form = UploadFileForm()
    return render(request, "upload.html", {"form": form})
```

Observera att vi måste skicka [`request.FILES`](/sv/5.2/ref/request-response/#django.http.HttpRequest.FILES) till formulärets konstruktör; det är så här fildata binds till ett formulär.

Här är ett vanligt sätt att hantera en uppladdad fil:

```
def handle_uploaded_file(f):
    with open("some/file/name.txt", "wb+") as destination:
        for chunk in f.chunks():
            destination.write(chunk)
```

Genom att loopa över `UploadedFile.chunks()` istället för att använda `read()` säkerställs att stora filer inte överbelastar systemets minne.

Det finns några andra metoder och attribut som är tillgängliga för `UploadedFile`-objekt; se [`UploadedFile`](/sv/5.2/ref/files/uploads/#django.core.files.uploadedfile.UploadedFile) för en fullständig referens.

### Hantera uppladdade filer med en modell

Om du sparar en fil på en [`Model`](/sv/5.2/ref/models/instances/#django.db.models.Model) med en [`FileField`](/sv/5.2/ref/models/fields/#django.db.models.FileField), kan du använda en [`ModelForm`](/sv/5.2/topics/forms/modelforms/#django.forms.ModelForm) som gör processen mycket enklare. Filobjektet kommer att sparas på den plats som anges av [`upload_to`](/sv/5.2/ref/models/fields/#django.db.models.FileField.upload_to)-argumentet för motsvarande [`FileField`](/sv/5.2/ref/models/fields/#django.db.models.FileField) när du anropar `form.save()`:

```
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import ModelFormWithFileField

def upload_file(request):
    if request.method == "POST":
        form = ModelFormWithFileField(request.POST, request.FILES)
        if form.is_valid():
            # file is saved
            form.save()
            return HttpResponseRedirect("/success/url/")
    else:
        form = ModelFormWithFileField()
    return render(request, "upload.html", {"form": form})
```

Om du konstruerar ett objekt manuellt kan du tilldela filobjektet från [`request.FILES`](/sv/5.2/ref/request-response/#django.http.HttpRequest.FILES) till filfältet i modellen:

```
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import UploadFileForm
from .models import ModelWithFileField

def upload_file(request):
    if request.method == "POST":
        form = UploadFileForm(request.POST, request.FILES)
        if form.is_valid():
            instance = ModelWithFileField(file_field=request.FILES["file"])
            instance.save()
            return HttpResponseRedirect("/success/url/")
    else:
        form = UploadFileForm()
    return render(request, "upload.html", {"form": form})
```

Om du konstruerar ett objekt manuellt utanför en begäran kan du tilldela ett [`File`](/sv/5.2/ref/files/file/#django.core.files.File) liknande objekt till [`FileField`](/sv/5.2/ref/models/fields/#django.db.models.FileField):

```
from django.core.management.base import BaseCommand
from django.core.files.base import ContentFile

class MyCommand(BaseCommand):
    def handle(self, *args, **options):
        content_file = ContentFile(b"Hello world!", name="hello-world.txt")
        instance = ModelWithFileField(file_field=content_file)
        instance.save()
```

### Ladda upp flera filer

Om du vill ladda upp flera filer med ett formulärfält skapar du en underklass av fältets widget och ställer in klassattributet `allow_multiple_selected` på `True`.

För att alla sådana filer ska kunna valideras av ditt formulär (och fältets värde ska inkludera dem alla) måste du också underklassa `FileField`. Se nedan för ett exempel.

> **Fält för flera filer**
>
> Django kommer sannolikt att ha ett ordentligt stöd för flera filfält någon gång i framtiden.

*`forms.py`*

```python
from django import forms

class MultipleFileInput(forms.ClearableFileInput):
    allow_multiple_selected = True

class MultipleFileField(forms.FileField):
    def __init__(self, *args, **kwargs):
        kwargs.setdefault("widget", MultipleFileInput())
        super().__init__(*args, **kwargs)

    def clean(self, data, initial=None):
        single_file_clean = super().clean
        if isinstance(data, (list, tuple)):
            result = [single_file_clean(d, initial) for d in data]
        else:
            result = [single_file_clean(data, initial)]
        return result

class FileFieldForm(forms.Form):
    file_field = MultipleFileField()
```

Åsidosätt sedan metoden `form_valid()` i din [`FormView`](/sv/5.2/ref/class-based-views/generic-editing/#django.views.generic.edit.FormView)-underklass för att hantera flera filuppladdningar:

*`Vyer.py`*

```python
from django.views.generic.edit import FormView
from .forms import FileFieldForm

class FileFieldFormView(FormView):
    form_class = FileFieldForm
    template_name = "upload.html"  # Replace with your template.
    success_url = "..."  # Replace with your URL or reverse().

    def form_valid(self, form):
        files = form.cleaned_data["file_field"]
        for f in files:
            ...  # Do something with each file.
        return super().form_valid(form)
```

> **Warning**
>
> Detta gör att du kan hantera flera filer endast på formulärnivå. Tänk på att du inte kan använda den för att lägga till flera filer på en enda modellinstans (i ett enda fält), till exempel även om den anpassade widgeten används med ett formulärfält som är relaterat till en modell `FileField`.

## Uppladdningshanterare

När en användare laddar upp en fil skickar Django filinformationen till en *uppladdningshanterare* \- en liten klass som hanterar filinformationen när den laddas upp. Uppladdningshanterare definieras initialt i inställningen [`FILE_UPLOAD_HANDLERS`](/sv/5.2/ref/settings/#std-setting-FILE_UPLOAD_HANDLERS), som har standardvärdet:

```
[
    "django.core.files.uploadhandler.MemoryFileUploadHandler",
    "django.core.files.uploadhandler.TemporaryFileUploadHandler",
]
```

Tillsammans tillhandahåller [`MemoryFileUploadHandler`](/sv/5.2/ref/files/uploads/#django.core.files.uploadhandler.MemoryFileUploadHandler) och [`TemporaryFileUploadHandler`](/sv/5.2/ref/files/uploads/#django.core.files.uploadhandler.TemporaryFileUploadHandler) Djangos standardbeteende för filuppladdning genom att läsa små filer i minnet och stora filer på disken.

Du kan skriva egna handlers som anpassar hur Django hanterar filer. Du kan till exempel använda anpassade hanterare för att genomdriva kvoter på användarnivå, komprimera data i farten, rendera förloppsbalkar och till och med skicka data till en annan lagringsplats direkt utan att lagra dem lokalt. Se [Skriva anpassade uppladdningshanterare](/sv/5.2/ref/files/uploads/#custom-upload-handlers) för detaljer om hur du kan anpassa eller helt ersätta uppladdningsbeteendet.

### Var uppladdade data lagras

Innan du sparar uppladdade filer måste data lagras någonstans.

Som standard, om en uppladdad fil är mindre än 2,5 megabyte, kommer Django att hålla hela innehållet i uppladdningen i minnet. Det innebär att när filen sparas sker endast en läsning från minnet och en skrivning till disken och det går därför mycket snabbt.

Men om en uppladdad fil är för stor kommer Django att skriva den uppladdade filen till en temporär fil som lagras i ditt systems temporära katalog. På en Unix-liknande plattform betyder det att du kan förvänta dig att Django genererar en fil som heter något i stil med `/tmp/tmpzfp6I6.upload`. Om en uppladdning är tillräckligt stor kan du se den här filen växa i storlek när Django strömmar data till disken.

Dessa specifikationer – 2,5 megabyte; `/tmp`; etc. – är ”rimliga standardvärden” som kan anpassas enligt beskrivningen i nästa avsnitt.

### Ändra beteende för uppladdningshanterare

Det finns några inställningar som styr Djangos filuppladdningsbeteende. Se [Filuppladdningsinställningar](/sv/5.2/ref/settings/#file-upload-settings) för detaljer.

### Ändra uppladdningshanterare i farten

Ibland kräver särskilda vyer olika uppladdningsbeteende. I dessa fall kan du åsidosätta uppladdningshanterare per begäran genom att ändra `request.upload_handlers`. Som standard innehåller den här listan de uppladdningshanterare som anges av [`FILE_UPLOAD_HANDLERS`](/sv/5.2/ref/settings/#std-setting-FILE_UPLOAD_HANDLERS), men du kan ändra listan som du skulle göra med vilken annan lista som helst.

Anta till exempel att du har skrivit en `ProgressBarUploadHandler` som ger feedback om uppladdningsförloppet till någon form av AJAX-widget. Du skulle lägga till den här hanteraren till dina uppladdningshanterare så här:

```
request.upload_handlers.insert(0, ProgressBarUploadHandler(request))
```

Genom att använda `list.insert()`, som visas ovan, säkerställs att förloppsindikatorn placeras i början av listan. Eftersom uppladdningshanterare exekveras i ordning garanterar denna placering att förloppsindikatorn körs före standardhanterarna, vilket gör att den kan spåra förloppet under hela uppladdningen.

Om du vill ersätta uppladdningshanterarna helt och hållet kan du tilldela en ny lista:

```
request.upload_handlers = [ProgressBarUploadHandler(request)]
```

> **Note**
>
> Du kan bara ändra uppladdningshanterare *före* åtkomst till `request.POST` eller `request.FILES` \- det är inte meningsfullt att ändra uppladdningshanterare efter att uppladdningshanteringen redan har börjat. Om du försöker ändra `request.upload_handlers` efter att ha läst från `request.POST` eller `request.FILES` kommer Django att ge ett felmeddelande.
>
> Därför bör du alltid modifiera uppladdningshanterare så tidigt som möjligt i din vy.
>
> Dessutom nås `request.POST` av [`CsrfViewMiddleware`](/sv/5.2/ref/middleware/#django.middleware.csrf.CsrfViewMiddleware) som är aktiverat som standard. Detta innebär att du måste använda [`csrf_exempt()`](/sv/5.2/ref/csrf/#django.views.decorators.csrf.csrf_exempt) på din vy för att du ska kunna ändra uppladdningshanterarna.  Du måste sedan använda [`csrf_protect()`](/sv/5.2/ref/csrf/#django.views.decorators.csrf.csrf_protect) på den funktion som faktiskt behandlar begäran.  Observera att detta innebär att hanterarna kan börja ta emot filuppladdningen innan CSRF-kontrollerna har gjorts. Exempel på kod:
>
> ```
> from django.views.decorators.csrf import csrf_exempt, csrf_protect
>
>
> @csrf_exempt
> def upload_file_view(request):
>     request.upload_handlers.insert(0, ProgressBarUploadHandler(request))
>     return _upload_file_view(request)
>
>
> @csrf_protect
> def _upload_file_view(request):
>     # Process request
>     ...
> ```
>
> Om du använder en klassbaserad vy måste du använda [`csrf_exempt()`](/sv/5.2/ref/csrf/#django.views.decorators.csrf.csrf_exempt) på dess [`dispatch()`](/sv/5.2/ref/class-based-views/base/#django.views.generic.base.View.dispatch) metod och [`csrf_protect()`](/sv/5.2/ref/csrf/#django.views.decorators.csrf.csrf_protect) på den metod som faktiskt behandlar förfrågan. Exempel på kod:
>
> ```
> from django.utils.decorators import method_decorator
> from django.views import View
> from django.views.decorators.csrf import csrf_exempt, csrf_protect
>
>
> @method_decorator(csrf_exempt, name="dispatch")
> class UploadFileView(View):
>     def setup(self, request, *args, **kwargs):
>         request.upload_handlers.insert(0, ProgressBarUploadHandler(request))
>         super().setup(request, *args, **kwargs)
>
>     @method_decorator(csrf_protect)
>     def post(self, request, *args, **kwargs):
>         # Process request
>         ...
> ```
