|
4 | 4 | from dataclasses import field |
5 | 5 | from typing import Any |
6 | 6 |
|
| 7 | +from django.core.exceptions import ImproperlyConfigured |
7 | 8 | from django.http import HttpRequest |
8 | 9 | from django.template.loader import render_to_string |
9 | 10 | from django.urls import reverse |
|
15 | 16 |
|
16 | 17 | @dataclass(frozen=True) |
17 | 18 | class Nav: |
18 | | - template_name: str = field(init=False) |
19 | | - items: list[NavGroup | NavItem] = field(init=False) |
| 19 | + template_name: str | None = field(init=False, default=None) |
| 20 | + items: list[NavGroup | NavItem] | None = field(init=False, default=None) |
| 21 | + |
| 22 | + def get_template_name(self) -> str: |
| 23 | + if self.template_name is not None: |
| 24 | + return self.template_name |
| 25 | + |
| 26 | + msg = f"{self.__class__!r} must define 'template_name' or override 'get_template_name()'" |
| 27 | + raise ImproperlyConfigured(msg % self.__class__.__name__) |
| 28 | + |
| 29 | + def get_items(self, request: HttpRequest) -> list[RenderedNavItem]: |
| 30 | + if self.items is not None: |
| 31 | + return [ |
| 32 | + RenderedNavItem(item, request) |
| 33 | + for item in self.items |
| 34 | + if check_item_permissions(item, request) |
| 35 | + ] |
| 36 | + |
| 37 | + msg = f"{self.__class__!r} must define 'items' or override 'get_items()'" |
| 38 | + raise ImproperlyConfigured(msg) |
20 | 39 |
|
21 | 40 | def get_context_data(self, request: HttpRequest) -> dict[str, Any]: |
22 | | - items = [ |
23 | | - RenderedNavItem(item, request) |
24 | | - for item in self.items |
25 | | - if check_item_permissions(item, request) |
26 | | - ] |
27 | | - return {"items": items} |
| 41 | + return { |
| 42 | + "items": self.get_items(request), |
| 43 | + "request": request, |
| 44 | + } |
28 | 45 |
|
29 | 46 | def render(self, request: HttpRequest, template_name: str | None = None) -> str: |
30 | 47 | context = self.get_context_data(request) |
31 | | - context["request"] = request |
32 | 48 | return render_to_string( |
33 | | - template_name=template_name or self.template_name, |
| 49 | + template_name=template_name or self.get_template_name(), |
34 | 50 | context=context, |
35 | 51 | request=request, |
36 | 52 | ) |
|
0 commit comments