Pre-fetch referenced templates

This commit is contained in:
jeremystretch 2023-02-10 16:01:41 -05:00
parent 8681e6d823
commit adaeedd6a2
2 changed files with 28 additions and 14 deletions

View File

@ -230,16 +230,20 @@ class ConfigTemplate(SyncedDataMixin, ExportTemplatesMixin, ChangeLoggedModel):
Render the contents of the template.
"""
context = context or {}
template_code = self.template_code
# output = render_jinja2(template_code, context)
template_path = self.data_file.path
environment = SandboxedEnvironment(
loader=ConfigTemplateLoader(data_source=self.data_source)
)
# Initialize the template loader & cache the base template code
loader = ConfigTemplateLoader(data_source=self.data_source)
loader.cache_templates({
template_path: self.template_code
})
# Initialize the Jinja2 environment
environment = SandboxedEnvironment(loader=loader)
environment.filters.update(get_config().JINJA2_FILTERS)
output = environment.from_string(source=template_code).render(**context)
# Render the template
output = environment.get_template(template_path).render(**context)
# Replace CRLF-style line terminators
output = output.replace('\r\n', '\n')
return output
return output.replace('\r\n', '\n')

View File

@ -1,7 +1,6 @@
import os
from django.apps import apps
from jinja2 import BaseLoader, TemplateNotFound
from jinja2.meta import find_referenced_templates
__all__ = (
'ConfigTemplateLoader',
@ -14,14 +13,25 @@ class ConfigTemplateLoader(BaseLoader):
"""
def __init__(self, data_source):
self.data_source = data_source
self._template_cache = {}
def get_source(self, environment, template):
DataFile = apps.get_model('core', 'DataFile')
# Retrieve template content from cache
try:
datafile = DataFile.objects.get(source=self.data_source, path=template)
template_source = datafile.data_as_string
except DataFile.DoesNotExist:
template_source = self._template_cache[template]
except KeyError:
raise TemplateNotFound(template)
# Find and pre-fetch referenced templates
if referenced_templates := find_referenced_templates(environment.parse(template_source)):
self.cache_templates({
df.path: df.data_as_string for df in
DataFile.objects.filter(source=self.data_source, path__in=referenced_templates)
})
return template_source, template, True
def cache_templates(self, templates):
self._template_cache.update(templates)