Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 43 additions & 10 deletions django/utils/cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from django.core.cache import caches
from django.http import HttpResponse, HttpResponseNotModified
from django.utils.crypto import md5
from django.utils.encoding import iri_to_uri
from django.utils.http import http_date, parse_etags, parse_http_date_safe, quote_etag
from django.utils.log import log_response
from django.utils.regex_helper import _lazy_re_compile
Expand Down Expand Up @@ -333,20 +334,35 @@ def has_vary_header(response, header_query):
return header_query.lower() in existing_headers


def _i18n_cache_key_suffix(request, cache_key):
"""If necessary, add the current locale or time zone to the cache key."""
def _i18n_cache_key_suffix(request, cache_key:str) -> str:
"""
If necessary, add the current locale or time zone to the cache key.
"""
language_code = ""
timezone = ""

if settings.USE_I18N:
# first check if LocaleMiddleware or another middleware added
# LANGUAGE_CODE to request, then fall back to the active language
# which in turn can also fall back to settings.LANGUAGE_CODE
cache_key += ".%s" % getattr(request, "LANGUAGE_CODE", get_language())
language_code = getattr(request, "LANGUAGE_CODE", get_language())
if settings.USE_TZ:
cache_key += ".%s" % get_current_timezone_name()
return cache_key
timezone = get_current_timezone_name()

return cache_key.handle_cache_key_suffixes(
cache_key=cache_key, language_code=language_code, timezone=timezone
)





def _generate_cache_key(request, method, headerlist, key_prefix):
"""Return a cache key from the headers given in the header list."""
"""
Entry point for cache key generation.

Return a cache key from the headers given in the header list.
"""
ctx = md5(usedforsecurity=False)
for header in headerlist:
value = request.META.get(header)
Expand All @@ -359,19 +375,32 @@ def _generate_cache_key(request, method, headerlist, key_prefix):
url.hexdigest(),
ctx.hexdigest(),
)

return _i18n_cache_key_suffix(request, cache_key)


def _generate_cache_header_key(key_prefix, request):
"""Return a cache key for the header cache."""
url = md5(request.build_absolute_uri().encode("ascii"), usedforsecurity=False)
def _generate_cache_key_from_request(*, key_prefix, request):
uri = _get_uri_from_request(request)
url_hash = md5(uri, usedforsecurity=False)
cache_key = "views.decorators.cache.cache_header.%s.%s" % (
key_prefix,
url.hexdigest(),
url_hash.hexdigest(),
)
return _i18n_cache_key_suffix(request, cache_key)


def _generate_cache_key_from_uri(*, key_prefix, uri):

url_hash = md5(uri, usedforsecurity=False)
cache_key = "views.decorators.cache.cache_header.%s.%s" % (
key_prefix,
url_hash.hexdigest(),
)
Comment on lines +395 to +398
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
cache_key = "views.decorators.cache.cache_header.%s.%s" % (
key_prefix,
url_hash.hexdigest(),
)
cache_key = f"views.decorators.cache.cache_header.{key_prefix}.{url_hash.hexdigest()}"

f-string is easier to read, write, and less computationally expensive than legacy string formatting. More details.

Comment on lines +395 to +398
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
cache_key = "views.decorators.cache.cache_header.%s.%s" % (
key_prefix,
url_hash.hexdigest(),
)
cache_key = f"views.decorators.cache.cache_header.{key_prefix}.{url_hash.hexdigest()}"

f-string is easier to read, write, and less computationally expensive than legacy string formatting. More.

return _i18n_cache_key_suffix(cache_key)




def get_cache_key(request, key_prefix=None, method="GET", cache=None):
"""
Return a cache key based on the request URL and query. It can be used
Expand Down Expand Up @@ -411,6 +440,8 @@ def learn_cache_key(request, response, cache_timeout=None, key_prefix=None, cach
key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX
if cache_timeout is None:
cache_timeout = settings.CACHE_MIDDLEWARE_SECONDS

# Generate the cache key.
cache_key = _generate_cache_header_key(key_prefix, request)
if cache is None:
cache = caches[settings.CACHE_MIDDLEWARE_ALIAS]
Expand All @@ -426,6 +457,8 @@ def learn_cache_key(request, response, cache_timeout=None, key_prefix=None, cach
if header != "ACCEPT_LANGUAGE" or not is_accept_language_redundant:
headerlist.append("HTTP_" + header)
headerlist.sort()

# Set the cache key.
cache.set(cache_key, headerlist, cache_timeout)
return _generate_cache_key(request, request.method, headerlist, key_prefix)
else:
Expand Down