python / expert
Snippet
Django Template Loaders with Custom Namespace and Caching Strategy
Custom template loaders extend Django's template loading pipeline with namespace resolution and in-memory caching. By implementing Loader interface and overriding get_template_sources, you enable namespaced template resolution (namespace:template syntax). The MD5-based cache key ensures efficient template caching while the one-hour timeout balances freshness with performance gains.
snippet.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import hashlibfrom django.template import TemplateDoesNotExistfrom django.template.loaders.base import Loaderfrom django.core.cache import cacheclass CachedNamespaceLoader(Loader):def __init__(self, engine, dirs, namespaces):super().__init__(engine, dirs)self.namespaces = namespaces or {}self._template_cache = {}def get_template_sources(self, template_name):namespace, _, template = template_name.partition(':')if namespace in self.namespaces:base_dirs = self.namespaces[namespace]for dir in base_dirs:try:yield self.get_template_path(f'{template}', dir)except FileNotFoundError:continuedef get_contents(self, origin):cache_key = f'template:{hashlib.md5(origin.name.encode()).hexdigest()}'template_source = cache.get(cache_key)if template_source is None:template_source = super().get_contents(origin)cache.set(cache_key, template_source, timeout=3600)return template_sourcedef get_template_path(self, template_name, dir):path = f'{dir}/{template_name}'if not os.path.exists(path):raise FileNotFoundError(f'Template {path} not found')return path
django
Breakdown
1
class CachedNamespaceLoader(Loader):
Extends Django's base Loader implementing custom loading logic
2
namespace, _, template = template_name.partition(':')
Splits namespace:template syntax for custom resolution
3
cache_key = f'template:{hashlib.md5(origin.name.encode()).hexdigest()}'
Creates deterministic cache key from template path hash
4
cache.set(cache_key, template_source, timeout=3600)
Caches compiled template source for one hour
5
yield self.get_template_path(f'{template}', dir)
Yields resolved template path for each namespace directory