Skip to content

Commit ae6890d

Browse files
authored
Add render_block function (#60)
Add a render_block function, which returns a HttpResponse object with the content set to the results of calling render_block_to_string.
1 parent 399e6e1 commit ae6890d

5 files changed

Lines changed: 99 additions & 7 deletions

File tree

CHANGELOG.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@ Changelog
66
next
77
====
88

9+
Improvements
10+
------------
11+
12+
* Add a new ``render_block`` function which returns a `HttpResponse` with the content
13+
set to the result of calling ``render_block_to_string()``. Contributed by
14+
`@gogognome <https://github.com/gogognome>`_. (`#60 <https://github.com/clokep/django-render-block/pull/60>`_)
15+
916
Maintenance
1017
-----------
1118

README.rst

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ And from Python:
7171
API Reference
7272
=============
7373

74-
The API is simple and attempts to mirror the built-in ``render_to_string`` API.
74+
The API is simple and attempts to mirror the built-in ``render_to_string`` and ``render`` API.
7575

7676
``render_block_to_string(template_name, block_name, context=None, request=None)``
7777

@@ -95,6 +95,34 @@ The API is simple and attempts to mirror the built-in ``render_to_string`` API.
9595
``request`` is optional and works only for Django templates. If both context and request
9696
are provided, a ``RequestContext`` will be used instead of a ``Context``.
9797

98+
Similarly there is a ``render_block`` function which returns an `HttpResponse` with
99+
the content sent to the result of ``render_block_to_string`` with the same parameters.
100+
101+
``render_block(request, template_name, block_name, context=None, content_type="text/html", status=200)``
102+
103+
``request``
104+
The request object used to render the template.
105+
106+
``template_name``
107+
The name of the template to load and render. If it’s a list of template
108+
names, Django uses ``select_template()`` instead of ``get_template()``
109+
to find the template.
110+
111+
``block_name``
112+
The name of the block to render from the above template.
113+
114+
``context``
115+
A ``dict`` to be used as the template’s context for rendering. A ``Context``
116+
object can be provided for Django templates.
117+
118+
``context`` is optional. If not provided, an empty context will be used.
119+
120+
``content_type``
121+
A ``str`` content type for the HTTP response.
122+
123+
``status``
124+
An ``int`` HTTP status code for the HTTP response.
125+
98126
Exceptions
99127
----------
100128

render_block/__init__.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
from render_block.base import render_block_to_string
1+
from render_block.base import render_block, render_block_to_string
22
from render_block.exceptions import BlockNotFound, UnsupportedEngine
33

4-
__all__ = ["BlockNotFound", "UnsupportedEngine", "render_block_to_string"]
4+
__all__ = [
5+
"BlockNotFound",
6+
"UnsupportedEngine",
7+
"render_block",
8+
"render_block_to_string",
9+
]

render_block/base.py

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from typing import List, Optional, Tuple, Union
22

3-
from django.http import HttpRequest
3+
from django.http import HttpRequest, HttpResponse
44
from django.template import Context, loader
55
from django.template.backends.django import Template as DjangoTemplate
66

@@ -27,10 +27,13 @@ def render_block_to_string(
2727
Loads the given template_name and renders the given block with the given
2828
dictionary as context. Returns a string.
2929
30-
template_name
30+
:param template_name:
3131
The name of the template to load and render. If it's a list of
3232
template names, Django uses select_template() instead of
3333
get_template() to find the template.
34+
:param block_name: The name of the block to load.
35+
:param context: The context dictionary used while rendering the template.
36+
:param request: The request that triggers the rendering of the block.
3437
"""
3538

3639
# Like render_to_string, template_name can be a string or a list/tuple.
@@ -55,3 +58,19 @@ def render_block_to_string(
5558
raise UnsupportedEngine(
5659
"Can only render blocks from the Django template backend."
5760
)
61+
62+
63+
def render_block(
64+
request: HttpRequest,
65+
template_name: str,
66+
block_name: str,
67+
context: Optional[Context] = None,
68+
content_type: Optional[str] = None,
69+
status: Optional[int] = None,
70+
) -> HttpResponse:
71+
"""
72+
Return an HttpResponse whose content is filled with the result of calling
73+
render_block.render_block_to_string() with the passed arguments.
74+
"""
75+
content = render_block_to_string(template_name, block_name, context, request)
76+
return HttpResponse(content, content_type, status)

tests/tests.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
33
from django.template import Context
44
from django.test import RequestFactory, TestCase, modify_settings, override_settings
55

6-
from render_block import BlockNotFound, UnsupportedEngine, render_block_to_string
6+
from render_block import (
7+
BlockNotFound,
8+
UnsupportedEngine,
9+
render_block,
10+
render_block_to_string,
11+
)
712

813

914
class TestDjango(TestCase):
@@ -174,6 +179,20 @@ def test_request_context(self) -> None:
174179

175180
self.assertEqual(result, "/dummy-url")
176181

182+
@modify_settings(
183+
INSTALLED_APPS={
184+
"prepend": [
185+
"django.contrib.auth",
186+
"django.contrib.contenttypes",
187+
],
188+
},
189+
)
190+
def test_render_block(self) -> None:
191+
"""Test rendering an individual block to a response."""
192+
request = RequestFactory().get("dummy-url")
193+
response = render_block(request, "test1.html", "block1")
194+
self.assertEqual(response.content, b"block1 from test1")
195+
177196

178197
@override_settings(
179198
TEMPLATES=[
@@ -185,7 +204,7 @@ def test_request_context(self) -> None:
185204
]
186205
)
187206
class TestJinja2(TestCase):
188-
"""Test the Django templating engine."""
207+
"""Test the Jinja2 templating engine."""
189208

190209
def assertExceptionMessageEquals(self, exception: Exception, expected: str) -> None:
191210
self.assertEqual(expected, exception.args[0])
@@ -271,3 +290,17 @@ def test_context(self) -> None:
271290
data = "block2 from test5"
272291
result = render_block_to_string("test5.html", "block2", {"foo": data})
273292
self.assertEqual(result, data)
293+
294+
@modify_settings(
295+
INSTALLED_APPS={
296+
"prepend": [
297+
"django.contrib.auth",
298+
"django.contrib.contenttypes",
299+
],
300+
},
301+
)
302+
def test_render_block(self) -> None:
303+
"""Test rendering an individual block to a response."""
304+
request = RequestFactory().get("dummy-url")
305+
response = render_block(request, "test1.html", "block1")
306+
self.assertEqual(response.content, b"block1 from test1")

0 commit comments

Comments
 (0)