docker setup
This commit is contained in:
		| @ -0,0 +1,13 @@ | ||||
| """ | ||||
| Wrapper for loading templates from "templates" directories in INSTALLED_APPS | ||||
| packages. | ||||
| """ | ||||
|  | ||||
| from django.template.utils import get_app_template_dirs | ||||
|  | ||||
| from .filesystem import Loader as FilesystemLoader | ||||
|  | ||||
|  | ||||
| class Loader(FilesystemLoader): | ||||
|     def get_dirs(self): | ||||
|         return get_app_template_dirs("templates") | ||||
| @ -0,0 +1,51 @@ | ||||
| from django.template import Template, TemplateDoesNotExist | ||||
|  | ||||
|  | ||||
| class Loader: | ||||
|     def __init__(self, engine): | ||||
|         self.engine = engine | ||||
|  | ||||
|     def get_template(self, template_name, skip=None): | ||||
|         """ | ||||
|         Call self.get_template_sources() and return a Template object for | ||||
|         the first template matching template_name. If skip is provided, ignore | ||||
|         template origins in skip. This is used to avoid recursion during | ||||
|         template extending. | ||||
|         """ | ||||
|         tried = [] | ||||
|  | ||||
|         for origin in self.get_template_sources(template_name): | ||||
|             if skip is not None and origin in skip: | ||||
|                 tried.append((origin, "Skipped to avoid recursion")) | ||||
|                 continue | ||||
|  | ||||
|             try: | ||||
|                 contents = self.get_contents(origin) | ||||
|             except TemplateDoesNotExist: | ||||
|                 tried.append((origin, "Source does not exist")) | ||||
|                 continue | ||||
|             else: | ||||
|                 return Template( | ||||
|                     contents, | ||||
|                     origin, | ||||
|                     origin.template_name, | ||||
|                     self.engine, | ||||
|                 ) | ||||
|  | ||||
|         raise TemplateDoesNotExist(template_name, tried=tried) | ||||
|  | ||||
|     def get_template_sources(self, template_name): | ||||
|         """ | ||||
|         An iterator that yields possible matching template paths for a | ||||
|         template name. | ||||
|         """ | ||||
|         raise NotImplementedError( | ||||
|             "subclasses of Loader must provide a get_template_sources() method" | ||||
|         ) | ||||
|  | ||||
|     def reset(self): | ||||
|         """ | ||||
|         Reset any state maintained by the loader instance (e.g. cached | ||||
|         templates or cached loader modules). | ||||
|         """ | ||||
|         pass | ||||
| @ -0,0 +1,100 @@ | ||||
| """ | ||||
| Wrapper class that takes a list of template loaders as an argument and attempts | ||||
| to load templates from them in order, caching the result. | ||||
| """ | ||||
|  | ||||
| import hashlib | ||||
|  | ||||
| from django.template import TemplateDoesNotExist | ||||
| from django.template.backends.django import copy_exception | ||||
|  | ||||
| from .base import Loader as BaseLoader | ||||
|  | ||||
|  | ||||
| class Loader(BaseLoader): | ||||
|     def __init__(self, engine, loaders): | ||||
|         self.get_template_cache = {} | ||||
|         self.loaders = engine.get_template_loaders(loaders) | ||||
|         super().__init__(engine) | ||||
|  | ||||
|     def get_dirs(self): | ||||
|         for loader in self.loaders: | ||||
|             if hasattr(loader, "get_dirs"): | ||||
|                 yield from loader.get_dirs() | ||||
|  | ||||
|     def get_contents(self, origin): | ||||
|         return origin.loader.get_contents(origin) | ||||
|  | ||||
|     def get_template(self, template_name, skip=None): | ||||
|         """ | ||||
|         Perform the caching that gives this loader its name. Often many of the | ||||
|         templates attempted will be missing, so memory use is of concern here. | ||||
|         To keep it in check, caching behavior is a little complicated when a | ||||
|         template is not found. See ticket #26306 for more details. | ||||
|  | ||||
|         With template debugging disabled, cache the TemplateDoesNotExist class | ||||
|         for every missing template and raise a new instance of it after | ||||
|         fetching it from the cache. | ||||
|  | ||||
|         With template debugging enabled, a unique TemplateDoesNotExist object | ||||
|         is cached for each missing template to preserve debug data. When | ||||
|         raising an exception, Python sets __traceback__, __context__, and | ||||
|         __cause__ attributes on it. Those attributes can contain references to | ||||
|         all sorts of objects up the call chain and caching them creates a | ||||
|         memory leak. Thus, unraised copies of the exceptions are cached and | ||||
|         copies of those copies are raised after they're fetched from the cache. | ||||
|         """ | ||||
|         key = self.cache_key(template_name, skip) | ||||
|         cached = self.get_template_cache.get(key) | ||||
|         if cached: | ||||
|             if isinstance(cached, type) and issubclass(cached, TemplateDoesNotExist): | ||||
|                 raise cached(template_name) | ||||
|             elif isinstance(cached, TemplateDoesNotExist): | ||||
|                 raise copy_exception(cached) | ||||
|             return cached | ||||
|  | ||||
|         try: | ||||
|             template = super().get_template(template_name, skip) | ||||
|         except TemplateDoesNotExist as e: | ||||
|             self.get_template_cache[key] = ( | ||||
|                 copy_exception(e) if self.engine.debug else TemplateDoesNotExist | ||||
|             ) | ||||
|             raise | ||||
|         else: | ||||
|             self.get_template_cache[key] = template | ||||
|  | ||||
|         return template | ||||
|  | ||||
|     def get_template_sources(self, template_name): | ||||
|         for loader in self.loaders: | ||||
|             yield from loader.get_template_sources(template_name) | ||||
|  | ||||
|     def cache_key(self, template_name, skip=None): | ||||
|         """ | ||||
|         Generate a cache key for the template name and skip. | ||||
|  | ||||
|         If skip is provided, only origins that match template_name are included | ||||
|         in the cache key. This ensures each template is only parsed and cached | ||||
|         once if contained in different extend chains like: | ||||
|  | ||||
|             x -> a -> a | ||||
|             y -> a -> a | ||||
|             z -> a -> a | ||||
|         """ | ||||
|         skip_prefix = "" | ||||
|  | ||||
|         if skip: | ||||
|             matching = [ | ||||
|                 origin.name for origin in skip if origin.template_name == template_name | ||||
|             ] | ||||
|             if matching: | ||||
|                 skip_prefix = self.generate_hash(matching) | ||||
|  | ||||
|         return "-".join(s for s in (str(template_name), skip_prefix) if s) | ||||
|  | ||||
|     def generate_hash(self, values): | ||||
|         return hashlib.sha1("|".join(values).encode()).hexdigest() | ||||
|  | ||||
|     def reset(self): | ||||
|         "Empty the template cache." | ||||
|         self.get_template_cache.clear() | ||||
| @ -0,0 +1,45 @@ | ||||
| """ | ||||
| Wrapper for loading templates from the filesystem. | ||||
| """ | ||||
|  | ||||
| from django.core.exceptions import SuspiciousFileOperation | ||||
| from django.template import Origin, TemplateDoesNotExist | ||||
| from django.utils._os import safe_join | ||||
|  | ||||
| from .base import Loader as BaseLoader | ||||
|  | ||||
|  | ||||
| class Loader(BaseLoader): | ||||
|     def __init__(self, engine, dirs=None): | ||||
|         super().__init__(engine) | ||||
|         self.dirs = dirs | ||||
|  | ||||
|     def get_dirs(self): | ||||
|         return self.dirs if self.dirs is not None else self.engine.dirs | ||||
|  | ||||
|     def get_contents(self, origin): | ||||
|         try: | ||||
|             with open(origin.name, encoding=self.engine.file_charset) as fp: | ||||
|                 return fp.read() | ||||
|         except FileNotFoundError: | ||||
|             raise TemplateDoesNotExist(origin) | ||||
|  | ||||
|     def get_template_sources(self, template_name): | ||||
|         """ | ||||
|         Return an Origin object pointing to an absolute path in each directory | ||||
|         in template_dirs. For security reasons, if a path doesn't lie inside | ||||
|         one of the template_dirs it is excluded from the result set. | ||||
|         """ | ||||
|         for template_dir in self.get_dirs(): | ||||
|             try: | ||||
|                 name = safe_join(template_dir, template_name) | ||||
|             except SuspiciousFileOperation: | ||||
|                 # The joined path was located outside of this template_dir | ||||
|                 # (it might be inside another one, so this isn't fatal). | ||||
|                 continue | ||||
|  | ||||
|             yield Origin( | ||||
|                 name=name, | ||||
|                 template_name=template_name, | ||||
|                 loader=self, | ||||
|             ) | ||||
| @ -0,0 +1,26 @@ | ||||
| """ | ||||
| Wrapper for loading templates from a plain Python dict. | ||||
| """ | ||||
|  | ||||
| from django.template import Origin, TemplateDoesNotExist | ||||
|  | ||||
| from .base import Loader as BaseLoader | ||||
|  | ||||
|  | ||||
| class Loader(BaseLoader): | ||||
|     def __init__(self, engine, templates_dict): | ||||
|         self.templates_dict = templates_dict | ||||
|         super().__init__(engine) | ||||
|  | ||||
|     def get_contents(self, origin): | ||||
|         try: | ||||
|             return self.templates_dict[origin.name] | ||||
|         except KeyError: | ||||
|             raise TemplateDoesNotExist(origin) | ||||
|  | ||||
|     def get_template_sources(self, template_name): | ||||
|         yield Origin( | ||||
|             name=template_name, | ||||
|             template_name=template_name, | ||||
|             loader=self, | ||||
|         ) | ||||
		Reference in New Issue
	
	Block a user