# Dokumentasi Django 5.2.8

# Kerangka kerja penyimpanan Django

Pertukaran mendasar dalam situs web dinamis adalah, mereka dinamis. Setiap kali pengguna meminta halaman, peladen jaringan membuat segala macam perhitungan -- mulai dari permintaan basisdara hingga membangun cetakan hingga logika bisnis -- untuk membuat halaman yang dilihat pengunjung situs anda. Ini jauh lebih mahal, dari perspektif pemrosesan-overhead, daripada pengaturan peladen read-a-file-off-the-filesystem standar Anda.

For most web applications, this overhead isn't a big deal. Most web applications aren't `washingtonpost.com` or `slashdot.org`; they're small-to medium-sized sites with so-so traffic. But for medium- to high-traffic sites, it's essential to cut as much overhead as possible.

Itu adalah dimana cache datang.

Meng-cache sesuatu berarti menyimpan hasil perhitungan yang mahal sehingga anda tidak perlu melakukan perhitungan di lain waktu. Berikut ini beberapa kodesemu yang menjelaskan cara kerjanya untuk halaman web yang dibuat secara dinamis:

    given a URL, try finding that page in the cache
    if the page is in the cache:
        return the cached page
    else:
        generate the page
        save the generated page in the cache (for next time)
        return the generated page

Django datang dengan sistem cache kuat yang membiarkan anda mentimpan halaman-halaman dinamis sehingga mereka tidak harus dihitung untuk setiap permintaan. Untuk kenyamanan, Django menawarkan tingkatan berbeda dari butiran cache: Anda dapat cache keluaran dari tampilan khusus, anda dapat cache hanya potongan-potongan yang sulit dihasilkan, atau anda dapat cache kelesuruhan situs anda.

Django juga bekerja dengan baik dengan cache "hilir", seperti Squid dan cache berbasis browser. Ini adalah jenis cache yang tidak anda kontrol secara langsung, tetapi anda dapat memberikan petunjuk (melalui header HTTP) tentang bagian mana dari situs anda yang harus di-cache, dan bagaimana caranya.

Lihat juga

Cache Framework design philosophy menjelaskan sedikit dari keputusan rancangan dari kerangka kerja.

## Mengatur tembolok

Sistem cache membutuhkan sejumlah kecil pengaturan. Yaitu, anda harus memberitahu itu dimana data cache anda harus tinggal -- apakah di basisdata, pada sistem berkas atau langsung di memori. Ini adalah keputusan penting yang mempengaruhi penampilan cache anda; ya beberapa jenis cache adalah lebih cepat dari lainnya.

Pilihan cache anda masuk di pengaturan `CACHES` di berkas pengaturan anda. Ini adalah sebuah penjelasan dari semua nilai-nilai tersedia untuk `CACHES`.

### Memcache

Memcached adalah server cache yang sepenuhnya berbasis memori, awalnya dikembangkan untuk menangani beban tinggi di LiveJournal.com dan kemudian di-open-source oleh Danga Interactive. Ini digunakan oleh situs-situs seperti Facebook dan Wikipedia untuk mengurangi akses basisdata dan secara dramatis meningkatkan kinerja situs.

Memcached berjalan sebagai daemon dan memberikan sejumlah tertentu dari RAM. Semua itu lakukan adalah menyediakan antarmuka cepat untuk menambah, mengambil dan menghapus data di cache. Semua data disimpan secara langsung di memori, sehingga tidak ada kelebihan dari basisdata atau penggunaan sistem berkas.

Setelah memasang Memcached sendiri, anda harus memasang pengikatan Memcached. Ada beberapa binding Python Memcached yang tersedia; keduanya didukung oleh Django adalah pylibmc dan pymemcache.

Untuk menggunakan Memcache dengan Django:

- Setel `BACKEND 1` ke `django.core.cache.backends.memcached.PyMemcacheCache` atau `django.core.cache.backends.memcached.PyLibMCCache` (tergantung pengikatan memcached pilihan anda)

- Setel `LOCATION` menjadi nilai-nilai `ip:port`, dimana `ip` adalah alamat IP dari daemon memcache dan `port` adalah pangkalan pada Memcache mana yang berjalan, atau menjadi nilai `unix:path`, dimana `path` adalah jalur ke berkas soket Unix Memcache.

Dalam contoh ini, Memcached berjalan di localhost (127.0.0.1) port 11211, menggunakan pengikatan `pymemcache`:

    CACHES = {
        "default": {
            "BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache",
            "LOCATION": "127.0.0.1:11211",
        }
    }

Dalam contoh ini, Memcached tersedia melalui file soket Unix lokal `/tmp/memcached.sock` menggunakan pengikat `pymemcache`:

    CACHES = {
        "default": {
            "BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache",
            "LOCATION": "unix:/tmp/memcached.sock",
        }
    }

Satu fitur yg hebar dari Memcache adalah kemampuannya berbagi sebuah cache terhadap banyak peladen. Ini berarti anda dapat menjalankan daemon Memcache pada banyak mesin, dan program akan memperlakukan kelompok mesin sebagai cache tunggal, tanpa butuh menggandakan nilai-nilai cache pada setiap mesin. Untuk mengambil keuntungan fitur ini, sertakan semua alamat peladen dalam `LOCATION 1`,antara sebagai titik koma atau string dipisahkan koma, atau sebagai sebuah daftar.

Di contoh ini, penyimpanan dibagi terhadao instance Memcache berjalan pada alamat IP 172.19.26.240 dan 172.19.26.242, keduanya di port 11211:

    CACHES = {
        "default": {
            "BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache",
            "LOCATION": [
                "172.19.26.240:11211",
                "172.19.26.242:11211",
            ],
        }
    }

Di contoh berikut, cache dibagi terhadap instance Memcache berjalan pada alamat IP 172.19.26.240 (port 11211), 172.19.26.242 (port 11212), dan 172.19.26.244 (port 11213):

    CACHES = {
        "default": {
            "BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache",
            "LOCATION": [
                "172.19.26.240:11211",
                "172.19.26.242:11212",
                "172.19.26.244:11213",
            ],
        }
    }

Secara awalan, backend `PyMemcacheCache` menyetel pilihan berikut (anda dapat menimpa mereka dalam `OPTIONS`):

    "OPTIONS": {
        "allow_unicode_keys": True,
        "default_noreply": False,
        "serde": pymemcache.serde.pickle_serde,
    }

Sebuah titik akhir tentang Memcached adalah cache berdasarkan-memori mempunyai kerugian: karena data cache disimpan di memori, data akan hilang jika peladen anda gagal. Jelasnya, memori tidak diperuntukkan untuk penyimpanan data tetap, jadi jangan bergantung oada cache berdasarkan-memori sebagai penyimpanan data anda satu-satunya -- mereka adalah diperuntukkan pemecahan untuk cache, bukan penyimpanan -- tetapi kami menitikkan ini disini karena cache berdasarkan-memori adalah khususnya sementara.

### Redis

Redis adalah basisdata dalam memori yang dapat digunakan untuk caching. Untuk memulai, anda memerlukan server Redis yang berjalan secara lokal atau di mesin jarak jauh.

Setelah menyetel peladen Redis, anda akan butuh memasang ikatan Python untuk Redis. redis-py adalah ikatan didukung secara asli oleh Django. Memasang paket hiredis-py juga dianjurkan.

Untuk menggunakan Redis sebagai backend cache anda dengan Django:

- Setel `BACKEND` menjadi `django.core.cache.backends.redis.RedisCache`.

- Set `LOCATION` to the URL pointing to your Redis instance, using the appropriate scheme. See the `redis-py` docs for details on the available schemes.

Sebagai contoh, jika Redis berjalan pada localhost (127.0.0.1) port 6379:

    CACHES = {
        "default": {
            "BACKEND": "django.core.cache.backends.redis.RedisCache",
            "LOCATION": "redis://127.0.0.1:6379",
        }
    }

Seringkali peladen Redis dilindungi dengan autentikasi. Untuk memasukkan nama pengguna dan kata sandi, tambahkan di `LOCATION` bersama dengan URL:

    CACHES = {
        "default": {
            "BACKEND": "django.core.cache.backends.redis.RedisCache",
            "LOCATION": "redis://username:password@127.0.0.1:6379",
        }
    }

Jika anda memiliki beberapa peladen Redis yang diatur dalam suasana replikasi, anda dapat menentukan peladen baik sebagai string yang dipisahkan titik koma atau koma, atau sebagai daftar. Saat menggunakan banyak peladen , operasi tulis dilakukan di peladen pertama (pemimpin). Operasi baca dilakukan di peladen lain (replika) yang dipilih secara acak

    CACHES = {
        "default": {
            "BACKEND": "django.core.cache.backends.redis.RedisCache",
            "LOCATION": [
                "redis://127.0.0.1:6379",  # leader
                "redis://127.0.0.1:6378",  # read-replica 1
                "redis://127.0.0.1:6377",  # read-replica 2
            ],
        }
    }

### Menembolok basisdata

Django dapat menyimpan data temboloknya dalam basisdata anda. Ini bekerja baik jika anda mendapatkan cepat, peladen basisdata diindeks baik.

Untuk menggunakan tabel basisdata sebagai backend tembolok anda:

- Setel `BACKEND` menjadi `django.core.cache.backends.db.DatabaseCache`

- Setel `LOCATION` menjadi `tablename`, nama dari tabel basisdata. Nama ini dapat menjadi apapun anda inginkan, selama dia adalah nama tabel yang sah yang tidak sedang digunakan dalam basisdata anda.

Dalam contoh ini, nama tabel tembolok adalah `my_cache_table`:

    CACHES = {
        "default": {
            "BACKEND": "django.core.cache.backends.db.DatabaseCache",
            "LOCATION": "my_cache_table",
        }
    }

Tidak seperti backend cache lainnya, cache basisdata tidak mendukung pemusnahan otomatis masukan yang kedaluwarsa di tingkat basisdata. Sebagai gantinya, masukan cache yang kedaluwarsa akan diambil setiap kali `add()`, `set()`, atau `touch()` dipanggil.

#### Membuat tabel tembolok

Sebelum menggunakan cache basisdata, anda harus membuat tabel cache dengan perintah ini:

    python manage.py createcachetable

Ini membuat tabel di basisdata anda yaitu dalam bentuk sesuai yang sistem tembolok-basidata harapkan. Nama dari tabel diambil dari `LOCATION`.

Jika anda menggunakan banyak basisdata tembolok, `createcachetable` membuat satu tabel untuk setiap tembolok.

Jika anda menggunakan banyak basisdata, `createcachetable` mengamati cara `allow_migrate()` dari perute basisdata anda (lihat dibawah).

Seperti `migrate`, `createcachetable` tidak akan menyentuh tabel yang ada. Dia tidak akan membuat tabel-tabel hilang.

Untuk mencetak SQL yang akan menjalankan, daripada menjalankannya, gunakan pilihan `createcachetable --dry-run`.

#### Basisdata banyak

Jika anda menggunakan penembolokan basisdata dengan banyak basisdata, anda akan juga butuh menyetel perintah perutean untuk tabel tembolok basisdata anda. Untuk tujuan perutean, tabel tembolok basisdata muncul sebagai model dinamai `CacheEntry`, di aplikasi dinamai `django_cache`. Model ini tidak akan muncul dalam model tembolok, tetapi rincian model dapat digunakan untuk tujuan perutean.

Sebagai contoh, perute berikut akan melangsungkan semua tindakan pembacaan tembolok ke `cache_replica`, dan semua tindakan penulisan ke `cache_primary`. Tabel tembolok hanya disinkronisasikan kedalam `cache_primary`:

    class CacheRouter:
        """A router to control all database cache operations"""

        def db_for_read(self, model, **hints):
            "All cache read operations go to the replica"
            if model._meta.app_label == "django_cache":
                return "cache_replica"
            return None

        def db_for_write(self, model, **hints):
            "All cache write operations go to primary"
            if model._meta.app_label == "django_cache":
                return "cache_primary"
            return None

        def allow_migrate(self, db, app_label, model_name=None, **hints):
            "Only install the cache model on primary"
            if app_label == "django_cache":
                return db == "cache_primary"
            return None

Jika anda tidak menentukan arah perute untuk model cache basisdata, backend cache akan menggunakan basisdata `default`.

Dan jika anda tidak menggunakan backend cache basisdata, anda tidak perlu khawatir untuk menyediakan instruksi perutean untuk model cache basisdata.

### Cache sistem berkas

Serial backend berdasarkan-berkas dan menyimpan setiap nilai cache sebagai berkas terpisah. Untuk menggunakan backend ini setel `BACKEND` menjadi `"django.core.cache.backends.filebased.FileBasedCache"` dan `LOCATION` menjadi direktori yang cocok. Sebagai contoh, untuk menyimpan data di `/var/tmp/django_cache`, gunakan pengaturan ini:

    CACHES = {
        "default": {
            "BACKEND": "django.core.cache.backends.filebased.FileBasedCache",
            "LOCATION": "/var/tmp/django_cache",
        }
    }

Jika anda berada di Windows, taruh huruf drive pada awal jalur, seperti ini:

    CACHES = {
        "default": {
            "BACKEND": "django.core.cache.backends.filebased.FileBasedCache",
            "LOCATION": "c:/foo/bar",
        }
    }

Jalur direktori harus mutlak -- yaitu, itu harus dimulai pada induk dari sistem berkas anda. Itu tidak mengapa apakah anda menaruh sebuah garis miring pada akhir pengaturan.

Pastikan direktori yang ditunjuk oleh pengaturan ini ada dan dapat dibaca dan ditulis, atau dapat dibuat oleh pengguna sistem tempat peladen jaringan anda berjalan. Melanjutkan contoh di atas, jika peladen anda berjalan sebagai pengguna `apache`, pastikan direktori `/var/tmp/django_cache` ada dan dapat dibaca dan ditulis oleh pengguna `apache`, atau bahwa dapat dibuat oleh pengguna `apache`.

Peringatan

Ketika cache `LOCATION` terdapat dalam `MEDIA_ROOT`, `STATIC_ROOT`, atau `STATICFILES_FINDERS`, data sensitif mungkin terbuka.

Penyerang yang mendapatkan akses ke berkas tembolok tidak hanya dapat memalsukan konten HTML, yang akan dipercaya oleh situs anda, tetapi juga mengeksekusi kode arbitrer dari jarak jauh, karena data tersebut diserialisasi menggunakan `pickle`.

Peringatan

Caching sistem berkas mungkin menjadi lambat saat menyimpan berkas dalam jumlah besar. Jika anda mengalami masalah ini, pertimbangkan untuk menggunakan mekanisme caching yang berbeda. Anda juga dapat membuat subkelas FileBasedCache dan meningkatkan strategi pemusnahan.

### Cache memori-lokal

Ini adalah cache awalan jika lainnya tidak ditentukan di berkas pengaturan anda. Jika anda ingin mempercepat keuntungan dari cace di-memori tetapi tidak mempunyai kemampuan dari menjalankan Memcached, perimbangkan backend cache memori-lokal. Cache ini adalah per-pengolahan (lihat dibawah) dan thread-safe. Untuk menggunakan itu, setel `BACKEND` menjadi `"django.core.cache.backends.locmem.LocMemCache"`. Sebagai contoh:

    CACHES = {
        "default": {
            "BACKEND": "django.core.cache.backends.locmem.LocMemCache",
            "LOCATION": "unique-snowflake",
        }
    }

Cache `LOCATION` digunakan untuk mencirikan penyimpanan memori tersendiri. Jika anda hanya mempunyai satu cache `locmem`, anda dapat mengabaikan `LOCATION`; bagaimanapun, jikla anda mempunyai lebih dari satu cache memori lokal, anda akan butuh memberikan sebuah nama pada setidaknya satu dari mereka agar menjaga mereka terpisah.

Penyimpanan sementara menggunakan strategi pemusnahan least-recently-used (LRU).

Perhatikan bahwa setiap proses akan memiliki instance tembolok pribadinya sendiri, yang berarti tidak ada caching lintas proses yang memungkinkan. Ini juga berarti tembolok memori lokal tidak terlalu hemat memori, jadi ini mungkin bukan pilihan yang baik untuk lingkungan produksi. Ini bagus untuk pengembangan.

### Cache tiruan (untuk pengembangan)

Akhirnya, Django datang dengan cache "dummy" yang tidak sebenarnya cache -- itu hanya menerapkan antarmuka cache tanpa melakukan apapun.

Ini adalah sangat berguna jika anda mempunyai situs produksi yang menggunakan cache pekerjaan-berat di beragam tempat tetapi lingkungan pengembangan/percobaan dimana anda tidak ingin cache dan tidak ingin merubah kode anda pada kasus-khusus terakhir. Untuk mengaktifkan cache dummy, setel `BACKEND` seperti begitu:

    CACHES = {
        "default": {
            "BACKEND": "django.core.cache.backends.dummy.DummyCache",
        }
    }

### Menggunakan backend cache penyesuaian

Selagi Django menyertakan dukungan untuk sejumlah backend cache keluar-dari-kotak, terkadang anda mungkin ingin menggunakan backend cache disesuaikan. Untuk menggunakan backend cache luar dengan Django, gunakan jalur impor Python sebagai `BACKEND` dari `CACHES` setting, seperti begitu:

    CACHES = {
        "default": {
            "BACKEND": "path.to.backend",
        }
    }

Jika anda membuat backend anda sendiri, anda dapat menggunakan backend tembolok standar sebagai penerapan acuan. Anda akan menemukan kode di direktori django/core/cache/backends/ dari sumber Django.

Catatan: Tanpa alasan yang benar-benar kuat, seperti host yang tidak mendukungnya, anda harus tetap menggunakan backend tembolok yang disertakan dengan Django. Mereka telah diuji dengan baik dan didokumentasikan dengan baik.

### Argumen cache

Setiap backend cache dapat memberikan argumen tambahan untuk mengendalikan perilaku cache. Argumen-argumen ini disediakan sebagai kunci-kunci tambahan di pengaturan `CACHES`. Argumen-argumen sah seperti berikut:

- `TIMEOUT`: Awalan waktu habis, dalam detik, untuk digunakan untuk cache. Awalan argumen ini pada `300` detik (5 menit). Anda dapat mensetel `TIMEOUT` menjadi `None` sehingga, secara awalan, kunci-kunci cache tidak pernah kadaluarsa. Sebuah nilai `0` menyebabkan kunci segera kadaluarsa (efektifnya "don't cache").

- `OPTIONS`: Pilihan apapun yang harus dilewatkan ke backend cache. Daftar dari pilihan sah akan beragam dengan setiap backend, dan backend cache oleh pustaka pihak-ketiga akan melewatkan pilihan mereka langsung ke pustaka cache pokok.

  Backend cache yang menerapkan strategi pemusnahan mereka sendiri (yaitu, backend `locmem`, `filesystem` dan `database`) akan menghormati pilihan-pilihan berikut:

  - `MAX_ENTRIES`: Nomor maksimal dari masukan diizinkan di cache sebelum nilai-nilai lama dihapus. Argumen ini awalan pada `300`.

  - CULL_FREQUENCY`: Pecahan masukan yang dimusnahkan ketika `MAX_ENTRIES` dicapai. Rasio sebenarnya adalah `1 / CULL_FREQUENCY`, jadi menyetel `CULL_FREQUENCY` menjadi `2` pada pemusnahan setengah masukan ketika `MAX_ENTRIES``dicapai. Argumen ini harus berupa integer dan awalan pada ``3`.

    Sebuah nilai dari `0` untuk `CULL_FREQUENCY` berarti bahwa keseluruhan cache akan dibuang ketika `MAX_ENTRIES` dicapai. Pada beberapa backend (`database` khususnya) ini membuat pemusnahan jauh lebih cepat pada pengeluaran dari lebih cache luput.

  Backend Memcached dan Redis melewatkan isi `OPTIONS` sebagai argumen kata kunci ke constructor klien, mengizinkan untuk kendali tingkatan lebih dari perilaku klien. Contoh penggunaan, lihat dibawaah.

- `KEY_PREFIX`: Sebuah string yang akan otomatis disertakan (ditambahkan secara awalan) ke semua kunci-kunci cache digunakan oleh peladen Django.

  Lihat cache documentation untuk informasi lebih.

- `VERSION`: Nomor versi awalan untuk kunci-kunci cache dibangkitkan oleh peladen Django.

  Lihat the cache documentation untuk informasi lebih.

- `KEY_FUNCTION` Sebuah string mengandung jalur bertitik pada sebuah fungsi yang menentukan bagaimana menyusun sebuah awalan, versi dan kunci kedalam kunci cache akhir.

  Lihat cache documentation untuk informasi lebih.

Di contoh ini, backend sistem berkas sedang dikonfigurasikan dengan waktu habis dari 60 detik, dan kapasitas maksimal dari 1000 barang:

    CACHES = {
        "default": {
            "BACKEND": "django.core.cache.backends.filebased.FileBasedCache",
            "LOCATION": "/var/tmp/django_cache",
            "TIMEOUT": 60,
            "OPTIONS": {"MAX_ENTRIES": 1000},
        }
    }

Ini adalah sebuah contoh konfigurasi untuk backend berdasarkan `pylibmc` yang mengadakan protokol biner, autentifikasi SASL, dan suasana perilaku `ketama`:

    CACHES = {
        "default": {
            "BACKEND": "django.core.cache.backends.memcached.PyLibMCCache",
            "LOCATION": "127.0.0.1:11211",
            "OPTIONS": {
                "binary": True,
                "username": "user",
                "password": "pass",
                "behaviors": {
                    "ketama": True,
                },
            },
        }
    }

Berikut adalah contoh konfigurasi untuk backend berbasis `pymemcache` yang memungkinkan penyatuan klien (yang dapat meningkatkan performa dengan menjaga klien tetap terhubung), memperlakukan kesalahan memcache/jaringan sebagai tembolok yang hilang, dan menyetel bendera``TCP_NODELAY`` pada soket koneksi

    CACHES = {
        "default": {
            "BACKEND": "django.core.cache.backends.memcached.PyMemcacheCache",
            "LOCATION": "127.0.0.1:11211",
            "OPTIONS": {
                "no_delay": True,
                "ignore_exc": True,
                "max_pool_size": 4,
                "use_pooling": True,
            },
        }
    }

Here's an example configuration for a `redis` based backend that selects database `10` (by default Redis ships with 16 logical databases), and sets a custom connection pool class (`redis.ConnectionPool` is used by default):

    CACHES = {
        "default": {
            "BACKEND": "django.core.cache.backends.redis.RedisCache",
            "LOCATION": "redis://127.0.0.1:6379",
            "OPTIONS": {
                "db": "10",
                "pool_class": "redis.BlockingConnectionPool",
            },
        }
    }

## Cache per-site

Sekali cache disetel, cara termudah menggunakan cacge adalah cache situs anda seluruhnya. Anda akan butuh menambahkan `'django.middleware.cache.UpdateCacheMiddleware'` dan `'django.middleware.cache.FetchFromCacheMiddleware'` ke pengaturan `MIDDLEWARE` anda, seperti di contoh ini:

    MIDDLEWARE = [
        "django.middleware.cache.UpdateCacheMiddleware",
        "django.middleware.common.CommonMiddleware",
        "django.middleware.cache.FetchFromCacheMiddleware",
    ]

Catatan

Tidak, itu bukan salah ketik: middleware "update" harus pertama di daftar, dan middleware "fetch" harus di terakhir. Rincian sedikit mengaburkan, tetapi lihat Order of MIDDLEWARE dibawah jika anda ingin cerita penuh.

Kemudian, tambah pengaturan dibutuhkan berikut ke berkas pengaturan Django anda:

- `CACHE_MIDDLEWARE_ALIAS` -- nama lain tembolok untuk digunakan untuk penyimpanan.

- `CACHE_MIDDLEWARE_SECONDS` -- Angka integer dari setiap halaman kedua harus di cache.

- `CACHE_MIDDLEWARE_KEY_PREFIX` -- jika cacge dibagi lintas banyak situs menggunakan pemasangan Django sama, setel ke nama dari situs, atau beberapa string lain yang unik pada instance Django ini, untuk mencegah tabrakan kunci. Gunakan sebuah string kosong jika anda tidak peduli.

`FetchFromCacheMiddleware` cache tanggapan GET dan HEAD dengan keadaan 200, dimana kepala permintaan dan tanggapan diizinkan. Tanggapan pada permintaan untuk URL sama dengan parameter permintaan berbeda dianggap menjadi halaman unik dan di cache terpisah. Middleware ini mengharapkan bahwa sebuah permintaan HEAD dijawab dengan kepala tanggapan sesuai seperti permintaan GET berkaitan; dalam hal ini itu dapat mengembalikan sebuah tanggapan GET cache untuk permintaan HEAD.

Selain itu, `UpdateCacheMiddleware` otomatis mensetel beberapa kepala dalam setiap `HttpResponse` yang mempengaruhi downstream caches:

- Setel kepala `Expires` ke tanggal/waktu saat ini ditambah menentukan `CACHE_MIDDLEWARE_SECONDS`.

- Setel kepala `Cache-Control` untuk memberikan umur maksimal untuk halaman -- kembali, dari pengaturan `CACHE_MIDDLEWARE_SECONDS`.

Lihat Middleware untuk lebih pada middleware

Jika sebuah tampilan menyetel waktu kadaluarsa cache nya sendiri (yaitu itu mempunyai bagian `max-age` di kepala `Cache-Control` nya) kemudian halaman akan di cache sampai waktu kadaluarsa, daripada `CACHE_MIDDLEWARE_SECONDS`. menggunakan penghias di `django.views.decorators.cache` anda dapat dengan mudah mensetel sebuah waktu kadaluarsa tampilan (menggunakan penghias `cache_control()`) atau meniadakan cache untuk sebuah tampilan (menggunakan penghias `never_cache()` decorator). Lihat bagian using other headers pada penghias ini.

Jika `USE_I18N`disetel menjadi ``True`` kemudian membangkitkan kunci cache akan menyertakan nama dari language aktif -- lihat juga Bagaimana Django menemukan pilihan bahasa). Ini mengizinkan anda dengan mudah cache situs banyak bahasa tanpa harus membuat kunci cache anda sendiri.

Kunci cache juga menyertakan current time zone ketika `USE_TZ` disetel menjadi `True`.

## Cache per-tampilan

django.views.decorators.cache.cache_page(timeout, *, cache=None, key_prefix=None)

Cara yang lebih terperinci untuk menggunakan kerangka caching adalah dengan menyimpan keluaran dari tampilan individual ke dalam caching. `Django.views.decorators.cache` mendefinisikan dekorator `cache_page` yang akan secara otomatis meng-cache respons tampilan untuk anda:

    from django.views.decorators.cache import cache_page

    @cache_page(60 * 15)
    def my_view(request): ...

`cache_page` mengambil argumen tunggal: waktu habis cacge, dalam detik. Di contoh diatas, hasil dari tampilan `my_view()` akan di cache untuk 15 menit. (catah bahwa kami telah menulis itu sebagai `60 * 15` untuk tujuan dapat dibaca. `60 * 15` akan di nilai menjadi `900` -- yaitu, 15 menit dikalikan oleh 60 detik per menit.)

Batas waktu tembolok yang ditetapkan oleh `cache_page` lebih diutamakan daripada direktif `max-age` dari kepala `Cache-Control`.

Cache per-tampilan, seperti cache per-site, adalah diambil sebagai datum masukan kendali dari URL. Jika banyak titik URL pada tampilan sama, setiap URL akan di cache terpisah. Melanjutkan contoh `my_view`, jika URLconf anda terlihat seperti ini:

    urlpatterns = [
        path("foo/<int:code>/", my_view),
    ]

kemudian permintaan pada `/foo/1/` dan `/foo/23/` akan di cache terpisah, seprti anda mungkin harapkan. Tetapi sekali URL tertentu (sebagai contoh, `/foo/23/`) telah diminta, permintaan berikut ke URL itu akan menggunakan cache.

`cache_page` dapat juga mengambil sebuah argumen kata kunci pilihan, `cache`, yang akan mengalihkan penghias menggunakan cache khusus (dari pengaturan `CACHES` anda) ketika cache menampilkan hasil. Secara awalan, cache `default` akan digunakan, tetapi anda dapat menentukan cache apapun anda inginkan:

    @cache_page(60 * 15, cache="special_cache")
    def my_view(request): ...

You can also override the cache prefix on a per-view basis. `cache_page` takes an optional keyword argument, `key_prefix`, which works in the same way as the `CACHE_MIDDLEWARE_KEY_PREFIX` setting for the middleware. It can be used like this:

    @cache_page(60 * 15, key_prefix="site1")
    def my_view(request): ...

Argumen `key_prefix` dan `cache` mungkin ditentukan bersama-sama. Argumen `key_prefix` dan `KEY_PREFIX` ditentukan dibawah `CACHES` akan digabungkan.

Selain itu, `cache_page` otomatis mensetel `Cache-Control` dan kepala `Expires` dalam tanggapan yang mempengaruhi downstream caches.

### Menentukan cache per-tampilan di URLconf

The examples in the previous section have hardcoded the fact that the view is cached, because `cache_page` alters the `my_view` function in place. This approach couples your view to the cache system, which is not ideal for several reasons. For instance, you might want to reuse the view functions on another, cache-less site, or you might want to distribute the views to people who might want to use them without being cached. The solution to these problems is to specify the per-view cache in the URLconf rather than next to the view functions themselves.

Anda dapat melakukannya dengan membungkus fungsi tampilan dengan `cache_page` saat anda merujuknya di URLconf. Inilah URLconf lama dari sebelumnya

    urlpatterns = [
        path("foo/<int:code>/", my_view),
    ]

Ini adalah hal yang sama, dengan `my_view` dibungkus di `cache_page`:

    from django.views.decorators.cache import cache_page

    urlpatterns = [
        path("foo/<int:code>/", cache_page(60 * 15)(my_view)),
    ]

## Cache bgian cetakan

Jika anda sedang mengejar lebih kendali, anda dapat juga cache fragmen cetakan menggunakan etiket cetakan `cache`. Untuk memberikan akses cetakan anda ke etiket ini, taruh `{% load cache %}` dekat atas dari cetakan anda.

Etiket cetakan `{% cache %}` menyimpan isi dari blok untuk sejumlah waktu yang diberikan. Itu mengambil setidaknya dua argumen: waktu habis cache, dalam detik, dan nama untuk memberikan bagian cache. Bagian di simpan selamanya jika waktu habis adalah `None`. Nama akan diambil dengan adanya, jangan menggunakan sebuah variabel. Sebagai contoh:

    {% load cache %}
    {% cache 500 sidebar %}
        .. sidebar ..
    {% endcache %}

Terkadang anda mungkin ingin menyimpan banyak salinan dari bagian tergantung pada beberapa dinamis data yang muncul didalam bagian. Sebagai contoh, anda mungkin ingin memisahkan salinan tersimpan dari batang sisi digunakan dalam contoh sebelumnya untuks etiap pengguna dari situs anda. Lakukan ini dengan melewatkan satu atau lebih argumen tambahan, yang mungkin berupa variabel dengan atau tanpa penyaring, pada etiket cetakan `{% cache %}` pada mencirikan secara unik bagian cache:

    {% load cache %}
    {% cache 500 sidebar request.user.username %}
        .. sidebar for logged-in user ..
    {% endcache %}

Jika `USE_I18N` disetel menjadi `True` cache middleware per-situs akan respect the active language. Untuk etiket cetakan `cache` anda dapat menggunakan satu dari translation-specific variables tersedia di cetakan untuk mencapai hasil sama:

    {% load i18n %}
    {% load cache %}

    {% get_current_language as LANGUAGE_CODE %}

    {% cache 600 welcome LANGUAGE_CODE %}
        {% translate "Welcome to example.com" %}
    {% endcache %}

Cache waktu habis dapat berupa sebuah variabel cetakan, selama variabel cetakan mengatasi nilai integer. Sebagai contoh, jika variabel cetakan `my_timeout` disetel menjadi nilai `600`, kemudian dua contoh berikut adalah setara:

    {% cache 600 sidebar %} ... {% endcache %}
    {% cache my_timeout sidebar %} ... {% endcache %}

Fitur ini berguna untuk menghindari pengulangan pada cetakan. Anda dapat menyetel batas waktu dalam variabel, di satu tempat, dan menggunakan kembali nilai tersebut.

Secara awalan, etiket cache akan mencoba menggunakan cache dipanggil "template_fragments". Jika tidak ada cache seperti itu ada, itu akan kembali menggunakan cache awalan. Anda mungkin memilih sebuah backend cache bergantian untuk digunakan dengan argumen kata kunci `using`, yang harus berupa argumen terakhir ke etiket.

    {% cache 300 local-thing ...  using="localcache" %}

Itu adalah dianggap sebuah kesalahan untuk menentukan sebuah nama cache yang tidak dikonfigurasi.

django.core.cache.utils.make_template_fragment_key(fragment_name, vary_on=None)

Jika anda ingin mengambil kunci cache digunakan untuk cache bagian, anda dapat menggunakan `make_template_fragment_key`. `fragment_name` adalah sama sebagai argumen kedua pada etiket cetakan `cache`; `vary_on` adalah sebuah daftar dari semua argumen tambahan dilewatkan etiket. Fungsi ini dapat berguna untuk membatalkan atau menimpa cache barang, sebagai contoh:

    >>> from django.core.cache import cache
    >>> from django.core.cache.utils import make_template_fragment_key
    # cache key for {% cache 500 sidebar username %}
    >>> key = make_template_fragment_key("sidebar", [username])
    >>> cache.delete(key)  # invalidates cached template fragment
    True

## API cache tingkat-bawah

Terkadang, cache sebuah seluruhnya halaman dibangun tidak mendapatkan anda sangat banyak, faktanya, nyaman berlebihan.

Mungkin, sebagai contoh, situs anda menyertakan sebuah tampilan yang hasilnya bergantung pada beberpa permintaan mahal, hasil dari yang berubah pada rentang berbeda. Dalam kasus ini, itu akan tidak sesuai menggunakan cache halaman-penuh yang strategi cache per-situs atau per-tampilan tawarkan, karena anda tidak ingin cache keseluruhan hasil (sejak beberapa data sering berubah), tetapi anda akan masih ingin cache hasil yang jarang berubah.

For cases like this, Django exposes a low-level cache API. You can use this API to store objects in the cache with any level of granularity you like. You can cache any Python object that can be pickled safely: strings, dictionaries, lists of model objects, and so forth. (Most common Python objects can be pickled; refer to the `Python documentation` for more information about pickling.)

### Mengakses cache

django.core.cache.caches

  Anda dapat mengakses cache dikonfigurasikan di pengaturan `CACHES` melalui obyek seperti-kamus: `django.core.cache.caches`. Permintaan berulang untuk nama lain sama di thread sama akan mengembalikab obyek sama.

      >>> from django.core.cache import caches
      >>> cache1 = caches["myalias"]
      >>> cache2 = caches["myalias"]
      >>> cache1 is cache2
      True

  Jika kunci yang dinamai tidak ada, `InvalidCacheBackendError` akan muncul.

  Untuk menyediakan thread-safety, sebuah instance berbeda dari backend cache akan dikembalikan untuk setiap thread.

django.core.cache.cache

  Sebagai jalan pintas, cache awalan tersedia sebagai `django.core.cache.cache`:

      >>> from django.core.cache import cache

  Obyek ini setara terhadap `caches['default']`.

### Penggunaan dasar

Antarmuka dasar adalah:

cache.set(key, value, timeout=DEFAULT_TIMEOUT, version=None)

    >>> cache.set("my_key", "hello, world!", 30)

cache.get(key, default=None, version=None)

    >>> cache.get("my_key")
    'hello, world!'

`key` harus berupa sebuah `str`, dan `value` dapat berupa obyek Python picklable.

Argumen `timeout` adalah pilihan dan awalan pada argumen `timeout` dari backend sesuai di pengaturan `CACHES` (dijelaskan diatas). Itu adalah jumlah nilai kedua harus disimpan di cache. Melewatkan di `None` untuk `timeout` akan cache nilai selamanya. Sebuah `timeout` dari `0` tidak akan cache nilai.

Jika objek tidak ada dalam cache, `cache.get()` mengembalikan `None`:

    >>> # Wait 30 seconds for 'my_key' to expire...
    >>> cache.get("my_key")
    None

JIka anda butuh menentukan apakah objek ada dalam cache dan anda telah menyimpan nilai harfiah `None`, gunakan objek penjaga sebagai awalan:

    >>> sentinel = object()
    >>> cache.get("my_key", sentinel) is sentinel
    False
    >>> # Wait 30 seconds for 'my_key' to expire...
    >>> cache.get("my_key", sentinel) is sentinel
    True

`cache.get()` can take a `default` argument. This specifies which value to return if the object doesn't exist in the cache:

    >>> cache.get("my_key", "has expired")
    'has expired'

cache.add(key, value, timeout=DEFAULT_TIMEOUT, version=None)

To add a key only if it doesn't already exist, use the `add()` method. It takes the same parameters as `set()`, but it will not attempt to update the cache if the key specified is already present:

    >>> cache.set("add_key", "Initial value")
    >>> cache.add("add_key", "New value")
    >>> cache.get("add_key")
    'Initial value'

Jika anda butuh mengetahui apakah `add()` menyimpan sebuah nilai di cache, anda dapat memeriksa nilai kembalian. Itu akan mengembalikan `True` jika nilai telah disimpan, `False` sebaliknya.

cache.get_or_set(key, default, timeout=DEFAULT_TIMEOUT, version=None)

If you want to get a key's value or set a value if the key isn't in the cache, there is the `get_or_set()` method. It takes the same parameters as `get()` but the default is set as the new cache value for that key, rather than returned:

    >>> cache.get("my_new_key")  # returns None
    >>> cache.get_or_set("my_new_key", "my new value", 100)
    'my new value'

Anda juga dapat melewatkan callable apapun sebagai nilai default:

    >>> import datetime
    >>> cache.get_or_set("some-timestamp-key", datetime.datetime.now)
    datetime.datetime(2014, 12, 11, 0, 15, 49, 457920)

cache.get_many(keys, version=None)

There's also a `get_many()` interface that only hits the cache once. `get_many()` returns a dictionary with all the keys you asked for that actually exist in the cache (and haven't expired):

    >>> cache.set("a", 1)
    >>> cache.set("b", 2)
    >>> cache.set("c", 3)
    >>> cache.get_many(["a", "b", "c"])
    {'a': 1, 'b': 2, 'c': 3}

cache.set_many(dict, timeout)

To set multiple values more efficiently, use `set_many()` to pass a dictionary of key-value pairs:

    >>> cache.set_many({"a": 1, "b": 2, "c": 3})
    >>> cache.get_many(["a", "b", "c"])
    {'a': 1, 'b': 2, 'c': 3}

Seperti `cache.set()`, `set_many()` mengambil sebuah pilihan parameter `timeout`.

Pada backend didukung (memcached), `set_many()` megnembalikan sebuah daftar dari kunci-kunci yang gagal dimasukkan.

cache.delete(key, version=None)

Anda dapat menghapus kunci secara eksplisit dengan `delete()` untuk membersihkan cache untuk objek tertentu:

    >>> cache.delete("a")
    True

`delete()` returns `True` if the key was successfully deleted, `False` otherwise.

cache.delete_many(keys, version=None)

If you want to clear a bunch of keys at once, `delete_many()` can take a list of keys to be cleared:

    >>> cache.delete_many(["a", "b", "c"])

cache.clear()

Finally, if you want to delete all the keys in the cache, use `cache.clear()`. Be careful with this; `clear()` will remove everything from the cache, not just the keys set by your application:

    >>> cache.clear()

cache.touch(key, timeout=DEFAULT_TIMEOUT, version=None)

`cache.touch()` sets a new expiration for a key. For example, to update a key to expire 10 seconds from now:

    >>> cache.touch("a", 10)
    True

Like other methods, the `timeout` argument is optional and defaults to the `TIMEOUT` option of the appropriate backend in the `CACHES` setting.

`touch()` mengembalikan `True` jika kunci berhasil disentuh, `False` sebaliknya.

cache.incr(key, delta=1, version=None)

cache.decr(key, delta=1, version=None)

You can also increment or decrement a key that already exists using the `incr()` or `decr()` methods, respectively. By default, the existing cache value will be incremented or decremented by 1. Other increment/decrement values can be specified by providing an argument to the increment/decrement call. A ValueError will be raised if you attempt to increment or decrement a nonexistent cache key:

    >>> cache.set("num", 1)
    >>> cache.incr("num")
    2
    >>> cache.incr("num", 10)
    12
    >>> cache.decr("num")
    11
    >>> cache.decr("num", 5)
    6

Catatan

Metide `incr()`/`decr()` tidak menjamin menjadi atom, Pada backend itu yang mendukung penaikan/penurunan atom (kebanyakan terutama backend memcache), penaikan dan penurunan akan menjadi atom. Bagaimanapun, jika backend tidak asli menyediakan sebuah tindakan penaikan/penurunan, itu akan diterapkan menggunakan dua-langkah mengambil/memperbaharui.

cache.close()

Anda dapat menutup hubungan ke cache anda dengan `close()` jika diterapkan oleh backend cache.

    >>> cache.close()

Catatan

Untuk cache yang tidak menerapkan metode `close` itu adalah no-op.

Catatan

The async variants of base methods are prefixed with `a`, e.g. `cache.aadd()` or `cache.adelete_many()`. See Asynchronous support for more details.

### Awalan kunci cache

Jika anda sedang berbagi sebuah instance cache diantara peladen, atau diantara lingkungan produksi dan pengembangan anda, itu memungkinkan untuk data cache oleh satu peladen untuk digunakan oleh peladen lain. Jika bentuk dari data cache berbeda diantara peladen, ini dapat membawa ke sangat keras dari mengenal masalah-masalah.

Untuk mencegah ini, Django menyediakan kemampuan untuk mengawali semua kunci cache digunakan oleh peladen. Ketika kunci cacge tertentu disimpan atau diambil, Django akan secara otomatis mengawali kunci cache dengan nilai dari pengaturan cache `KEY_PREFIX`.

Dengan memastikan setiap instance Django mempunyai `KEY_PREFIX` berbeda, anda dapat memastikan bahwa akan tidak ada tubrukan di nilai-nilai cache.

### Memversikan cache

Ketika anda merubah menjalankan kode yang menggunakan nilai cache, anda mungkin butuh membersihkan nilai-nilai cache yang ada. Cara termudah melakukan ini adalah membilas keseluruhan cache, tetapi ini dapat membawa ke kehilangan nilai cache yang masih sah dan berguna.

Django menyediakan cara terbaik pada nilai-nilai cache masing-masing sasaran. Kerangka kerja cache Django mempunyai penciri versi lebar-sistem, ditentukan menggunakan pengaturan cache `VERSION`. Nilai dari pengaturan ini secara otomatis dipadukan dengan awalan cache dan kunci cache disediakan-pengguna untuk mendapatkan kunci cache akhir.

By default, any key request will automatically include the site default cache key version. However, the primitive cache functions all include a `version` argument, so you can specify a particular cache key version to set or get. For example:

    >>> # Set version 2 of a cache key
    >>> cache.set("my_key", "hello world!", version=2)
    >>> # Get the default version (assuming version=1)
    >>> cache.get("my_key")
    None
    >>> # Get version 2 of the same key
    >>> cache.get("my_key", version=2)
    'hello world!'

The version of a specific key can be incremented and decremented using the `incr_version()` and `decr_version()` methods. This enables specific keys to be bumped to a new version, leaving other keys unaffected. Continuing our previous example:

    >>> # Increment the version of 'my_key'
    >>> cache.incr_version("my_key")
    >>> # The default version still isn't available
    >>> cache.get("my_key")
    None
    # Version 2 isn't available, either
    >>> cache.get("my_key", version=2)
    None
    >>> # But version 3 *is* available
    >>> cache.get("my_key", version=3)
    'hello world!'

### Perubahan kunci cache

Seperti digambarkan di dua bagian sebelumnya, kunci cache disediakan oleh seorang pengguna tidak digunakan secara harfiah -- itu dipadukan dengan awalan cache dan versi kunci untuk menyediakan kunci cache akhir. Secara awalan, tiga bagian digabungkan menggunakan titik dua untuk menghasilkan string akhir:

    def make_key(key, key_prefix, version):
        return "%s:%s:%s" % (key_prefix, version, key)

Jika anda ingin memadukan bagian-bagian di cara berbeda, atau memberlakukan pengolahan lain menjadi kunci akhir (sebagai contoh, mengambil campuran inti dari bagian-bagian kunci), anda daat menyediakan sebuah fungsi kunci penyesuaian.

Pengaturan cache `KEY_FUNCTION` menentukan jalur-bertitik pada sebuah fungsi mencocokan purwa-rupa dari `make_key()` diatas. Jika disediakan, fungsi kunci penyesuaian ini akan digunakan sebagai gantia dari kunci awalan memadukan fungsi.

### Peringatan kunci cache

Memcache, backend cache paling digunakan-umum produksi, tidak mengizinkan kunci cache lebih panjang dari 250 karakter atau mengandung ruang kosong atau kendali karakter, dan menggunakan kunci seperti itu akan menyebabkan sebuah pengecualian. Untuk mendorong kode ringan-cache menerbitkan sebuah peringatan (`django.core.cache.backends.base.CacheKeyWarning`) jika sebuah kecil yang dapat menyebabkan sebuah kesalahan pada memcache.

Jika anda sedang menggunakan backend produksi yang dapat menerima jangkauan lebih luas dari kunci (backend penyesuaian, atau satu dari bukan-memcache backend siap-pakai), dan ingin menggunakan jangkauan luas ini tanpa peringatan, anda dapat mendiamkan `CacheKeyWarning` dengan kode ini di modul `management` dari satu dari `INSTALLED_APPS` anda:

    import warnings

    from django.core.cache import CacheKeyWarning

    warnings.simplefilter("ignore", CacheKeyWarning)

Jika anda ingin daripada menyediakan penyesuaian logika pengecekan kunci untuk satu dari backend pasang-tetap, anda dapat mensubkelaskannya, timpa hanya metode `validate_key`, dan ikuti petunjuk untuk using a custom cache backend. Sebagai contoh, untuk melakukan ini untuk backend `locmem`, taruh kode ini di modul:

    from django.core.cache.backends.locmem import LocMemCache

    class CustomLocMemCache(LocMemCache):
        def validate_key(self, key):
            """Custom validation, raising exceptions or warnings as needed."""
            ...

...dan menggunakan jalur Python bertitik pada kelas ini di bagain `BACKEND` dari pengaturan `CACHES`.

## Dukungan asinkronus

Django has developing support for asynchronous cache backends, but does not yet support asynchronous caching. It will be coming in a future release.

`django.core.cache.backends.base.BaseCache` has async variants of all base methods. By convention, the asynchronous versions of all methods are prefixed with `a`. By default, the arguments for both variants are the same:

    >>> await cache.aset("num", 1)
    >>> await cache.ahas_key("num")
    True

## Cache hilir

So far, this document has focused on caching your own data. But another type of caching is relevant to web development, too: caching performed by "downstream" caches. These are systems that cache pages for users even before the request reaches your website.

Ini adalah sedikit contoh dari cache hilir:

- When using HTTP, your ISP may cache certain pages, so if you requested a page from `http://example.com/`, your ISP would send you the page without having to access example.com directly. The maintainers of example.com have no knowledge of this caching; the ISP sits between example.com and your web browser, handling all of the caching transparently. Such caching is not possible under HTTPS as it would constitute a man-in-the-middle attack.

- Situs jaringan Django anda mungkin duduk dibelakang cache proxy, seperti Squid Web Proxy Cache (http://www.squid-cache.org/), yang cache halaman untuk penampilan. Dalam kasus ini, setiap permintaan pertama akan ditangani oleh proxy, dan itu akan dilewatkan ke aplikasi anda jika dibutuhkan.

- Your web browser caches pages, too. If a web page sends out the appropriate headers, your browser will use the local cached copy for subsequent requests to that page, without even contacting the web page again to see whether it has changed.

Downstream caching is a nice efficiency boost, but there's a danger to it: Many web pages' contents differ based on authentication and a host of other variables, and cache systems that blindly save pages based purely on URLs could expose incorrect or sensitive data to subsequent visitors to those pages.

For example, if you operate a web email system, then the contents of the "inbox" page depend on which user is logged in. If an ISP blindly cached your site, then the first user who logged in through that ISP would have their user-specific inbox page cached for subsequent visitors to the site. That's not cool.

Untungnya, HTTP menyediakan sebuah pemecahan pada masalah ini. Sejumlah kepala HTTP ada untuk memberikan petunjuk cache hilir untuk membedakan isi cache mereka bergantung pada variabel-variabel ditunjuk, dan memberitahu mekanisme cache tidak meng cache halaman tertentu. Kami akan mencari beberapa kepala ini di bagian-bagian yang mengikuti.

## Menggunakan kepala `Vary`

The `Vary` header defines which request headers a cache mechanism should take into account when building its cache key. For example, if the contents of a web page depend on a user's language preference, the page is said to "vary on language."

Secara awalan, sistem cache Django membuat kunci cache nya menggunakan URL sepenuhnya-memenuhi syarat diminta -- sebagai contoh, `"https://www.example.com/stories/2005/?order_by=author"`. Ini berarti setiap permintaan ke URL itu akan menggunakan versi cache sama, tanpa memperhatikan dari perbedaan agen-pengguna seperti kue atau pilihan bahasa. Bagaimanapun, jika halaman ini menghasilkan isi berbeda berdasarkan pada beberapa perbedaan di kepala permintaan -- seperti sebuah kue, atau sebuah bahasa, atau agen-pengguna -- anda akan butuh menggunakan kepala `Vary` untuk memberitahu mekanisme cache yang keluaran halaman bergantung pada hal-hal tersebut.

Untuk melakukan ini di Django, gunakan penghias tampilan `django.views.decorators.vary.vary_on_headers()` nyaman, seperti begitu:

    from django.views.decorators.vary import vary_on_headers

    @vary_on_headers("User-Agent")
    def my_view(request): ...

Di kasus ini, mekanisme cache (seperti middleware cache sendiri Django) akan cache sebuah versi terpisah dari halaman untuk setiap agen-pengguna unik.

The advantage to using the `vary_on_headers` decorator rather than manually setting the `Vary` header (using something like `response.headers['Vary'] = 'user-agent'`) is that the decorator adds to the `Vary` header (which may already exist), rather than setting it from scratch and potentially overriding anything that was already in there.

Anda dapat melewatkan banyak kepala pada `vary_on_headers()`:

    @vary_on_headers("User-Agent", "Cookie")
    def my_view(request): ...

Ini memberitahukan cache hilir untuk vary pada kedua, yang berarti setiap perpaduan dari agen-pengguna dan kue akan mendapatkan nilai cache nya sendiri. Sebagai contoh, sebuah permintaan dengan agen-pengguna `Mozilla` dan nilai kue `foo=bar` akan dianggap berbeda dari permintaan dengan agen-pengguna `Mozilla` dan nilai kue `foo=ham`.

Karena beragam pada kue adalah sangat umum, ada sebuah penghias `django.views.decorators.vary.vary_on_cookie()`. Kedua tampilan ini adalah setara:

    @vary_on_cookie
    def my_view(request): ...

    @vary_on_headers("Cookie")
    def my_view(request): ...

Kepala anda lewatkan ke `vary_on_headers` tidak hal-hal sensitif; `"User-Agent"` adalah hal sama seperti `"user-agent"`.

Anda dapat juga menggunakan fungsi pembantu, `django.utils.cache.patch_vary_headers()`, secara langsung. Fungsi ini menyetel, atau menambah ke, `Vary header`. Sebagai contoh:

    from django.shortcuts import render
    from django.utils.cache import patch_vary_headers

    def my_view(request):
        ...
        response = render(request, "template_name", context)
        patch_vary_headers(response, ["Cookie"])
        return response

`patch_vary_headers` mengambil sebuah instance `HttpResponse` sebagai argumen pertamanya dan sebuah list/tuple dari nama-nama kepala kasus-tidak-peka sebagai argumen keduanya.

Untuk informasi lebih lanjut tentang header Vary, lihat official Vary spec.

## Mengendalikan tembolok: Menggunakan kepala lainnya

Masalah lain dengan cache adalah pribadi dari data dan pertanyaan dari dimana data harus disimpan di cache urutan kebawah.

A user usually faces two kinds of caches: their own browser cache (a private cache) and their provider's cache (a public cache). A public cache is used by multiple users and controlled by someone else. This poses problems with sensitive data--you don't want, say, your bank account number stored in a public cache. So web applications need a way to tell caches which data is private and which is public.

Pemecahannya adalah menunjukkan cache halaman harus berupa "private". Untuk melakukan ini di Django, gunakan penghias tampilan `cache_control()`. Contoh:

    from django.views.decorators.cache import cache_control

    @cache_control(private=True)
    def my_view(request): ...

Penghias ini merawat dari mengirim keluar kepala HTTP sesuai dibelakang layar.

Catat bahwa pengaturan kendali cache "pribadi" and "umum" adalah saling eksklusif. Penghias memastikan bahwa petunjuk "umum: dipindahkan jika "pribadi" harus disetel (dan sebaliknya). Sebuah contoh penggunaan daro dua petunjuk akan menjadi sebuah situs blog yang menawarkan kedua masukan pribadi dan umum. Masukan umum mungkin di cache pada cache berbagi apapun. Kode berikut menggunakan `patch_cache_control()`, cara manual untuk merubah kepala kendali cache (itu adalah secara internal dipanggil oleh penghias `cache_control()`):

    from django.views.decorators.cache import patch_cache_control
    from django.views.decorators.vary import vary_on_cookie

    @vary_on_cookie
    def list_blog_entries_view(request):
        if request.user.is_anonymous:
            response = render_only_public_entries()
            patch_cache_control(response, public=True)
        else:
            response = render_private_and_public_entries(request.user)
            patch_cache_control(response, private=True)

        return response

You can control downstream caches in other ways as well (see RFC 9111 for details on HTTP caching). For example, even if you don't use Django's server-side cache framework, you can still tell clients to cache a view for a certain amount of time with the max-age directive:

    from django.views.decorators.cache import cache_control

    @cache_control(max_age=3600)
    def my_view(request): ...

(Jika anda melakukan menggunakan middleware cache, itu sudah disetel `max-age` dengan nilai dari pengaturan `CACHE_MIDDLEWARE_SECONDS`. Dalam kasus itu, penyesuaian `max-age` dari penghias `cache_control()` akan mengambil hak lebih tinggi, dan nilai-nlai kepala akan digabung dengan benar.)

`Cache-Control` sah apapun menangganpi petunjuk adalah sah di `cache_control()`. Ini adalah beberapa contoh lebih:

- `no_transform=True`

- `must_revalidate=True`

- `stale_while_revalidate=num_seconds`

- `no_cache=True`

Daftar penuh dari arahan dikenal dapat ditemukan di IANA registry (catat bahwa tidak semua dari mereka memberlakukan terhadap tanggapan).

Jika anda ingin menggunakan kepala untuk meniadakan cache sama sekali, `never_cache()` adalah tampilan penghias yang menambahkan kepala-kepala untuk memastikan tanggapan tidak akan di cache oleh peramban atau cache lain. Contoh:

    from django.views.decorators.cache import never_cache

    @never_cache
    def myview(request): ...

## urutan dari `MIDDLEWARE`

Jika anda menggunakan middleware cache, itu adalah penting untuk menaruh setiap setengah di tempat kanan dalam pengaturan `MIDDLEWARE`, Itu karena middleware cache butuh mengetahui kepala-kepala mana yang digunakan oleh cary pentimpan cache. Middleware selau menambahkan sesuatu ke kepala tanggapan `Vary` ketika itu dapat.

`UpdateCacheMiddleware` berjalan selama fase tanggapan, dimana middleware berjalan di membalikkan urutan, jadi sebuah barang pada teratas dari daftar menjalankan terakhir selama fase tanggapan. Dengan demikian, anda butuh memastikan bahwa `UpdateCacheMiddleware` muncul sebelum middleware lain apapun yang mungkin menambahkan sesuatu ke kepala `Vary`. Modul middleware berikut melakukannya:

- `SessionMiddleware` menambah `Cookie`

- `GZipMiddleware` menambah `Accept-Encoding`

- `LocaleMiddleware` menambah `Accept-Language`

`FetchFromCacheMiddleware`, di sisi lain, berjalan selama fase permintaan, dimana middleware diberlakukan pertama-ke-terakhir, jadi sebuah barang pada teratas dari daftar berjalan pertama selama fase permintaan. `FetchFromCacheMiddleware` juga butuh menjalankan setelah middleware lain memperbaharui kepala `vary`, jadi `FetchFromCacheMiddleware` harus berupa setelah barang apapun yang melakukannya.