Components in Python
New in version 0.81
Components can be rendered outside of Django templates, calling them as regular functions ("React-style").
The component class defines render
and render_to_response
class methods. These methods accept positional args, kwargs, and slots, offering the same flexibility as the {% component %}
tag:
class SimpleComponent(Component):
template = """
{% load component_tags %}
hello: {{ hello }}
foo: {{ foo }}
kwargs: {{ kwargs|safe }}
slot_first: {% slot "first" required / %}
"""
def get_context_data(self, arg1, arg2, **kwargs):
return {
"hello": arg1,
"foo": arg2,
"kwargs": kwargs,
}
rendered = SimpleComponent.render(
args=["world", "bar"],
kwargs={"kw1": "test", "kw2": "ooo"},
slots={"first": "FIRST_SLOT"},
context={"from_context": 98},
)
Renders:
Inputs of render
and render_to_response
¤
Both render
and render_to_response
accept the same input:
Component.render(
context: Mapping | django.template.Context | None = None,
args: List[Any] | None = None,
kwargs: Dict[str, Any] | None = None,
slots: Dict[str, str | SafeString | SlotFunc] | None = None,
escape_slots_content: bool = True
) -> str:
-
args
- Positional args for the component. This is the same as calling the component as{% component "my_comp" arg1 arg2 ... %}
-
kwargs
- Keyword args for the component. This is the same as calling the component as{% component "my_comp" key1=val1 key2=val2 ... %}
-
slots
- Component slot fills. This is the same as pasing{% fill %}
tags to the component. Accepts a dictionary of{ slot_name: slot_content }
whereslot_content
can be a string orSlotFunc
. -
escape_slots_content
- Whether the content fromslots
should be escaped.True
by default to prevent XSS attacks. If you disable escaping, you should make sure that any content you pass to the slots is safe, especially if it comes from user input. -
context
- A context (dictionary or Django's Context) within which the component is rendered. The keys on the context can be accessed from within the template. -
NOTE: In "isolated" mode, context is NOT accessible, and data MUST be passed via component's args and kwargs.
-
request
- A Django request object. This is used to enable Django templatecontext_processors
to run,
allowing for template tags like{% csrf_token %}
and variables like{{ debug }}
. - Similar behavior can be achieved with provide / inject.
- This is used internally to convert
context
to a RequestContext. It does nothing ifcontext
is already aContext
instance.
SlotFunc
¤
When rendering components with slots in render
or render_to_response
, you can pass either a string or a function.
The function has following signature:
def render_func(
context: Context,
data: Dict[str, Any],
slot_ref: SlotRef,
) -> str | SafeString:
return nodelist.render(ctx)
context
- Django's Context available to the Slot Node.data
- Data passed to the{% slot %}
tag. See Scoped Slots.slot_ref
- The default slot content. See Accessing original content of slots.- NOTE: The slot is lazily evaluated. To render the slot, convert it to string with
str(slot_ref)
.
Example:
def footer_slot(ctx, data, slot_ref):
return f"""
SLOT_DATA: {data['abc']}
ORIGINAL: {slot_ref}
"""
MyComponent.render_to_response(
slots={
"footer": footer_slot,
},
)
Response class of render_to_response
¤
While render
method returns a plain string, render_to_response
wraps the rendered content in a "Response" class. By default, this is django.http.HttpResponse
.
If you want to use a different Response class in render_to_response
, set the Component.response_class
attribute:
class MyResponse(HttpResponse):
def __init__(self, *args, **kwargs) -> None:
super().__init__(*args, **kwargs)
# Configure response
self.headers = ...
self.status = ...
class SimpleComponent(Component):
response_class = MyResponse
template: types.django_html = "HELLO"
response = SimpleComponent.render_to_response()
assert isinstance(response, MyResponse)