{"title":"Como escrever uma classe de armazenamento customizada","version":"4.2","locale":"pt-br","docname":"howto/custom-file-storage","url":"/pt-br/4.2/howto/custom-file-storage/","canonical":"https://djangodocs.dev/pt-br/4.2/howto/custom-file-storage/","summary":"Se você precisa de um armazenador de arquivos customizados – um exemplo comum é armazenar arquivos em algum sistema remoto – você pode faze-lo definido uma classe…","html":"<h1>Como escrever uma classe de armazenamento customizada<a class=\"heading-anchor\" href=\"#how-to-write-a-custom-storage-class\"><span class=\"visually-hidden\">Link para este cabeçalho</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Se você precisa de um armazenador de arquivos customizados – um exemplo comum é armazenar arquivos em algum sistema remoto – você pode faze-lo definido uma classe de armazenamento customizada. Você precisará seguir estes passos:</p>\n<ol class=\"arabic\">\n<li><p>O seu Sistema de armazenamento customizado deve ser uma subclasse de <code class=\"docutils literal notranslate\"><span class=\"pre\">django.core.files.storage.Storage</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.files.storage</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Storage</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyStorage</span><span class=\"p\">(</span><span class=\"n\">Storage</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n</li>\n<li><p>Django deve ser capaz de instanciar o seu sistema de armazenamento sem nenhum argumento. Isso significa que quaisquer definições devem ser tomada a partir de <code class=\"docutils literal notranslate\"><span class=\"pre\">django.conf.settings</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.conf</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">settings</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.files.storage</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">Storage</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyStorage</span><span class=\"p\">(</span><span class=\"n\">Storage</span><span class=\"p\">):</span>\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"fm\">__init__</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">option</span><span class=\"o\">=</span><span class=\"kc\">None</span><span class=\"p\">):</span>\n        <span class=\"k\">if</span> <span class=\"ow\">not</span> <span class=\"n\">option</span><span class=\"p\">:</span>\n            <span class=\"n\">option</span> <span class=\"o\">=</span> <span class=\"n\">settings</span><span class=\"o\">.</span><span class=\"n\">CUSTOM_STORAGE_OPTIONS</span>\n        <span class=\"o\">...</span>\n</code></pre></div>\n</li>\n<li><p>A classe de armazenamento deve implementar os métodos <a class=\"reference internal\" href=\"#django.core.files.storage._open\" title=\"django.core.files.storage._open\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">_open()</span></code></a> e <a class=\"reference internal\" href=\"#django.core.files.storage._save\" title=\"django.core.files.storage._save\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">_save()</span></code></a>, além de qualquer outro método apropriado para a sua classe de armazenamento. Veja abaixo mais sobre estes métodos.</p>\n<p>Além disso, se sua classe permite armazenamento local de arquivo, deve-se sobrescrever o método <code class=\"docutils literal notranslate\"><span class=\"pre\">path()</span></code>.</p>\n</li>\n<li><p>Sua classe de armazenamento deve ser  <a class=\"reference internal\" href=\"/pt-br/4.2/topics/migrations/#custom-deconstruct-method\"><span class=\"std std-ref\">“desconstruível”</span></a> para que possa ser “serializado” quando usado em um campo na “migration”. Uma vez que seus campos têm argumentos que são eles mesmos <a class=\"reference internal\" href=\"/pt-br/4.2/topics/migrations/#migration-serializing\"><span class=\"std std-ref\">serializáveis</span></a>, é possível usar o “decorator” de classe <code class=\"docutils literal notranslate\"><span class=\"pre\">django.utils.deconstruct.deconstructible</span></code> para isso (que é usado pelo Django no FileSystemStorage).</p></li>\n</ol>\n<p>Por padrão, os seguintes métodos levantam <code class=\"docutils literal notranslate\"><span class=\"pre\">NotImplementedError</span></code> e normalmente terão de ser sobrescritas:</p>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/pt-br/4.2/ref/files/storage/#django.core.files.storage.Storage.delete\" title=\"django.core.files.storage.Storage.delete\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Storage.delete()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/pt-br/4.2/ref/files/storage/#django.core.files.storage.Storage.exists\" title=\"django.core.files.storage.Storage.exists\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Storage.exists()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/pt-br/4.2/ref/files/storage/#django.core.files.storage.Storage.listdir\" title=\"django.core.files.storage.Storage.listdir\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Storage.listdir()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/pt-br/4.2/ref/files/storage/#django.core.files.storage.Storage.size\" title=\"django.core.files.storage.Storage.size\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Storage.size()</span></code></a></p></li>\n<li><p><a class=\"reference internal\" href=\"/pt-br/4.2/ref/files/storage/#django.core.files.storage.Storage.url\" title=\"django.core.files.storage.Storage.url\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Storage.url()</span></code></a></p></li>\n</ul>\n<p>Note porém que nem todos estes métodos são requeridos e talvez deliberadamente omitidos. Caso isso ocorra, é possível deixar cada método não implementado e ainda ter um armazenamento que funcione.</p>\n<p>A título de exemplo, listando o conteúdo de um certo armazenamento backend acaba se tornando custoso, você pode decidir por não implementar <code class=\"docutils literal notranslate\"><span class=\"pre\">Storage.listdir()</span></code>.</p>\n<p>Outro exemplo seria um backend que só lida com a escrita de arquivos. Neste caso, não seria necessário implementar qualquer um dos métodos acima.</p>\n<p>Em última análise, quais destes métodos são implementados depende de você. Deixando de implementar alguns métodos irá resultar em uma interface parcial (possivelmente quebrada).</p>\n<p>Você também pode querer usar hooks feitos especificamente para objetos de storage personalizados. Estes são os seguintes:</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.core.files.storage._open\">\n<span class=\"sig-name descname\"><span class=\"pre\">_open</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">mode</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">'rb'</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.core.files.storage._open\"><span class=\"visually-hidden\">Link para esta definição</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p><strong>Obrigatório</strong>.</p>\n<p>Called by <code class=\"docutils literal notranslate\"><span class=\"pre\">Storage.open()</span></code>, this is the actual mechanism the storage class\nuses to open the file. This must return a <code class=\"docutils literal notranslate\"><span class=\"pre\">File</span></code> object, though in most cases,\nyou’ll want to return some subclass here that implements logic specific to the\nbackend storage system. The <a class=\"reference external\" href=\"https://docs.python.org/3/library/exceptions.html#FileNotFoundError\" title=\"(em Python v3.14)\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">FileNotFoundError</span></code></a> exception should be raised\nwhen a file doesn’t exist.</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.core.files.storage._save\">\n<span class=\"sig-name descname\"><span class=\"pre\">_save</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">content</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.core.files.storage._save\"><span class=\"visually-hidden\">Link para esta definição</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Chamado por `` Storage.save () <code class=\"docutils literal notranslate\"><span class=\"pre\">.</span> <span class=\"pre\">O</span> <span class=\"pre\">``</span> <span class=\"pre\">name</span></code> já terá passado por `` get_valid_name ()`` e <code class=\"docutils literal notranslate\"><span class=\"pre\">get_available_name</span> <span class=\"pre\">()</span></code>, e o <code class=\"docutils literal notranslate\"><span class=\"pre\">content</span></code> será ele mesmo um objeto <code class=\"docutils literal notranslate\"><span class=\"pre\">File</span></code>.</p>\n<p>Should return the actual name of the file saved (usually the <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> passed\nin, but if the storage needs to change the file name return the new name\ninstead).</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.core.files.storage.get_valid_name\">\n<span class=\"sig-name descname\"><span class=\"pre\">get_valid_name</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">name</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.core.files.storage.get_valid_name\"><span class=\"visually-hidden\">Link para esta definição</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Retorna um nome de arquivo adequado para uso com o sistema de armazenamento subjacente. O argumento <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> passado para esse método é o nome do arquivo original enviado para o servidor ou, se `` upload_to`` é um “callable” (método), o nome do arquivo retornado por esse método depois de qualquer informação de caminho ser removido. Sobrescreva isso para customizar como caracteres fora de padrão são convertidos para nomes de arquivos seguros.</p>\n<p>O código fornecido em <code class=\"docutils literal notranslate\"><span class=\"pre\">Storage</span></code> guarda apenas os caracteres alfanuméricos, pontos e “underscore” do nome do arquivo original, removendo qualquer outra cosa.</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.core.files.storage.get_alternative_name\">\n<span class=\"sig-name descname\"><span class=\"pre\">get_alternative_name</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">file_root</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">file_ext</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.core.files.storage.get_alternative_name\"><span class=\"visually-hidden\">Link para esta definição</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Retorna um nome de arquivo alternativo baseado nos parâmetros de <code class=\"docutils literal notranslate\"><span class=\"pre\">file_root</span></code> e <code class=\"docutils literal notranslate\"><span class=\"pre\">file_ext</span></code>. Por padrão, um “underscore” e uma string de 7 caracteres alfanuméricos aleatórios são acrescentados antes da extensão.</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.core.files.storage.get_available_name\">\n<span class=\"sig-name descname\"><span class=\"pre\">get_available_name</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">name</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">max_length</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.core.files.storage.get_available_name\"><span class=\"visually-hidden\">Link para esta definição</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Retorna um nome de arquivo que está disponível no mecanismo de armazenamento, possivelmente levando em conta o nome do arquivo fornecido. O argumento <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> passado para este método já terá sido limpo para um nome de arquivo válido para o sistema de armazenamento, de acordo com o método <code class=\"docutils literal notranslate\"><span class=\"pre\">get_valid_name()</span></code> descrito acima.</p>\n<p>O comprimento do nome do arquivo não será superior a `` max_length``, se informado. Se um nome de arquivo único não pode ser encontrado, a: exc: <a href=\"#id1\"><span class=\"problematic\" id=\"id2\">`</span></a>SuspiciousFileOperation &lt;django.core.exceptions.SuspiciousOperation&gt; <a href=\"#id3\"><span class=\"problematic\" id=\"id4\">`</span></a>Exceção é gerada.</p>\n<p>Se um arquivo <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> já existe, <code class=\"docutils literal notranslate\"><span class=\"pre\">get_alternative_name()</span></code> é chamado para obter um nome alternativo.</p>\n<section id=\"use-your-custom-storage-engine\">\n<span id=\"using-custom-storage-engine\"></span><h2>Use seu mecanismo de armazenamento personalizado<a class=\"heading-anchor\" href=\"#use-your-custom-storage-engine\"><span class=\"visually-hidden\">Link para este cabeçalho</span><span aria-hidden=\"true\">#</span></a></h2>\n<aside class=\"version-note version-added\" data-version=\"4.2\">\n<p class=\"version-note-title\">New in Django 4.2</p></aside>\n<p>The first step to using your custom storage with Django is to tell Django about\nthe file storage backend you’ll be using. This is done using the\n<a class=\"reference internal\" href=\"/pt-br/4.2/ref/settings/#std-setting-STORAGES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">STORAGES</span></code></a> setting. This setting maps storage aliases, which are a way\nto refer to a specific storage throughout Django, to a dictionary of settings\nfor that specific storage backend. The settings in the inner dictionaries are\ndescribed fully in the <a class=\"reference internal\" href=\"/pt-br/4.2/ref/settings/#std-setting-STORAGES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">STORAGES</span></code></a> documentation.</p>\n<p>Storages are then accessed by alias from from the\n<a class=\"reference internal\" href=\"/pt-br/4.2/ref/files/storage/#django.core.files.storage.storages\" title=\"django.core.files.storage.storages\"><code class=\"xref py py-data docutils literal notranslate\"><span class=\"pre\">django.core.files.storage.storages</span></code></a> dictionary:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.files.storage</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">storages</span>\n\n<span class=\"n\">example_storage</span> <span class=\"o\">=</span> <span class=\"n\">storages</span><span class=\"p\">[</span><span class=\"s2\">&quot;example&quot;</span><span class=\"p\">]</span>\n</code></pre></div>\n</section>","rootId":"how-to-write-a-custom-storage-class","toc":[{"title":"Use seu mecanismo de armazenamento personalizado","anchor":"use-your-custom-storage-engine","children":[]}],"breadcrumbs":[{"docname":"howto/index","title":"Guias de “como fazer”","url":"/pt-br/4.2/howto/"}],"prev":{"docname":"howto/custom-template-tags","title":"How to create custom template tags and filters","url":"/pt-br/4.2/howto/custom-template-tags/"},"next":{"docname":"howto/deployment/index","title":"How to deploy Django","url":"/pt-br/4.2/howto/deployment/"},"formats":{"html":"/pt-br/4.2/howto/custom-file-storage/","markdown":"/pt-br/4.2/howto/custom-file-storage.md","json":"/pt-br/4.2/howto/custom-file-storage.json"},"source":"https://github.com/django/django/blob/stable/4.2.x/docs/howto/custom-file-storage.txt","official":"https://docs.djangoproject.com/pt-br/4.2/howto/custom-file-storage/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10","1.9"],"inLocales":["en","zh-hans","fr","ja","id","it","pt-br","ko","es","el","pl"]}