Cara Menghapus (Invalidate) page_cache django

Caching di django sungguh mudah, tinggal import fungsi decorator page_cache, tambahkan di view yang mau kita cache, dan bamm, selesai, halaman kita sekarang sudah masuk cache. Masalah muncul karena kadang kita ingin halaman ini kita invalidate, misal karena ada comment baru, ada update terbaru di halaman tersebut. Bagaimana cara invalidate page_cache?

Seperti umumnya fungsi cache, ada yang namanya key dan value yang mau kita cache. Namun di fungsi decorator django tidak memberi keleluasaan kita untuk set key, jadi jika ingin invalidate page_cache, kita harus tahu key dari view yang di-cache tersebut.

Setelah googling beberapa lama, nemu fungsi berikut:

from django.conf import settings


def expire_view_cache(
    view_name,
    args=[],
    namespace=None,
    key_prefix=None,
    method="GET"):

    """
    This function allows you to invalidate any view-level cache.

    view_name: view function you wish to invalidate or it's named url pattern
    args: any arguments passed to the view function
    namepace: optioal, if an application namespace is needed
    key prefix: for the @cache_page decorator for the function (if any)

    http://stackoverflow.com/questions/2268417/expire-a-view-cache-in-django
    added: method to request to get the key generating properly

    https://userlinux.net/django-and-memcache-clear-cache-keys.html
    """

    from django.core.urlresolvers import reverse
    from django.http import HttpRequest
    from django.utils.cache import get_cache_key
    from django.core.cache import cache
    from django.conf import settings
    # create a fake request object
    request = HttpRequest()
    request.method = method

    # saya tambahkan 2 baris berikut soalnya django 1.10 butuh ini
    request.META['SERVER_NAME'] = settings.SERVER_NAME
    request.META['SERVER_PORT'] = settings.SERVER_PORT
    # end
    if settings.USE_I18N:
        request.LANGUAGE_CODE = settings.LANGUAGE_CODE
    # Loookup the request path:
    if namespace:
        view_name = namespace + ":" + view_name
    request.path = reverse(view_name, args=args)
    # get cache key, expire if the cached item exists:
    key = get_cache_key(request, key_prefix=key_prefix)
    if key:
        if cache.get(key):
            cache.set(key, None, 0)
        return True
    return False

Saya menambahkan fungsi tersebut kedalam file utils.py di direktori root aplikasi (myapp/utils.py)

local_settings.py

SERVER_NAME = '127.0.0.1'
SERVER_PORT = '8000'

Setelah itu, panggil fungsi ini ketika ingin meng-invalidate page_cache. Saya menambahkan di Model post_save, karena asumsi saya, ketika Model tersebut di update/save, berarti ada yang baru, maka cache di clear biar perubahan tersebut muncul/terlihat.

models.py — post_save

from myapp.utils import expire_view_cache

# invalidate index page
invalidate = expire_view_cache('index')
if invalidate:
    print 'index cache cleared'

Sekarang coba masuk admin, update/save sebuah object, dan cache dari halaman index akan invalidate (clear).

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s