Skip to content

Commit d6895e9

Browse files
add get_context_data and render methods to Nav (#39)
1 parent cf7312f commit d6895e9

File tree

4 files changed

+61
-16
lines changed

4 files changed

+61
-16
lines changed

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@ and this project attempts to adhere to [Semantic Versioning](https://semver.org/
1818

1919
## [Unreleased]
2020

21+
### Added
22+
23+
- The `Nav` class now has two new methods: `get_context_data` and `render`. These methods are used to render the navigation to a template. These new methods give greater flexibility for customizing the rendering of the navigation, as they can be overridden when defining a new `Nav`.
24+
- `Nav.get_context_data` method takes a Django `HttpRequest` object and returns a dictionary of context data that can be used to render the navigation to a template.
25+
- `Nav.render` method takes a Django `HttpRequest` object and an optional template name and renders the navigation to a template, returning the rendered template as a string.
26+
27+
### Removed
28+
29+
- `Nav.render_from_request` method has been removed. This was only used within the template tag to render a `Nav` template from an `HttpRequest` object. It has been removed in favor of the new `Nav.get_context_data` and `Nav.render` methods.
30+
2131
## [0.3.0]
2232

2333
### Added

src/django_simple_nav/nav.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,18 +18,19 @@ class Nav:
1818
template_name: str = field(init=False)
1919
items: list[NavGroup | NavItem] = field(init=False)
2020

21-
@classmethod
22-
def render_from_request(
23-
cls, request: HttpRequest, template_name: str | None = None
24-
) -> str:
21+
def get_context_data(self, request: HttpRequest) -> dict[str, Any]:
2522
items = [
2623
RenderedNavItem(item, request)
27-
for item in cls.items
24+
for item in self.items
2825
if check_item_permissions(item, request.user) # type: ignore[arg-type]
2926
]
27+
return {"items": items}
28+
29+
def render(self, request: HttpRequest, template_name: str | None = None) -> str:
30+
context = self.get_context_data(request)
3031
return render_to_string(
31-
template_name=template_name or cls.template_name,
32-
context={"items": items},
32+
template_name=template_name or self.template_name,
33+
context=context,
3334
)
3435

3536

src/django_simple_nav/templatetags/django_simple_nav.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ def render(self, context):
3939
) from err
4040

4141
if isinstance(self.nav, str):
42-
nav = import_string(self.nav)
42+
nav = import_string(self.nav)()
4343
else:
4444
nav = self.nav
4545

46-
assert hasattr(nav, "render_from_request")
46+
assert hasattr(nav, "render")
4747

48-
return nav.render_from_request(context["request"], self.template_name)
48+
return nav.render(context["request"], self.template_name)

tests/test_nav.py

Lines changed: 40 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,18 @@ def test_nav_render(user, expected_count, req):
5050
user = baker.make(get_user_model())
5151

5252
req.user = user
53-
rendered_template = DummyNav.render_from_request(req)
53+
54+
rendered_template = DummyNav().render(req)
5455

5556
assert count_anchors(rendered_template) == expected_count
5657

5758

58-
def test_dotted_path_rendering(req):
59+
def test_dotted_path_nav_render(req):
5960
req.user = baker.make(get_user_model())
61+
6062
nav = import_string("tests.navs.DummyNav")
6163

62-
assert nav.render_from_request(req)
64+
assert nav().render(req)
6365

6466

6567
@pytest.mark.parametrize(
@@ -88,15 +90,15 @@ def test_nav_render_with_permissions(req, permission, expected_count):
8890
user.save()
8991

9092
req.user = user
91-
rendered_template = DummyNav.render_from_request(req)
93+
rendered_template = DummyNav().render(req)
9294

9395
assert count_anchors(rendered_template) == expected_count
9496

9597

96-
def test_nav_render_from_request_with_template_name(req):
98+
def test_nav_render_with_template_name(req):
9799
req.user = AnonymousUser()
98100

99-
rendered_template = DummyNav.render_from_request(req, "tests/alternate.html")
101+
rendered_template = DummyNav().render(req, "tests/alternate.html")
100102

101103
assert "This is an alternate template." in rendered_template
102104

@@ -185,3 +187,35 @@ def test_extra_context_builtins(req):
185187
assert rendered_group_item.permissions == ["is_staff"]
186188
assert rendered_group_item.extra_context == {"foo": "bar"}
187189
assert rendered_group_item.foo == "bar"
190+
191+
192+
def test_get_context_data(req):
193+
req.user = baker.make(get_user_model())
194+
195+
context = DummyNav().get_context_data(req)
196+
197+
assert context["items"]
198+
199+
200+
def test_get_context_data_override(req):
201+
class OverrideNav(DummyNav):
202+
def get_context_data(self, request):
203+
return {"foo": "bar"}
204+
205+
req.user = baker.make(get_user_model())
206+
207+
context = OverrideNav().get_context_data(req)
208+
209+
assert context["foo"] == "bar"
210+
211+
212+
def test_get_context_data_override_render(req):
213+
class OverrideNav(DummyNav):
214+
def get_context_data(self, request):
215+
return {"foo": "bar"}
216+
217+
req.user = baker.make(get_user_model())
218+
219+
rendered_template = OverrideNav().render(req)
220+
221+
assert count_anchors(rendered_template) == 0

0 commit comments

Comments
 (0)