A generic cache decorator around low level cache api

245 views
Skip to first unread message

suayip uzulmez

unread,
Aug 24, 2022, 6:03:43 PM8/24/22
to Django developers (Contributions to Django itself)
Usually, I need to construct a simple cache pipeline to optimize database access using low-level cache API (django.core.cache).

I think we could use a decorator as such to ease this process:

cached_context(key, *, timeout, cache)

I know higher-level utilities exist such as cache_page, however I think the decorator above provides more granularity over what to cache. For example, I usually need such decorator in model methods where I do some database aggregation operations based on the instance.

What do you think?

Adam Johnson

unread,
Aug 26, 2022, 5:24:39 AM8/26/22
to Django developers (Contributions to Django itself)
I'm not sure I quite understand your proposal. Are you suggesting a decorator that caches the results of every queryset that is resolved within the decorated function?

If so, I'm not sure how useful it would be. First, if a single query is problematic, there’s normally a way to optimize it within the database - for example, a materialized view allows you to “cache” query results and recompute them in the background. Second, QuerySets are lazy, so it could be surprising to decorate a function that returns a QuerySet that is not yet resolved.

--
You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-develop...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/facbcfa8-2404-4dc6-b56d-eb0f25ba491cn%40googlegroups.com.

suayip uzulmez

unread,
Aug 26, 2022, 7:45:13 AM8/26/22
to Django developers (Contributions to Django itself)
It doesn't necessarily have to be a QuerySet; any function or  method that takes some processing time could be decorated (e.g., an external call to an API). My aim is to reduce this code:

def do_some_processing():
    cache_key = "key"

    if cached_value := cache.get(cache_key):
        return cached_value

    fresh_value = do_some_computing()
    cache.set(cached_value, fresh_value, 30)
    return fresh_value

to this:

@cached_context("key", timeout=30)
def do_some_processing():
    return do_some_computing()


AFAIK cache.set evaluates QuerySets, how would that be a problem?.
26 Ağustos 2022 Cuma tarihinde saat 12:24:39 UTC+3 itibarıyla Adam Johnson şunları yazdı:

suayip uzulmez

unread,
Jan 2, 2023, 9:11:01 AM1/2/23
to Django developers (Contributions to Django itself)
I would like to see more opinions on this, I am using this type of utility in almost every project I make and it seems to me it would a decent utility function.

26 Ağustos 2022 Cuma tarihinde saat 14:45:13 UTC+3 itibarıyla suayip uzulmez şunları yazdı:

Diederik van der Boor

unread,
Jan 4, 2023, 12:06:28 PM1/4/23
to django-d...@googlegroups.com
You’d mean something like this (for inspiration)?


This would give the simplicity of using a @cache_results decorator,
while allowing to bypass or refresh the cache when needed.

I’m not sure but likely there are some packages that have a similar function.

Best,
Diederik

suayip uzulmez

unread,
Jan 7, 2023, 4:46:50 AM1/7/23
to Django developers (Contributions to Django itself)
Yes something like this. I would comment on implementation details, but at this point I want to know if people would be content to add this sort of functionality to core.
Of course, there bound to be a library that essentially does this, however seeing it as such a common utility I think it would be great to have it in core and not bother with a 3rd party library.

4 Ocak 2023 Çarşamba tarihinde saat 20:06:28 UTC+3 itibarıyla Diederik van der Boor şunları yazdı:
Reply all
Reply to author
Forward
0 new messages