How to do a Django cache decorator that exclude by URL parameters

After asking on Reddit, I started digging on internet looking other projects with custom cache decorator and mixing various I was able to achieve this.

"""Custom cache decorator."""
from django.http import HttpResponse
from django.views.decorators.cache import cache_page as original_cache_page
from datetime import datetime
from functools import wraps


def cache_page(timeout, *, cache=None, key_prefix=None):
    """If logged error, if start/end_date is today no caching."""

    def decorator(func):
        @wraps(func)
        def func_wrapper(request, *args, **kwargs):
            if not request.user.is_authenticated:
                return HttpResponse(status=401)

            now = datetime.strftime(datetime.now(), "%Y-%m-%d")
            if (
                request.query_params.get("start_date") == now and request.query_params.get("end_date") == now
            ):
                return func(request, *args, **kwargs)

            return original_cache_page(timeout, key_prefix="_user_{}_".format(request.user.id))(func)(
                request, *args, **kwargs
            )

        return func_wrapper

    return decorator

We can see that this creates a custom decorator, check if the user is logged or not (with an error) and check if there are some parameters with the today date (in my case). If it is today no cache otherwise it will use the native method, also we are caching by user the response output.

So in your project you can replace:

from django.views.decorators.cache import cache_page

With:

from [yourporjectplaceholder].cache_decorator import cache_page

 

Liked it? Take a second to support Mte90 on Patreon!
Become a patron at Patreon!

Leave a Reply

Your email address will not be published. Required fields are marked *