Skip to content

Components¤

These are the components provided by django_components.

DynamicComponent ¤

Bases: django_components.component.Component

See source code

This component is given a registered name or a reference to another component, and behaves as if the other component was in its place.

The args, kwargs, and slot fills are all passed down to the underlying component.

Parameters:

  • is (str | Type[Component]) –

    Component that should be rendered. Either a registered name of a component, or a Component class directly. Required.

  • registry (ComponentRegistry, default: None ) –

    Specify the registry to search for the registered name. If omitted, all registries are searched until the first match.

  • *args (Optional[Any], default: None ) –

    Additional data passed to the component.

  • **kwargs (Optional[Any], default: None ) –

    Additional data passed to the component.

Slots:

  • Any slots, depending on the actual component.

Examples:

Django

{% component "dynamic" is=table_comp data=table_data headers=table_headers %}
    {% fill "pagination" %}
        {% component "pagination" / %}
    {% endfill %}
{% endcomponent %}

Or in case you use the django_components.component_shorthand_formatter tag formatter:

{% dynamic is=table_comp data=table_data headers=table_headers %}
    {% fill "pagination" %}
        {% component "pagination" / %}
    {% endfill %}
{% enddynamic %}

Python

from django_components import DynamicComponent

DynamicComponent.render(
    kwargs={
        "is": table_comp,
        "data": table_data,
        "headers": table_headers,
    },
    slots={
        "pagination": PaginationComponent.render(
            deps_strategy="ignore",
        ),
    },
)

Use cases¤

Dynamic components are suitable if you are writing something like a form component. You may design it such that users give you a list of input types, and you render components depending on the input types.

While you could handle this with a series of if / else statements, that's not an extensible approach. Instead, you can use the dynamic component in place of normal components.

Component name¤

By default, the dynamic component is registered under the name "dynamic". In case of a conflict, you can set the COMPONENTS.dynamic_component_name setting to change the name used for the dynamic components.

# settings.py
COMPONENTS = ComponentsSettings(
    dynamic_component_name="my_dynamic",
)

After which you will be able to use the dynamic component with the new name:

{% component "my_dynamic" is=table_comp data=table_data headers=table_headers %}
    {% fill "pagination" %}
        {% component "pagination" / %}
    {% endfill %}
{% endcomponent %}

ErrorFallback ¤

Bases: django_components.component.Component

See source code

Use ErrorFallback to catch errors and display a fallback content instead.

This is similar to React's ErrorBoundary component.

Example:

Given this template:

{% component "error_fallback" fallback="Oops, something went wrong" %}
    {% component "table" / %}
{% endcomponent %}

Then:

  • If the table component does NOT raise an error, then the table is rendered as normal.
  • If the table component DOES raise an error, then error_fallback renders Oops, something went wrong.

To have more control over the fallback content, you can use the fallback slot instead of the fallback kwarg.

{% component "error_fallback" %}
    {% fill "content" %}
        {% component "table" / %}
    {% endfill %}
    {% fill "fallback" %}
        <p>Oops, something went wrong</p>
        {% button href="/report-error" %}
            Report error
        {% endbutton %}
    {% endfill %}
{% endcomponent %}

If you want to print the error, you can access the error variable as slot data.

{% component "error_fallback" %}
    {% fill "content" %}
        {% component "table" / %}
    {% endfill %}
    {% fill "fallback" data="data" %}
        Oops, something went wrong:
        <pre>{{ data.error }}</pre>
    {% endfill %}
{% endcomponent %}

Python:

With fallback kwarg:

from django_components import ErrorFallback

ErrorFallback.render(
    slots={
        # Main content
        "content": lambda ctx: TableComponent.render(
            deps_strategy="ignore",
        ),
    },
    kwargs={
        # Fallback content
        "fallback": "Oops, something went wrong",
    },
)

With fallback slot:

from django_components import ErrorFallback

ErrorFallback.render(
    slots={
        # Main content
        "content": lambda ctx: TableComponent.render(
            deps_strategy="ignore",
        ),
        # Fallback content
        "fallback": lambda ctx: mark_safe("Oops, something went wrong: " + ctx.error),
    },
)

Info

Remember to define the content slot as function, so it's evaluated from inside of ErrorFallback.