Opened 6 years ago

Closed 5 years ago

#11269 closed (fixed)

Allow key_prefix to be callable

Reported by: kmike Owned by: nobody
Component: Core (Cache system) Version: master
Severity: Keywords:
Cc: miracle2k, zeth Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:


"cache_page" decorator accepts "key_prefix" argument.

If "cache_page" will allow "key_prefix" to be callable it will be easier to fine-tune view caching.
For example, it will be easier to have per-user cache or to cache views based on specified GET parameters (there is dedicated #4992 ticket for that).

I've attached patch for that feature.

The sample syntax:

#have 2 static versions of the my_view response for authenticated and anonymous users

def my_key_prefix(request):
    if request.GET:
        return None #magic value to disable caching

    if request.user.is_authenticated():
        return 'logged_in'
        return 'not_logged_in'
@cache_page(600, my_key_prefix)
def my_view(request):
....... #something is different for authenticated and anonymous users
#cache my_paginated_view based on "page" parameter in query string
def page_key_prefix(request):
    return request.GET.get('page','')

@cache_page(60, page_key_prefix)
def my_paginated_view(request)
.... #page number is passed via 'page' GET parameter and used for pagination

Attachments (1)

callable_key_prefix.diff (2.4 KB) - added by kmike 6 years ago.

Download all attachments as: .zip

Change History (9)

Changed 6 years ago by kmike

comment:1 Changed 6 years ago by kmike

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset

Standalone app with cache_page_with prefix decorator:

comment:2 Changed 6 years ago by Alex

  • Triage Stage changed from Unreviewed to Accepted

comment:3 Changed 6 years ago by miracle2k

  • Cc miracle2k added

comment:4 Changed 6 years ago by zeth

For the second example, that of get parameters, I just generalise the whole thing, i.e. any and all get parameters are used for the key_prefix.

i.e. something like:

def get_requests(request):
    """Turn the GET parameters into a string.
    Used for caching."""
    key_prefix = ""
    # Get the parameters out
    parameters = request.GET.items()
    # Sort them so we only have one order in the cache
    # Turn it into a string
    for pair in parameters:
        for item in pair:
            key_prefix += "%s-" % item
    return key_prefix

@cache_page(600, my_key_prefix)
def my_view(request):
    #blah blah

This pattern seems to work for all the situations I have encountered so far. This seems to be more DRY than the example above.

comment:5 Changed 6 years ago by zeth

  • Cc zeth added

comment:6 Changed 6 years ago by Loststylus

zeth, your get_requests doesn't provide support for multiple GET-variables with the same name (for example, checkboxes sent via GET), so cached results for /?a=1 and /?a=1&a=3 would be the same.

comment:7 Changed 6 years ago by Loststylus

The workaround is to use

parameters = dict(request.GET).items()

instead of

parameters = request.GET.items()

comment:8 Changed 5 years ago by otherjacob

  • Resolution set to fixed
  • Status changed from new to closed

#13795 should have taken care of any use case for this.

Note: See TracTickets for help on using tickets.
Back to Top