| 24 | |
| 25 | @cached_property |
| 26 | def templates(self): |
| 27 | if self._templates is None: |
| 28 | self._templates = settings.TEMPLATES |
| 29 | |
| 30 | templates = {} |
| 31 | backend_names = [] |
| 32 | for tpl in self._templates: |
| 33 | try: |
| 34 | # This will raise an exception if 'BACKEND' doesn't exist or |
| 35 | # isn't a string containing at least one dot. |
| 36 | default_name = tpl["BACKEND"].rsplit(".", 2)[-2] |
| 37 | except Exception: |
| 38 | invalid_backend = tpl.get("BACKEND", "<not defined>") |
| 39 | raise ImproperlyConfigured( |
| 40 | "Invalid BACKEND for a template engine: {}. Check " |
| 41 | "your TEMPLATES setting.".format(invalid_backend) |
| 42 | ) |
| 43 | |
| 44 | tpl = { |
| 45 | "NAME": default_name, |
| 46 | "DIRS": [], |
| 47 | "APP_DIRS": False, |
| 48 | "OPTIONS": {}, |
| 49 | **tpl, |
| 50 | } |
| 51 | |
| 52 | templates[tpl["NAME"]] = tpl |
| 53 | backend_names.append(tpl["NAME"]) |
| 54 | |
| 55 | counts = Counter(backend_names) |
| 56 | duplicates = [alias for alias, count in counts.most_common() if count > 1] |
| 57 | if duplicates: |
| 58 | raise ImproperlyConfigured( |
| 59 | "Template engine aliases aren't unique, duplicates: {}. " |
| 60 | "Set a unique NAME for each engine in settings.TEMPLATES.".format( |
| 61 | ", ".join(duplicates) |
| 62 | ) |
| 63 | ) |
| 64 | |
| 65 | return templates |
| 66 | |
| 67 | def __getitem__(self, alias): |
| 68 | try: |