import io from os.path import join, abspath from typing import Generator from django.apps import apps from django.template import TemplateDoesNotExist, Origin from django.template.loaders.base import Loader as BaseLoader class SpecificAppTemplateLoader(BaseLoader): def get_template_sources(self, app_template_name: str) -> Generator[Origin, None, None]: template_parts = app_template_name.split(':', 1) if len(template_parts) != 2: raise TemplateDoesNotExist(app_template_name) app_name, template_name = template_parts app_dir = apps.get_app_config(app_name).path template_dir = abspath(join(app_dir, 'templates')) template_path = join(template_dir, template_name) yield Origin( name=template_path, template_name=template_name, loader=self, ) def get_contents(self, origin: Origin) -> str: try: with io.open(origin.name, encoding=self.engine.file_charset) as fp: return fp.read() except IOError: pass raise TemplateDoesNotExist(f'Could not read template content: {origin}')