---
title: "“Upload” de arquivos"
version: 6.1
locale: pt-br
source: https://docs.djangoproject.com/pt-br/6.1/topics/http/file-uploads/
canonical: https://djangodocs.dev/pt-br/6.1/topics/http/file-uploads/
---
# “Upload” de arquivos

Quando o Django lida com o upload de arquivos, o arquivo de dados termina sendo colocado em [`request.FILES`](/pt-br/6.1/ref/request-response/#django.http.HttpRequest.FILES) (para mais sobre o objeto `request` veja a documentação sobre [objetos de requisição e resposta](/pt-br/6.1/ref/request-response/)). Este documento explica como arquivos são armazenados no disco ou na memória, e como personalizar o comportamento padrão.

> **Warning**
>
> Existem riscos de segurança se você estiver aceitando o upload de conteúdo de usuários não confiáveis! Veja o tópico do guia de segurança em [Conteúdo carregado por upload de usuários](/pt-br/6.1/topics/security/#user-uploaded-content-security) para detalhes.

## Básico sobre upload de arquivos

Consider a form containing a [`FileField`](/pt-br/6.1/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()
```

Uma “view” que lida com este formulário irá receber o arquivo em [`request.FILES`](/pt-br/6.1/ref/request-response/#django.http.HttpRequest.FILES), o qual é um dicionário contendo uma chave para cada [`FileField`](/pt-br/6.1/ref/forms/fields/#django.forms.FileField) (ou [`ImageField`](/pt-br/6.1/ref/forms/fields/#django.forms.ImageField), ou outra subclasse de [`FileField`](/pt-br/6.1/ref/forms/fields/#django.forms.FileField)) no formulário. Tal que os dados vindos do formulário acima devem estar acessíveis como `request.FILES['file']`.

Note that [`request.FILES`](/pt-br/6.1/ref/request-response/#django.http.HttpRequest.FILES) will only
contain data if the request method was `POST`, at least one file field was
actually posted, and the `<form>` that posted the request has the attribute
`enctype="multipart/form-data"`. Otherwise, `request.FILES` will be empty.

Most of the time, you’ll pass the file data from `request` into the form as
described in [Binding uploaded files to a form](/pt-br/6.1/ref/forms/api/#binding-uploaded-files). This would look something like:

*`views.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})
```

Note que temos que passar [`request.FILES`](/pt-br/6.1/ref/request-response/#django.http.HttpRequest.FILES) para o construtor do “form”; é assim que os dados do arquivo entra no form.

Aqui uma maneira comum que você talvez lide com o “upload” de arquivo:

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

Fazendo “loops” sobre `UploadedFile.chunks()` ao invés de usar o `read()` garante que grandes arquivos não vão forçar a memória do seu sistema.

Existem alguns outros métodos e atributos disponíveis nos objetos `UploadedFile`; veja a [`UploadedFile`](/pt-br/6.1/ref/files/uploads/#django.core.files.uploadedfile.UploadedFile) para uma completa referência.

### Lindando com o “upload” de arquivos com um modelo.

Se você está usando um arquivo em uma [`Model`](/pt-br/6.1/ref/models/instances/#django.db.models.Model) com uma [`FileField`](/pt-br/6.1/ref/models/fields/#django.db.models.FileField), usando uma [`ModelForm`](/pt-br/6.1/topics/forms/modelforms/#django.forms.ModelForm) faz este processo bem mais fácil. O objeto arquivo será salvo em um local especificado pelo argumento [`upload_to`](/pt-br/6.1/ref/models/fields/#django.db.models.FileField.upload_to) do [`FileField`](/pt-br/6.1/ref/models/fields/#django.db.models.FileField) correspondente quando chamar `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})
```

If you are constructing an object manually, you can assign the file object from
[`request.FILES`](/pt-br/6.1/ref/request-response/#django.http.HttpRequest.FILES) to the file field in the
model:

```
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})
```

If you are constructing an object manually outside of a request, you can assign
a [`File`](/pt-br/6.1/ref/files/file/#django.core.files.File) like object to the
[`FileField`](/pt-br/6.1/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()
```

### Enviando múltiplos arquivos

If you want to upload multiple files using one form field, create a subclass
of the field’s widget and set its `allow_multiple_selected` class attribute
to `True`.

In order for such files to be all validated by your form (and have the value of
the field include them all), you will also have to subclass `FileField`. See
below for an example.

> **Multiple file field**
>
> Django is likely to have a proper multiple file field support at some point
> in the future.

*`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()
```

Then override the `form_valid()` method of your
[`FormView`](/pt-br/6.1/ref/class-based-views/generic-editing/#django.views.generic.edit.FormView) subclass to handle multiple file
uploads:

*`views.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**
>
> This will allow you to handle multiple files at the form level only. Be
> aware that you cannot use it to put multiple files on a single model
> instance (in a single field), for example, even if the custom widget is used
> with a form field related to a model `FileField`.

## Manipuladores de envios de arquivos

Quando um usuário envia um arquivo, o Django passa os dados do arquivo para um \* manipular de envio de arquivo\* – uma pequena classe que lida com dados de arquivos enquanto este é enviado. Manipuladores de envio de arquivo não inicialmente definidos na definição [`FILE_UPLOAD_HANDLERS`](/pt-br/6.1/ref/settings/#std-setting-FILE_UPLOAD_HANDLERS) o qual tem como padrão:

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

Juntos as classes class:MemoryFileUploadHandler e [`TemporaryFileUploadHandler`](/pt-br/6.1/ref/files/uploads/#django.core.files.uploadhandler.TemporaryFileUploadHandler) fornecem ao Django um comportamento padrão para o envio de arquivos  que lê arquios pequenos na memória e grandes arquivos no disco.

Você pode escrever manipuladores que personalizem a maneira como Django lida com arquivos. Você pode por exemplo, usar manipuladores personalizados para forçar quotas no nível do usuário, comprimir dados enquanto chegam, renderizar barras de progresso, e mesmo enviar dados diretamente para um outro local de armazenamento sem armazenar localmente. Para maiores detalhes veja o [Writing custom upload handlers](/pt-br/6.1/ref/files/uploads/#custom-upload-handlers)  para saber como você  pode personalizar ou mudar completamente o comportamento do envio.

### Onde os dados de arquivos enviados são armazenados

Antes que você salve os arquivos enviados, os dados precisam ser salvos em algum lugar.

Por padrão, se um arquivo enviado é menor que 2.5 megabytes, o Django irá manter todo o conteúdo do arquivo em memória. Isso significa que salvar o arquivo envolve somente uma leitura na memória e uma escrita no disco e portanto muito rápido.

Porém, se o arquivo enviado é muito grande, o Django irá escrever o arquivo enviado em um arquivo temporário no diretório de arquivos temporários do seu sistema. Em uma plataforma Unix isso significa que você pode esperar que o Django crie um arquivo cujo o nome seja algo como /tmp/tmpzfp6I6.upload\`. Se o arquivo enviado é grande o bastante, você pode assistir o arquivo crescer em tamanho enquanto o Django transmite o dado para o disco.

These specifics – 2.5 megabytes; `/tmp`; etc. – are “reasonable defaults”
which can be customized as described in the next section.

### Mudando o comportamento do manipulador de envio de arquivos

Existem algumas definições que controla como o manipulador de envio de arquivo do Django se comporta. Para detalhes veja o [Definições de envio de arquivos](/pt-br/6.1/ref/settings/#file-upload-settings).

### Modificando manipuladores de envio de arquivos durante a execução

As vezes uma “view” em particular requer um comportamento diferente para o envio de arquivos. Neste caso, você pode sobrescrever um manipulador baseado no “request” modificando o `request.upload_handlers`. Por padrão, esta lista contém os manipuladores informados pelo [`FILE_UPLOAD_HANDLERS`](/pt-br/6.1/ref/settings/#std-setting-FILE_UPLOAD_HANDLERS), mas você pode modificar essa lista como qualquer outra lista.

Por exemplo, suponha que você tenha escrito um `ProgressBarUploadHandler` que dá um retorno sobre o progresso do envio do arquivo para algum tipo de “widget” AJAX. Você adicionaria este manipulador a sua lista de manipuladores como aqui:

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

Using `list.insert()`, as shown above, ensures that the progress bar handler
is placed at the beginning of the list. Since upload handlers are executed in
order, this placement guarantees that the progress bar handler runs before the
default handlers, allowing it to track progress across the entire upload.

If you want to replace the upload handlers completely, you can assign a new
list:

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

> **Note**
>
> Você só pode modificar manipuladores de envio *antes* de acessar `request.POST` ou `request.FILES`– não faz sentido mudar o manipulador de arquivos depois que o tratamento do envio já iniciou. Se você tentar modificar o `request.upload_handlers` depois da leitura do request.POST\`\`ou request.FILES\`\`o Django irá emitir um erro.
>
> Então, você deve sempre modificar os manipuladores de arquivos  tão cedo quanto possível nas suas “views”.
>
> Also, `request.POST` is accessed by
> [`CsrfViewMiddleware`](/pt-br/6.1/ref/middleware/#django.middleware.csrf.CsrfViewMiddleware) which is enabled by
> default. This means you will need to use
> [`csrf_exempt()`](/pt-br/6.1/ref/csrf/#django.views.decorators.csrf.csrf_exempt) on your view to allow you
> to change the upload handlers. You will then need to use
> [`csrf_protect()`](/pt-br/6.1/ref/csrf/#django.views.decorators.csrf.csrf_protect) on the function that
> actually processes the request. Note that this means that the handlers may
> start receiving the file upload before the CSRF checks have been done.
> Example code:
>
> ```
> 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
>     ...
> ```
>
> If you are using a class-based view, you will need to use
> [`csrf_exempt()`](/pt-br/6.1/ref/csrf/#django.views.decorators.csrf.csrf_exempt) on its
> [`dispatch()`](/pt-br/6.1/ref/class-based-views/base/#django.views.generic.base.View.dispatch) method and
> [`csrf_protect()`](/pt-br/6.1/ref/csrf/#django.views.decorators.csrf.csrf_protect) on the method that
> actually processes the request. Example code:
>
> ```
> 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
>         ...
> ```
