Django - caching multiple sites

I have several sites under one Django application in which I would like to implement caching on the site. However, this proves that this is a real hassle.

what happens is that settings.CACHE_MIDDLEWARE_KEY_PREFIX set once at startup, and I cannot go further and change it depending on what the current site is. As a result, if the url page http://website1.com/abc/ cached, then http://website2.com/abc/ displays the cached version of http://website1.com/abc/ . Both of these websites run on the same instance of Django, as this is what allows us to make Django Sites.

Is this the wrong approach? Since at runtime I cannot dynamically set CACHE_MIDDLEWARE_KEY_PREFIX , I cannot cache multiple sites using Django site caching. I also can not do this for the template and view caching.

I get the impression that the way that this really needs to be set up is that each site needs its own instance of Django, which is pretty much identical, except for the settings file, which in my case will differ only by the value CACHE_MIDDLEWARE_KEY_PREFIX . These instances Django all read and write to the same database. It concerns me, as this can create a number of new problems.

Am I following the right path, or am I mistaken about how to work with the architecture of several sites? I checked the Django docs and there is no real mention of how to handle caching (i.e. not low level caching) for Django applications serving multiple sites.

+6
django django-caching django-sites
source share
3 answers

(Disclaimer: The following is a pure assumption and has not been verified. Consume a pinch of salt.)

Perhaps you can use the alter_on_headers decorator to include the host header in the cache key. This should result in cache keys that include the HTTP Host header, thereby effectively isolating the caches for your sites.

 @vary_on_headers('Host') def my_view(request): # .... 

Of course, this will only work for each view, and adding a decorator to all views can be a big problem.

Digging into the @vary_on_headers source , it shows the use of patch_vary_headers () , which could be used in middleware to apply the same behavior at the site level. Something like:

 from django.utils.cache import patch_vary_headers class VaryByHostMiddleware(object): def process_response(self, request, response): patch_vary_headers(response, ('Host',)) return response 
+1
source share

I recently ran into this problem. What I did based on the documentation was to create a custom method to add the site ID to the key used to cache the view.

In settings.py add the argument KEY_FUNCTION:

 CACHES = { 'default': { 'BACKEND': 'path.to.backend', 'LOCATION': 'path.to.location', 'TIMEOUT': 60, 'KEY_FUNCTION': 'path.to.custom.make_key_per_site', 'OPTIONS': { 'MAX_ENTRIES': 1000 } } } 

And my own make_key method:

 def make_key_per_site(key, key_prefix, version): site_id = '' try: site = get_current_site() # Whatever you use to get your site data site_id = site['id'] except: pass return ':'.join([key_prefix, site_id, str(version), key]) 
+1
source share

You need to change get_full_path to build_absolute_uri in django.util.cache file

 def _generate_cache_header_key(key_prefix, request): """Returns a cache key for the header cache.""" #path = md5_constructor(iri_to_uri(request.get_full_path())) path = md5_constructor(iri_to_uri(request.build_absolute_uri())) # patch using full path cache_key = 'views.decorators.cache.cache_header.%s.%s' % ( key_prefix, path.hexdigest()) return _i18n_cache_key_suffix(request, cache_key) def _generate_cache_key(request, method, headerlist, key_prefix): """Returns a cache key from the headers given in the header list.""" ctx = md5_constructor() for header in headerlist: value = request.META.get(header, None) if value is not None: ctx.update(value) #path = md5_constructor(iri_to_uri(request.get_full_path())) path = md5_constructor(iri_to_uri(request.build_absolute_uri())) cache_key = 'views.decorators.cache.cache_page.%s.%s.%s.%s' % ( key_prefix, request.method, path.hexdigest(), ctx.hexdigest()) return _i18n_cache_key_suffix(request, cache_key) 

Or create your own weak caching middleware for multiple users. http://macrotoma.blogspot.com/2012/06/custom-multisite-caching-on-django.html

0
source share

All Articles