A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://django-components.github.io/django-components/latest/reference/api/ below:

API - Django-Components

Args class-attribute ¤

See source code

Optional typing for positional arguments passed to the component.

If set and not None, then the args parameter of the data methods (get_template_data(), get_js_data(), get_css_data()) will be the instance of this class:

from typing import NamedTuple
from django_components import Component

class Table(Component):
    class Args(NamedTuple):
        color: str
        size: int

    def get_template_data(self, args: Args, kwargs, slots, context):
        assert isinstance(args, Table.Args)

        return {
            "color": args.color,
            "size": args.size,
        }

The constructor of this class MUST accept positional arguments:

As such, a good starting point is to set this field to a subclass of NamedTuple.

Use Args to:

You can also use Args to validate the positional arguments for Component.render():

Table.render(
    args=Table.Args(color="red", size=10),
)

Read more on Typing and validation.

Cache class-attribute ¤

See source code

The fields of this class are used to configure the component caching.

Read more about Component caching.

Example:

from django_components import Component

class MyComponent(Component):
    class Cache:
        enabled = True
        ttl = 60 * 60 * 24  # 1 day
        cache_name = "my_cache"
CssData class-attribute ¤

See source code

Optional typing for the data to be returned from get_css_data().

If set and not None, then this class will be instantiated with the dictionary returned from get_css_data() to validate the data.

The constructor of this class MUST accept keyword arguments:

You can also return an instance of CssData directly from get_css_data() to get type hints:

from typing import NamedTuple
from django_components import Component

class Table(Component):
    class CssData(NamedTuple):
        color: str
        size: int

    def get_css_data(self, args, kwargs, slots, context):
        return Table.CssData(
            color=kwargs["color"],
            size=kwargs["size"],
        )

A good starting point is to set this field to a subclass of NamedTuple or a dataclass.

Use CssData to:

Read more on Typing and validation.

Info

If you use a custom class for CssData, this class needs to be convertable to a dictionary.

You can implement either:

  1. _asdict() method

    class MyClass:
        def __init__(self):
            self.x = 1
            self.y = 2
    
        def _asdict(self):
            return {'x': self.x, 'y': self.y}
    
  2. Or make the class dict-like with __iter__() and __getitem__()

    class MyClass:
        def __init__(self):
            self.x = 1
            self.y = 2
    
        def __iter__(self):
            return iter([('x', self.x), ('y', self.y)])
    
        def __getitem__(self, key):
            return getattr(self, key)
    
Defaults class-attribute ¤

See source code

The fields of this class are used to set default values for the component's kwargs.

Read more about Component defaults.

Example:

from django_components import Component, Default

class MyComponent(Component):
    class Defaults:
        position = "left"
        selected_items = Default(lambda: [1, 2, 3])
JsData class-attribute ¤

See source code

Optional typing for the data to be returned from get_js_data().

If set and not None, then this class will be instantiated with the dictionary returned from get_js_data() to validate the data.

The constructor of this class MUST accept keyword arguments:

You can also return an instance of JsData directly from get_js_data() to get type hints:

from typing import NamedTuple
from django_components import Component

class Table(Component):
    class JsData(NamedTuple):
        color: str
        size: int

    def get_js_data(self, args, kwargs, slots, context):
        return Table.JsData(
            color=kwargs["color"],
            size=kwargs["size"],
        )

A good starting point is to set this field to a subclass of NamedTuple or a dataclass.

Use JsData to:

Read more on Typing and validation.

Info

If you use a custom class for JsData, this class needs to be convertable to a dictionary.

You can implement either:

  1. _asdict() method

    class MyClass:
        def __init__(self):
            self.x = 1
            self.y = 2
    
        def _asdict(self):
            return {'x': self.x, 'y': self.y}
    
  2. Or make the class dict-like with __iter__() and __getitem__()

    class MyClass:
        def __init__(self):
            self.x = 1
            self.y = 2
    
        def __iter__(self):
            return iter([('x', self.x), ('y', self.y)])
    
        def __getitem__(self, key):
            return getattr(self, key)
    
Kwargs class-attribute ¤

See source code

Optional typing for keyword arguments passed to the component.

If set and not None, then the kwargs parameter of the data methods (get_template_data(), get_js_data(), get_css_data()) will be the instance of this class:

from typing import NamedTuple
from django_components import Component

class Table(Component):
    class Kwargs(NamedTuple):
        color: str
        size: int

    def get_template_data(self, args, kwargs: Kwargs, slots, context):
        assert isinstance(kwargs, Table.Kwargs)

        return {
            "color": kwargs.color,
            "size": kwargs.size,
        }

The constructor of this class MUST accept keyword arguments:

As such, a good starting point is to set this field to a subclass of NamedTuple or a dataclass.

Use Kwargs to:

You can also use Kwargs to validate the keyword arguments for Component.render():

Table.render(
    kwargs=Table.Kwargs(color="red", size=10),
)

Read more on Typing and validation.

Media class-attribute ¤

See source code

Defines JS and CSS media files associated with this component.

This Media class behaves similarly to Django's Media class:

However, there's a few differences from Django's Media class:

  1. Our Media class accepts various formats for the JS and CSS files: either a single file, a list, or (CSS-only) a dictionary (See ComponentMediaInput).
  2. Individual JS / CSS files can be any of str, bytes, Path, SafeString, or a function (See ComponentMediaInputPath).

Example:

class MyTable(Component):
    class Media:
        js = [
            "path/to/script.js",
            "https://unpkg.com/alpinejs@3.14.7/dist/cdn.min.js",  # AlpineJS
        ]
        css = {
            "all": [
                "path/to/style.css",
                "https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css",  # TailwindCSS
            ],
            "print": ["path/to/style2.css"],
        }
Slots class-attribute ¤

See source code

Optional typing for slots passed to the component.

If set and not None, then the slots parameter of the data methods (get_template_data(), get_js_data(), get_css_data()) will be the instance of this class:

from typing import NamedTuple
from django_components import Component, Slot, SlotInput

class Table(Component):
    class Slots(NamedTuple):
        header: SlotInput
        footer: Slot

    def get_template_data(self, args, kwargs, slots: Slots, context):
        assert isinstance(slots, Table.Slots)

        return {
            "header": slots.header,
            "footer": slots.footer,
        }

The constructor of this class MUST accept keyword arguments:

As such, a good starting point is to set this field to a subclass of NamedTuple or a dataclass.

Use Slots to:

You can also use Slots to validate the slots for Component.render():

Table.render(
    slots=Table.Slots(
        header="HELLO IM HEADER",
        footer=Slot(lambda ctx: ...),
    ),
)

Read more on Typing and validation.

Info

Components can receive slots as strings, functions, or instances of Slot.

Internally these are all normalized to instances of Slot.

Therefore, the slots dictionary available in data methods (like get_template_data()) will always be a dictionary of Slot instances.

To correctly type this dictionary, you should set the fields of Slots to Slot or SlotInput:

SlotInput is a union of Slot, string, and function types.

TemplateData class-attribute ¤

See source code

Optional typing for the data to be returned from get_template_data().

If set and not None, then this class will be instantiated with the dictionary returned from get_template_data() to validate the data.

The constructor of this class MUST accept keyword arguments:

TemplateData(**template_data)

You can also return an instance of TemplateData directly from get_template_data() to get type hints:

from typing import NamedTuple
from django_components import Component

class Table(Component):
    class TemplateData(NamedTuple):
        color: str
        size: int

    def get_template_data(self, args, kwargs, slots, context):
        return Table.TemplateData(
            color=kwargs["color"],
            size=kwargs["size"],
        )

A good starting point is to set this field to a subclass of NamedTuple or a dataclass.

Use TemplateData to:

Read more on Typing and validation.

Info

If you use a custom class for TemplateData, this class needs to be convertable to a dictionary.

You can implement either:

  1. _asdict() method

    class MyClass:
        def __init__(self):
            self.x = 1
            self.y = 2
    
        def _asdict(self):
            return {'x': self.x, 'y': self.y}
    
  2. Or make the class dict-like with __iter__() and __getitem__()

    class MyClass:
        def __init__(self):
            self.x = 1
            self.y = 2
    
        def __iter__(self):
            return iter([('x', self.x), ('y', self.y)])
    
        def __getitem__(self, key):
            return getattr(self, key)
    
View class-attribute ¤

See source code

The fields of this class are used to configure the component views and URLs.

This class is a subclass of django.views.View. The Component instance is available via self.component.

Override the methods of this class to define the behavior of the component.

Read more about Component views and URLs.

Example:

class MyComponent(Component):
    class View:
        def get(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse:
            return HttpResponse("Hello, world!")
args instance-attribute ¤

See source code

Positional arguments passed to the component.

This is part of the Render API.

args has the same behavior as the args argument of Component.get_template_data():

Example:

With Args class:

from django_components import Component

class Table(Component):
    class Args(NamedTuple):
        page: int
        per_page: int

    def on_render_before(self, context: Context, template: Optional[Template]) -> None:
        assert self.args.page == 123
        assert self.args.per_page == 10

rendered = Table.render(
    args=[123, 10],
)

Without Args class:

from django_components import Component

class Table(Component):
    def on_render_before(self, context: Context, template: Optional[Template]) -> None:
        assert self.args[0] == 123
        assert self.args[1] == 10
class_id class-attribute ¤

See source code

Unique ID of the component class, e.g. MyComponent_ab01f2.

This is derived from the component class' module import path, e.g. path.to.my.MyComponent.

context instance-attribute ¤

See source code

The context argument as passed to Component.get_template_data().

This is Django's Context with which the component template is rendered.

If the root component or template was rendered with RequestContext then this will be an instance of RequestContext.

Whether the context variables defined in context are available to the template depends on the context behavior mode:

context_processors_data property ¤
context_processors_data: Dict

See source code

Retrieve data injected by context_processors.

This data is also available from within the component's template, without having to return this data from get_template_data().

In regular Django templates, you need to use RequestContext to apply context processors.

In Components, the context processors are applied to components either when:

See Component.request on how the request (HTTPRequest) object is passed to and within the components.

NOTE: This dictionary is generated dynamically, so any changes to it will not be persisted.

Example:

class MyComponent(Component):
    def get_template_data(self, args, kwargs, slots, context):
        user = self.context_processors_data['user']
        return {
            'is_logged_in': user.is_authenticated,
        }
css class-attribute instance-attribute ¤

See source code

Main CSS associated with this component inlined as string.

Example:

class MyComponent(Component):
    css = """
        .my-class {
            color: red;
        }
    """

Syntax highlighting

When using the inlined template, you can enable syntax highlighting with django_components.types.css.

Learn more about syntax highlighting.

from django_components import Component, types

class MyComponent(Component):
    css: types.css = '''
      .my-class {
        color: red;
      }
    '''
css_file class-attribute ¤

See source code

Main CSS associated with this component as file path.

The filepath must be either:

When you create a Component class with css_file, these will happen:

  1. If the file path is relative to the directory where the component's Python file is, the path is resolved.
  2. The file is read and its contents is set to Component.css.

Example:

path/to/style.css
.my-class {
    color: red;
}
path/to/component.py
class MyComponent(Component):
    css_file = "path/to/style.css"

print(MyComponent.css)
# Output:
# .my-class {
#     color: red;
# };
debug_highlight instance-attribute ¤ deps_strategy instance-attribute ¤

See source code

Dependencies strategy defines how to handle JS and CSS dependencies of this and child components.

Read more about Dependencies rendering.

This is part of the Render API.

There are six strategies:

do_not_call_in_templates class-attribute ¤
do_not_call_in_templates: bool = True

See source code

Django special property to prevent calling the instance as a function inside Django templates.

Read more about Django's do_not_call_in_templates.

id instance-attribute ¤

See source code

This ID is unique for every time a Component.render() (or equivalent) is called (AKA "render ID").

This is useful for logging or debugging.

The ID is a 7-letter alphanumeric string in the format cXXXXXX, where XXXXXX is a random string of 6 alphanumeric characters (case-sensitive).

E.g. c1A2b3c.

A single render ID has a chance of collision 1 in 57 billion. However, due to birthday paradox, the chance of collision increases to 1% when approaching ~33K render IDs.

Thus, there is currently a soft-cap of ~30K components rendered on a single page.

If you need to expand this limit, please open an issue on GitHub.

Example:

class MyComponent(Component):
    def get_template_data(self, args, kwargs, slots, context):
        print(f"Rendering '{self.id}'")

MyComponent.render()
# Rendering 'ab3c4d'
input instance-attribute ¤

See source code

Deprecated. Will be removed in v1.

Input holds the data that were passed to the current component at render time.

This includes:

Example:

class Table(Component):
    def get_template_data(self, args, kwargs, slots, context):
        # Access component's inputs, slots and context
        assert self.args == [123, "str"]
        assert self.kwargs == {"variable": "test", "another": 1}
        footer_slot = self.slots["footer"]
        some_var = self.input.context["some_var"]

rendered = TestComponent.render(
    kwargs={"variable": "test", "another": 1},
    args=[123, "str"],
    slots={"footer": "MY_SLOT"},
)
is_filled instance-attribute ¤

See source code

Deprecated. Will be removed in v1. Use Component.slots instead. Note that Component.slots no longer escapes the slot names.

Dictionary describing which slots have or have not been filled.

This attribute is available for use only within:

You can also access this variable from within the template as

{{ component_vars.is_filled.slot_name }}

js class-attribute instance-attribute ¤

See source code

Main JS associated with this component inlined as string.

Warning

Only one of js or js_file must be defined.

Example:

class MyComponent(Component):
    js = "console.log('Hello, World!');"

Syntax highlighting

When using the inlined template, you can enable syntax highlighting with django_components.types.js.

Learn more about syntax highlighting.

from django_components import Component, types

class MyComponent(Component):
    js: types.js = '''
      console.log('Hello, World!');
    '''
js_file class-attribute ¤

See source code

Main JS associated with this component as file path.

The filepath must be either:

When you create a Component class with js_file, these will happen:

  1. If the file path is relative to the directory where the component's Python file is, the path is resolved.
  2. The file is read and its contents is set to Component.js.

Warning

Only one of js or js_file must be defined.

Example:

path/to/script.js
console.log('Hello, World!');
path/to/component.py
class MyComponent(Component):
    js_file = "path/to/script.js"

print(MyComponent.js)
# Output: console.log('Hello, World!');
kwargs instance-attribute ¤

See source code

Keyword arguments passed to the component.

This is part of the Render API.

kwargs has the same behavior as the kwargs argument of Component.get_template_data():

Example:

With Kwargs class:

from django_components import Component

class Table(Component):
    class Kwargs(NamedTuple):
        page: int
        per_page: int

    def on_render_before(self, context: Context, template: Optional[Template]) -> None:
        assert self.kwargs.page == 123
        assert self.kwargs.per_page == 10

rendered = Table.render(
    kwargs={
        "page": 123,
        "per_page": 10,
    },
)

Without Kwargs class:

from django_components import Component

class Table(Component):
    def on_render_before(self, context: Context, template: Optional[Template]) -> None:
        assert self.kwargs["page"] == 123
        assert self.kwargs["per_page"] == 10
media class-attribute instance-attribute ¤

See source code

Normalized definition of JS and CSS media files associated with this component. None if Component.Media is not defined.

This field is generated from Component.media_class.

Read more on Accessing component's Media JS / CSS.

Example:

class MyComponent(Component):
    class Media:
        js = "path/to/script.js"
        css = "path/to/style.css"

print(MyComponent.media)
# Output:
# <script src="/static/path/to/script.js"></script>
# <link href="/static/path/to/style.css" media="all" rel="stylesheet">
media_class class-attribute ¤
media_class: Type[Media] = Media

See source code

Set the Media class that will be instantiated with the JS and CSS media files from Component.Media.

This is useful when you want to customize the behavior of the media files, like customizing how the JS or CSS files are rendered into <script> or <link> HTML tags.

Read more in Media class.

Example:

class MyTable(Component):
    class Media:
        js = "path/to/script.js"
        css = "path/to/style.css"

    media_class = MyMediaClass
name instance-attribute ¤

See source code

The name of the component.

If the component was registered, this will be the name under which the component was registered in the ComponentRegistry.

Otherwise, this will be the name of the class.

Example:

@register("my_component")
class RegisteredComponent(Component):
    def get_template_data(self, args, kwargs, slots, context):
        return {
            "name": self.name,  # "my_component"
        }

class UnregisteredComponent(Component):
    def get_template_data(self, args, kwargs, slots, context):
        return {
            "name": self.name,  # "UnregisteredComponent"
        }
node instance-attribute ¤

See source code

The ComponentNode instance that was used to render the component.

This will be set only if the component was rendered with the {% component %} tag.

Accessing the ComponentNode is mostly useful for extensions, which can modify their behaviour based on the source of the Component.

class MyComponent(Component):
    def get_template_data(self, context, template):
        if self.node is not None:
            assert self.node.name == "my_component"

For example, if MyComponent was used in another component - that is, with a {% component "my_component" %} tag in a template that belongs to another component - then you can use self.node.template_component to access the owner Component class.

class Parent(Component):
    template: types.django_html = '''
        <div>
            {% component "my_component" / %}
        </div>
    '''

@register("my_component")
class MyComponent(Component):
    def get_template_data(self, context, template):
        if self.node is not None:
            assert self.node.template_component == Parent

Info

Component.node is None if the component is created by Component.render() (but you can pass in the node kwarg yourself).

outer_context instance-attribute ¤

See source code

When a component is rendered with the {% component %} tag, this is the Django's Context object that was used just outside of the component.

{% with abc=123 %}
    {{ abc }} {# <--- This is in outer context #}
    {% component "my_component" / %}
{% endwith %}

This is relevant when your components are isolated, for example when using the "isolated" context behavior mode or when using the only flag.

When components are isolated, each component has its own instance of Context, so outer_context is different from the context argument.

raw_args instance-attribute ¤

See source code

Positional arguments passed to the component.

This is part of the Render API.

Unlike Component.args, this attribute is not typed and will remain as plain list even if you define the Component.Args class.

Example:

from django_components import Component

class Table(Component):
    def on_render_before(self, context: Context, template: Optional[Template]) -> None:
        assert self.raw_args[0] == 123
        assert self.raw_args[1] == 10
raw_kwargs instance-attribute ¤

See source code

Keyword arguments passed to the component.

This is part of the Render API.

Unlike Component.kwargs, this attribute is not typed and will remain as plain dict even if you define the Component.Kwargs class.

Example:

from django_components import Component

class Table(Component):
    def on_render_before(self, context: Context, template: Optional[Template]) -> None:
        assert self.raw_kwargs["page"] == 123
        assert self.raw_kwargs["per_page"] == 10
raw_slots instance-attribute ¤

See source code

Slots passed to the component.

This is part of the Render API.

Unlike Component.slots, this attribute is not typed and will remain as plain dict even if you define the Component.Slots class.

Example:

from django_components import Component

class Table(Component):
    def on_render_before(self, context: Context, template: Optional[Template]) -> None:
        assert self.raw_slots["header"] == "MY_HEADER"
        assert self.raw_slots["footer"] == "FOOTER: " + ctx.data["user_id"]
registered_name instance-attribute ¤

See source code

If the component was rendered with the {% component %} template tag, this will be the name under which the component was registered in the ComponentRegistry.

Otherwise, this will be None.

Example:

@register("my_component")
class MyComponent(Component):
    template = "{{ name }}"

    def get_template_data(self, args, kwargs, slots, context):
        return {
            "name": self.registered_name,
        }

Will print my_component in the template:

{% component "my_component" / %}

And None when rendered in Python:

MyComponent.render()
# None
request instance-attribute ¤

See source code

HTTPRequest object passed to this component.

Example:

class MyComponent(Component):
    def get_template_data(self, args, kwargs, slots, context):
        user_id = self.request.GET['user_id']
        return {
            'user_id': user_id,
        }

Passing request to a component:

In regular Django templates, you have to use RequestContext to pass the HttpRequest object to the template.

With Components, you can either use RequestContext, or pass the request object explicitly via Component.render() and Component.render_to_response().

When a component is nested in another, the child component uses parent's request object.

response_class class-attribute ¤

See source code

This attribute configures what class is used to generate response from Component.render_to_response().

The response class should accept a string as the first argument.

Defaults to django.http.HttpResponse.

Example:

from django.http import HttpResponse
from django_components import Component

class MyHttpResponse(HttpResponse):
    ...

class MyComponent(Component):
    response_class = MyHttpResponse

response = MyComponent.render_to_response()
assert isinstance(response, MyHttpResponse)
slots instance-attribute ¤

See source code

Slots passed to the component.

This is part of the Render API.

slots has the same behavior as the slots argument of Component.get_template_data():

Example:

With Slots class:

from django_components import Component, Slot, SlotInput

class Table(Component):
    class Slots(NamedTuple):
        header: SlotInput
        footer: SlotInput

    def on_render_before(self, context: Context, template: Optional[Template]) -> None:
        assert isinstance(self.slots.header, Slot)
        assert isinstance(self.slots.footer, Slot)

rendered = Table.render(
    slots={
        "header": "MY_HEADER",
        "footer": lambda ctx: "FOOTER: " + ctx.data["user_id"],
    },
)

Without Slots class:

from django_components import Component, Slot, SlotInput

class Table(Component):
    def on_render_before(self, context: Context, template: Optional[Template]) -> None:
        assert isinstance(self.slots["header"], Slot)
        assert isinstance(self.slots["footer"], Slot)
template class-attribute instance-attribute ¤

See source code

Inlined Django template (as a plain string) associated with this component.

Example:

class Table(Component):
    template = '''
      <div>
        {{ my_var }}
      </div>
    '''

Syntax highlighting

When using the inlined template, you can enable syntax highlighting with django_components.types.django_html.

Learn more about syntax highlighting.

from django_components import Component, types

class MyComponent(Component):
    template: types.django_html = '''
      <div>
        {{ my_var }}
      </div>
    '''
template_file class-attribute ¤

See source code

Filepath to the Django template associated with this component.

The filepath must be either:

Example:

Assuming this project layout:

|- components/
  |- table/
    |- table.html
    |- table.css
    |- table.js

Template name can be either relative to the python file (components/table/table.py):

class Table(Component):
    template_file = "table.html"

Or relative to one of the directories in COMPONENTS.dirs or COMPONENTS.app_dirs (components/):

class Table(Component):
    template_file = "table/table.html"
get_context_data ¤

See source code

DEPRECATED: Use get_template_data() instead. Will be removed in v2.

Use this method to define variables that will be available in the template.

Receives the args and kwargs as they were passed to the Component.

This method has access to the Render API.

Read more about Template variables.

Example:

class MyComponent(Component):
    def get_context_data(self, name, *args, **kwargs):
        return {
            "name": name,
            "id": self.id,
        }

    template = "Hello, {{ name }}!"

MyComponent.render(name="World")

Warning

get_context_data() and get_template_data() are mutually exclusive.

If both methods return non-empty dictionaries, an error will be raised.

get_css_data ¤

See source code

Use this method to define variables that will be available from within the component's CSS code.

This method has access to the Render API.

The data returned from this method will be serialized to string.

Read more about CSS variables.

Example:

class MyComponent(Component):
    def get_css_data(self, args, kwargs, slots, context):
        return {
            "color": kwargs["color"],
        }

    css = '''
        .my-class {
            color: var(--color);
        }
    '''

MyComponent.render(color="red")

Args:

Pass-through kwargs:

It's best practice to explicitly define what args and kwargs a component accepts.

However, if you want a looser setup, you can easily write components that accept any number of kwargs, and pass them all to the CSS code.

To do that, simply return the kwargs dictionary itself from get_css_data():

class MyComponent(Component):
    def get_css_data(self, args, kwargs, slots, context):
        return kwargs

Type hints:

To get type hints for the args, kwargs, and slots parameters, you can define the Args, Kwargs, and Slots classes on the component class, and then directly reference them in the function signature of get_css_data().

When you set these classes, the args, kwargs, and slots parameters will be given as instances of these (args instance of Args, etc).

When you omit these classes, or set them to None, then the args, kwargs, and slots parameters will be given as plain lists / dictionaries, unmodified.

Read more on Typing and validation.

Example:

from typing import NamedTuple
from django.template import Context
from django_components import Component, SlotInput

class MyComponent(Component):
    class Args(NamedTuple):
        color: str

    class Kwargs(NamedTuple):
        size: int

    class Slots(NamedTuple):
        footer: SlotInput

    def get_css_data(self, args: Args, kwargs: Kwargs, slots: Slots, context: Context):
        assert isinstance(args, MyComponent.Args)
        assert isinstance(kwargs, MyComponent.Kwargs)
        assert isinstance(slots, MyComponent.Slots)

        return {
            "color": args.color,
            "size": kwargs.size,
        }

You can also add typing to the data returned from get_css_data() by defining the CssData class on the component class.

When you set this class, you can return either the data as a plain dictionary, or an instance of CssData.

If you return plain dictionary, the data will be validated against the CssData class by instantiating it with the dictionary.

Example:

class MyComponent(Component):
    class CssData(NamedTuple):
        color: str
        size: int

    def get_css_data(self, args, kwargs, slots, context):
        return {
            "color": kwargs["color"],
            "size": kwargs["size"],
        }
        # or
        return MyComponent.CssData(
            color=kwargs["color"],
            size=kwargs["size"],
        )
get_js_data ¤

See source code

Use this method to define variables that will be available from within the component's JavaScript code.

This method has access to the Render API.

The data returned from this method will be serialized to JSON.

Read more about JavaScript variables.

Example:

class MyComponent(Component):
    def get_js_data(self, args, kwargs, slots, context):
        return {
            "name": kwargs["name"],
            "id": self.id,
        }

    js = '''
        $onLoad(({ name, id }) => {
            console.log(name, id);
        });
    '''

MyComponent.render(name="World")

Args:

Pass-through kwargs:

It's best practice to explicitly define what args and kwargs a component accepts.

However, if you want a looser setup, you can easily write components that accept any number of kwargs, and pass them all to the JavaScript code.

To do that, simply return the kwargs dictionary itself from get_js_data():

class MyComponent(Component):
    def get_js_data(self, args, kwargs, slots, context):
        return kwargs

Type hints:

To get type hints for the args, kwargs, and slots parameters, you can define the Args, Kwargs, and Slots classes on the component class, and then directly reference them in the function signature of get_js_data().

When you set these classes, the args, kwargs, and slots parameters will be given as instances of these (args instance of Args, etc).

When you omit these classes, or set them to None, then the args, kwargs, and slots parameters will be given as plain lists / dictionaries, unmodified.

Read more on Typing and validation.

Example:

from typing import NamedTuple
from django.template import Context
from django_components import Component, SlotInput

class MyComponent(Component):
    class Args(NamedTuple):
        color: str

    class Kwargs(NamedTuple):
        size: int

    class Slots(NamedTuple):
        footer: SlotInput

    def get_js_data(self, args: Args, kwargs: Kwargs, slots: Slots, context: Context):
        assert isinstance(args, MyComponent.Args)
        assert isinstance(kwargs, MyComponent.Kwargs)
        assert isinstance(slots, MyComponent.Slots)

        return {
            "color": args.color,
            "size": kwargs.size,
            "id": self.id,
        }

You can also add typing to the data returned from get_js_data() by defining the JsData class on the component class.

When you set this class, you can return either the data as a plain dictionary, or an instance of JsData.

If you return plain dictionary, the data will be validated against the JsData class by instantiating it with the dictionary.

Example:

class MyComponent(Component):
    class JsData(NamedTuple):
        color: str
        size: int

    def get_js_data(self, args, kwargs, slots, context):
        return {
            "color": kwargs["color"],
            "size": kwargs["size"],
        }
        # or
        return MyComponent.JsData(
            color=kwargs["color"],
            size=kwargs["size"],
        )
get_template_data ¤

See source code

Use this method to define variables that will be available in the template.

This method has access to the Render API.

Read more about Template variables.

Example:

class MyComponent(Component):
    def get_template_data(self, args, kwargs, slots, context):
        return {
            "name": kwargs["name"],
            "id": self.id,
        }

    template = "Hello, {{ name }}!"

MyComponent.render(name="World")

Args:

Pass-through kwargs:

It's best practice to explicitly define what args and kwargs a component accepts.

However, if you want a looser setup, you can easily write components that accept any number of kwargs, and pass them all to the template (similar to django-cotton).

To do that, simply return the kwargs dictionary itself from get_template_data():

class MyComponent(Component):
    def get_template_data(self, args, kwargs, slots, context):
        return kwargs

Type hints:

To get type hints for the args, kwargs, and slots parameters, you can define the Args, Kwargs, and Slots classes on the component class, and then directly reference them in the function signature of get_template_data().

When you set these classes, the args, kwargs, and slots parameters will be given as instances of these (args instance of Args, etc).

When you omit these classes, or set them to None, then the args, kwargs, and slots parameters will be given as plain lists / dictionaries, unmodified.

Read more on Typing and validation.

Example:

from typing import NamedTuple
from django.template import Context
from django_components import Component, SlotInput

class MyComponent(Component):
    class Args(NamedTuple):
        color: str

    class Kwargs(NamedTuple):
        size: int

    class Slots(NamedTuple):
        footer: SlotInput

    def get_template_data(self, args: Args, kwargs: Kwargs, slots: Slots, context: Context):
        assert isinstance(args, MyComponent.Args)
        assert isinstance(kwargs, MyComponent.Kwargs)
        assert isinstance(slots, MyComponent.Slots)

        return {
            "color": args.color,
            "size": kwargs.size,
            "id": self.id,
        }

You can also add typing to the data returned from get_template_data() by defining the TemplateData class on the component class.

When you set this class, you can return either the data as a plain dictionary, or an instance of TemplateData.

If you return plain dictionary, the data will be validated against the TemplateData class by instantiating it with the dictionary.

Example:

class MyComponent(Component):
    class TemplateData(NamedTuple):
        color: str
        size: int

    def get_template_data(self, args, kwargs, slots, context):
        return {
            "color": kwargs["color"],
            "size": kwargs["size"],
        }
        # or
        return MyComponent.TemplateData(
            color=kwargs["color"],
            size=kwargs["size"],
        )

Warning

get_template_data() and get_context_data() are mutually exclusive.

If both methods return non-empty dictionaries, an error will be raised.

inject ¤

See source code

Use this method to retrieve the data that was passed to a {% provide %} tag with the corresponding key.

To retrieve the data, inject() must be called inside a component that's inside the {% provide %} tag.

You may also pass a default that will be used if the {% provide %} tag with given key was NOT found.

This method is part of the Render API, and raises an error if called from outside the rendering execution.

Read more about Provide / Inject.

Example:

Given this template:

{% provide "my_provide" message="hello" %}
    {% component "my_comp" / %}
{% endprovide %}

And given this definition of "my_comp" component:

from django_components import Component, register

@register("my_comp")
class MyComp(Component):
    template = "hi {{ message }}!"

    def get_template_data(self, args, kwargs, slots, context):
        data = self.inject("my_provide")
        message = data.message
        return {"message": message}

This renders into:

As the {{ message }} is taken from the "my_provide" provider.

on_render ¤

See source code

This method does the actual rendering.

Read more about this hook in Component hooks.

You can override this method to:

The default implementation renders the component's Template with the given Context.

class MyTable(Component):
    def on_render(self, context, template):
        if template is None:
            return None
        else:
            return template.render(context)

The template argument is None if the component has no template.

Modifying rendered template

To change what gets rendered, you can:

class MyTable(Component):
    def on_render(self, context, template):
        return "Hello"

Post-processing rendered template

To access the final output, you can yield the result instead of returning it.

This will return a tuple of (rendered HTML, error). The error is None if the rendering succeeded.

class MyTable(Component):
    def on_render(self, context, template):
        html, error = yield template.render(context)

        if error is None:
            # The rendering succeeded
            return html
        else:
            # The rendering failed
            print(f"Error: {error}")

At this point you can do 3 things:

  1. Return a new HTML

    The new HTML will be used as the final output.

    If the original template raised an error, it will be ignored.

    class MyTable(Component):
        def on_render(self, context, template):
            html, error = yield template.render(context)
    
            return "NEW HTML"
    
  2. Raise a new exception

    The new exception is what will bubble up from the component.

    The original HTML and original error will be ignored.

    class MyTable(Component):
        def on_render(self, context, template):
            html, error = yield template.render(context)
    
            raise Exception("Error message")
    
  3. Return nothing (or None) to handle the result as usual

    If you don't raise an exception, and neither return a new HTML, then original HTML / error will be used:

    class MyTable(Component):
        def on_render(self, context, template):
            html, error = yield template.render(context)
    
            if error is not None:
                # The rendering failed
                print(f"Error: {error}")
    
on_render_after ¤

See source code

Hook that runs when the component was fully rendered, including all its children.

It receives the same arguments as on_render_before(), plus the outcome of the rendering:

on_render_after() behaves the same way as the second part of on_render() (after the yield).

class MyTable(Component):
    def on_render_after(self, context, template, result, error):
        if error is None:
            # The rendering succeeded
            return result
        else:
            # The rendering failed
            print(f"Error: {error}")

Same as on_render(), you can return a new HTML, raise a new exception, or return nothing:

  1. Return a new HTML

    The new HTML will be used as the final output.

    If the original template raised an error, it will be ignored.

    class MyTable(Component):
        def on_render_after(self, context, template, result, error):
            return "NEW HTML"
    
  2. Raise a new exception

    The new exception is what will bubble up from the component.

    The original HTML and original error will be ignored.

    class MyTable(Component):
        def on_render_after(self, context, template, result, error):
            raise Exception("Error message")
    
  3. Return nothing (or None) to handle the result as usual

    If you don't raise an exception, and neither return a new HTML, then original HTML / error will be used:

    class MyTable(Component):
        def on_render_after(self, context, template, result, error):
            if error is not None:
                # The rendering failed
                print(f"Error: {error}")
    
on_render_before ¤
on_render_before(context: Context, template: Optional[Template]) -> None

See source code

Runs just before the component's template is rendered.

It is called for every component, including nested ones, as part of the component render lifecycle.

Parameters:

Returns:

Example:

You can use this hook to access the context or the template:

from django.template import Context, Template
from django_components import Component

class MyTable(Component):
    def on_render_before(self, context: Context, template: Optional[Template]) -> None:
        # Insert value into the Context
        context["from_on_before"] = ":)"

        assert isinstance(template, Template)

Warning

If you want to pass data to the template, prefer using get_template_data() instead of this hook.

Warning

Do NOT modify the template in this hook. The template is reused across renders.

Since this hook is called for every component, this means that the template would be modified every time a component is rendered.

render classmethod ¤
render(
    context: Optional[Union[Dict[str, Any], Context]] = None,
    args: Optional[Any] = None,
    kwargs: Optional[Any] = None,
    slots: Optional[Any] = None,
    deps_strategy: DependenciesStrategy = "document",
    type: Optional[DependenciesStrategy] = None,
    render_dependencies: bool = True,
    request: Optional[HttpRequest] = None,
    outer_context: Optional[Context] = None,
    registry: Optional[ComponentRegistry] = None,
    registered_name: Optional[str] = None,
    node: Optional[ComponentNode] = None,
) -> str

See source code

Render the component into a string. This is the equivalent of calling the {% component %} tag.

Button.render(
    args=["John"],
    kwargs={
        "surname": "Doe",
        "age": 30,
    },
    slots={
        "footer": "i AM A SLOT",
    },
)

Inputs:

Type hints:

Component.render() is NOT typed. To add type hints, you can wrap the inputs in component's Args, Kwargs, and Slots classes.

Read more on Typing and validation.

from typing import NamedTuple, Optional
from django_components import Component, Slot, SlotInput

# Define the component with the types
class Button(Component):
    class Args(NamedTuple):
        name: str

    class Kwargs(NamedTuple):
        surname: str
        age: int

    class Slots(NamedTuple):
        my_slot: Optional[SlotInput] = None
        footer: SlotInput

# Add type hints to the render call
Button.render(
    args=Button.Args(
        name="John",
    ),
    kwargs=Button.Kwargs(
        surname="Doe",
        age=30,
    ),
    slots=Button.Slots(
        footer=Slot(lambda ctx: "Click me!"),
    ),
)
render_to_response classmethod ¤
render_to_response(
    context: Optional[Union[Dict[str, Any], Context]] = None,
    args: Optional[Any] = None,
    kwargs: Optional[Any] = None,
    slots: Optional[Any] = None,
    deps_strategy: DependenciesStrategy = "document",
    type: Optional[DependenciesStrategy] = None,
    render_dependencies: bool = True,
    request: Optional[HttpRequest] = None,
    outer_context: Optional[Context] = None,
    registry: Optional[ComponentRegistry] = None,
    registered_name: Optional[str] = None,
    node: Optional[ComponentNode] = None,
    **response_kwargs: Any
) -> HttpResponse

See source code

Render the component and wrap the content in an HTTP response class.

render_to_response() takes the same inputs as Component.render(). See that method for more information.

After the component is rendered, the HTTP response class is instantiated with the rendered content.

Any additional kwargs are passed to the response class.

Example:

Button.render_to_response(
    args=["John"],
    kwargs={
        "surname": "Doe",
        "age": 30,
    },
    slots={
        "footer": "i AM A SLOT",
    },
    # HttpResponse kwargs
    status=201,
    headers={...},
)
# HttpResponse(content=..., status=201, headers=...)

Custom response class:

You can set a custom response class on the component via Component.response_class. Defaults to django.http.HttpResponse.

from django.http import HttpResponse
from django_components import Component

class MyHttpResponse(HttpResponse):
    ...

class MyComponent(Component):
    response_class = MyHttpResponse

response = MyComponent.render_to_response()
assert isinstance(response, MyHttpResponse)

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4