Theme
Version
GitHubPyPIDiscord
On this page

Components

django-components ships these ready-to-use components. Register them like any other component, then use them in your templates.

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.

ParameterTypeDescription
isstr | type[Component]Component that should be rendered. Either a registered name of a component, or a Component class directly. Required.
registryComponentRegistry | NoneSpecify the registry to search for the registered name. If omitted, all registries are searched until the first match. (default: None)
*argsAny | NoneAdditional data passed to the component. (default: None)
**kwargsAny | NoneAdditional data passed to the component. (default: None)

Slots:

  • Any slots, depending on the actual component.

Example

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 %}

Methods

on_render

on_render(context: Context, template: Template | None) -> str

ErrorFallback

Bases: django_components.component.Component

See source code

A component that catches errors and displays fallback content, similar to React's ErrorBoundary.

See React's ErrorBoundary component.

Parameters:

  • fallback (str, optional): A string to display when an error occurs. Cannot be used together with the fallback slot.

Slots:

  • content or default: The main content that might raise an error.
  • fallback: Custom fallback content to display when an error occurs. When using the fallback slot, you can access the error object through slot data ({% fill "fallback" data="data" %}). Cannot be used together with the fallback kwarg.

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.

Attributes

template

template: django_html

Methods

on_render

on_render(context: Context, template: Template | None) -> OnRenderGenerator

Classes

django-components version: 0.152.0