{"title":"Bagaimana menulis kelas penyimpanan disesuaikan","version":"6.1","locale":"id","docname":"howto/custom-file-storage","url":"/id/6.1/howto/custom-file-storage/","canonical":"https://djangodocs.dev/id/6.1/howto/custom-file-storage/","summary":"Jika anda butuh untuk menyediakan penyimpanan berkas disesuaikan -- contoh umum adalah menyimpan berkas di beberapa sistem terpencil -- anda dapat melakukannya…","html":"<h1>Bagaimana menulis kelas penyimpanan disesuaikan<a class=\"heading-anchor\" href=\"#how-to-write-a-custom-storage-class\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Jika anda butuh untuk menyediakan penyimpanan berkas disesuaikan -- contoh umum adalah menyimpan berkas di beberapa sistem terpencil -- anda dapat melakukannya dengan menentukan kelas penyimpanan disesuaikan. Anda akan butuh mengikuti langkah-langkah ini:</p>\n<ol class=\"arabic\">\n<li><p>Sistem penyimpanan disesuaikan anda harus subkelas dari <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> <span class=\"o\">...</span>\n</code></pre></div>\n</li>\n<li><p>Django harus dapat memberikan contoh sistem penyimanan disesuaikan anda tanpa argumen apapun. Ini berarti bahwa setiap pengaturan harus diambil dari  <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>Your storage class must implement the <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> and <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>\nmethods, along with any other methods appropriate to your storage class. See\nbelow for more on these methods.</p>\n<p>Sebagai tambahan, jika kelas anda menyediakan penyimpanan berkas lokal, itu harus menimpa metode <code class=\"docutils literal notranslate\"><span class=\"pre\">path()</span></code>.</p>\n</li>\n<li><p>Your storage class must be <a class=\"reference internal\" href=\"/id/6.1/topics/migrations/#custom-deconstruct-method\"><span class=\"std std-ref\">deconstructible</span></a> so it can be serialized when it's used on a\nfield in a migration. As long as your field has arguments that are\nthemselves <a class=\"reference internal\" href=\"/id/6.1/topics/migrations/#migration-serializing\"><span class=\"std std-ref\">serializable</span></a>, you can use the\n<code class=\"docutils literal notranslate\"><span class=\"pre\">django.utils.deconstruct.deconstructible</span></code> class decorator for this\n(that's what Django uses on FileSystemStorage).</p></li>\n</ol>\n<p>Secara awalan, metode berikut memunculkan <code class=\"docutils literal notranslate\"><span class=\"pre\">NotImplementedError</span></code> dan akan khususnya ditimpa:</p>\n<ul class=\"simple\">\n<li><p><a class=\"reference internal\" href=\"/id/6.1/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=\"/id/6.1/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=\"/id/6.1/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=\"/id/6.1/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=\"/id/6.1/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>Catat bagaimanapun bahwa tidak semua metode ini diwajibkan dan mungkin sengaja dihilangkan. Ketika itu terjadi, itu memungkinkan meninggalkan setiap cara tidak diterapkan dan masih memiliki Penyimpanan bekerja.</p>\n<p>Sebagai contoh, jika mencantumkan isi dari backend penyimpanan tertentu ternyata mahal, anda mungkin memutuskan tidak menerapkan <code class=\"docutils literal notranslate\"><span class=\"pre\">Storage.listdir()</span></code>.</p>\n<p>Cara lain akan menjadi backend yang ahnya menangani penulisan ke berkas. Dalam kasus ini, anda tidak akan butuh menerapkan apapun metode diatas.</p>\n<p>Akhirnya, metode mana yang anda terapkan terserah anda. Meninggalkan beberapa cara tidak diterapkan akan menghasilkan antarmuka sebagian (kemungkinan rusak).</p>\n<p>Anda akan juga ingin menggunakan penghubung khususnya dirancang untuk obyek penyimpanan disesuaikan. Ini adalah:</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 to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p><strong>Wajib</strong>.</p>\n<p>DIpanggil oleh <code class=\"docutils literal notranslate\"><span class=\"pre\">Storage.open()</span></code>, ini adalah mekanisme sebenarnya kelas penyimpanan menggunakan untuk membuka berkas. Ini harus mengembalikan objek <code class=\"docutils literal notranslate\"><span class=\"pre\">File</span></code>, meskipun dalam kebanyakan kasus, anda akan ingin mengembalikan beberapa subkelas disini yang menerapkan logika khusus pada sistem penyimpanan backend. Pengecualian <a class=\"reference external\" href=\"https://docs.python.org/3/library/exceptions.html#FileNotFoundError\" title=\"(di Python v3.14)\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">FileNotFoundError</span></code></a> harus dimunculkan ketika berkas tidak ada.</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 to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Dipanggil oleh <code class=\"docutils literal notranslate\"><span class=\"pre\">Storage.save()</span></code>, <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> sudah telah melalui <code class=\"docutils literal notranslate\"><span class=\"pre\">get_valid_name()</span></code> dan <code class=\"docutils literal notranslate\"><span class=\"pre\">get_available_name()</span></code>, dan <code class=\"docutils literal notranslate\"><span class=\"pre\">content</span></code> akan menjadi obyek <code class=\"docutils literal notranslate\"><span class=\"pre\">File</span></code> itu sendiri.</p>\n<p>Harus mengembalikan nama sebenarnya dari berkas disimpan (biasanya <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> dilewatkan, tetapi jika penyimpanan butuh merubah nama berkas mengembalikan nama baru sebagai gantinya).</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 to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Mengembalikan sebuah nama berkas yang cocok untuk digunakan dengan sistem penyimpanan pokok. Argumen <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> dilewati ke cara ini antara berkas nama asli dikirim ke peladen atau, jika <code class=\"docutils literal notranslate\"><span class=\"pre\">upload_to</span></code> adalah callable, nama berkas dikembalikan oleh cara tersebut setelah informasi jalur dipindahkan. Kesampingkan ini untuk menyesuaikan bagaimana karakter bukan-standar dirubah ke nama berkas aman.</p>\n<p>Kode disediakan di <code class=\"docutils literal notranslate\"><span class=\"pre\">Storage</span></code> hanya mempertahankan karakter alpanumerik, titik dan garis bawah dari nama berkas asli, memindahkan semua yang lainnya.</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 to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Mengembalikan nama berkas lain berdasarkan pada parameter <code class=\"docutils literal notranslate\"><span class=\"pre\">file_root</span></code> dan <code class=\"docutils literal notranslate\"><span class=\"pre\">file_ext</span></code>. Secara awalan, sebuah garis bawah ditambah 7 karakter string alfanumerik acak ditambahkan ke nama berkas sebelum ekstensi.</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 to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Mengembalikan nama berkas yang tersedia di mekanisme penyimpanan, barangkali mengambil nama berkas tersedia ke dalam akun. argumen <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> dilewati ke cara ini akan sudah dibersihkan ke nama berkas sah untuk sistem penyimpanan, menurut cara <code class=\"docutils literal notranslate\"><span class=\"pre\">get_valid_name()</span></code> digambarkan diatas.</p>\n<p>Panjang dari nama berkas tidak melebihi <code class=\"docutils literal notranslate\"><span class=\"pre\">max_length</span></code>, jika disediakan. Jika nama berkas unik bebas tidak dapat ditemukan, sebuah pengecualian <a class=\"reference internal\" href=\"/id/6.1/ref/exceptions/#django.core.exceptions.SuspiciousOperation\" title=\"django.core.exceptions.SuspiciousOperation\"><code class=\"xref py py-exc docutils literal notranslate\"><span class=\"pre\">SuspiciousFileOperation</span></code></a> muncul.</p>\n<p>Jika sebuah berkas dengan <code class=\"docutils literal notranslate\"><span class=\"pre\">name</span></code> sudah ada, <code class=\"docutils literal notranslate\"><span class=\"pre\">get_alternative_name()</span></code> dipanggil untuk mendapatkan nama alternatif.</p>\n<section id=\"use-your-custom-storage-engine\">\n<span id=\"using-custom-storage-engine\"></span><h2>Gunakan mesin penyimpanan penyesuaian anda<a class=\"heading-anchor\" href=\"#use-your-custom-storage-engine\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Langkah pertama untuk menggunakan penyimpanan penyesuaian anda dengan Django adalah memberitahu Django tetnang berkas backend penyimpanan anda sedang gunakan.. Ini dilakukan dengan pengaturan <a class=\"reference internal\" href=\"/id/6.1/ref/settings/#std-setting-STORAGES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">STORAGES</span></code></a>. Pengaturan ini memetakan nama lain penyimpanan, yang merupakan cara merujuk pada penyumpanan khusus di Django, pada pengaturan dictionary untuk backend penyimpanan khusus itu. Pengaturan dalam  dictionary terdalam digambarkan sepenuhnya dalam dokumentasi <a class=\"reference internal\" href=\"/id/6.1/ref/settings/#std-setting-STORAGES\"><code class=\"xref std std-setting docutils literal notranslate\"><span class=\"pre\">STORAGES</span></code></a>.</p>\n<p>Penyimpanan dapat diakses oleh nama lain dari dictionary <a class=\"reference internal\" href=\"/id/6.1/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>:</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":"Gunakan mesin penyimpanan penyesuaian anda","anchor":"use-your-custom-storage-engine","children":[]}],"breadcrumbs":[{"docname":"howto/index","title":"Panduan Cara-cara","url":"/id/6.1/howto/"}],"prev":{"docname":"howto/csrf","title":"Bagaimana menggunakan perlindungan CSRF Django","url":"/id/6.1/howto/csrf/"},"next":{"docname":"howto/custom-management-commands","title":"Bagaimana membuat perintah django-admin yang disesuaikan","url":"/id/6.1/howto/custom-management-commands/"},"formats":{"html":"/id/6.1/howto/custom-file-storage/","markdown":"/id/6.1/howto/custom-file-storage.md","json":"/id/6.1/howto/custom-file-storage.json"},"source":"https://github.com/django/django/blob/stable/6.1.x/docs/howto/custom-file-storage.txt","official":"https://docs.djangoproject.com/id/6.1/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","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}