component_registry - Django-Components" > component_registry - Django-Components" >
Skip to content

component_registry ¤

registry module-attribute ¤

The default and global component registry. Use this instance to directly register or remove components:

# Register components
registry.register("button", ButtonComponent)
registry.register("card", CardComponent)
# Get single
registry.get("button")
# Get all
registry.all()
# Unregister single
registry.unregister("button")
# Unregister all
registry.clear()

ComponentRegistry ¤

ComponentRegistry(
    library: Optional[Library] = None, settings: Optional[Union[RegistrySettings, Callable[[ComponentRegistry], RegistrySettings]]] = None
)

Manages which components can be used in the template tags.

Each ComponentRegistry instance is associated with an instance of Django's Library. So when you register or unregister a component to/from a component registry, behind the scenes the registry automatically adds/removes the component's template tag to/from the Library.

The Library instance can be set at instantiation. If omitted, then the default Library instance from django_components is used. The Library instance can be accessed under library attribute.

Example:

# Use with default Library
registry = ComponentRegistry()

# Or a custom one
my_lib = Library()
registry = ComponentRegistry(library=my_lib)

# Usage
registry.register("button", ButtonComponent)
registry.register("card", CardComponent)
registry.all()
registry.clear()
registry.get()
Source code in src/django_components/component_registry.py
def __init__(
    self,
    library: Optional[Library] = None,
    settings: Optional[Union[RegistrySettings, Callable[["ComponentRegistry"], RegistrySettings]]] = None,
) -> None:
    self._registry: Dict[str, ComponentRegistryEntry] = {}  # component name -> component_entry mapping
    self._tags: Dict[str, Set[str]] = {}  # tag -> list[component names]
    self._library = library
    self._settings_input = settings
    self._settings: Optional[Callable[[], InternalRegistrySettings]] = None

    all_registries.append(self)

library property ¤

library: Library

The template tag library with which the component registry is associated.

all ¤

all() -> Dict[str, Type[Component]]

Retrieve all registered component classes.

Example:

# First register components
registry.register("button", ButtonComponent)
registry.register("card", CardComponent)
# Then get all
registry.all()
# > {
# >   "button": ButtonComponent,
# >   "card": CardComponent,
# > }
Source code in src/django_components/component_registry.py
def all(self) -> Dict[str, Type["Component"]]:
    """
    Retrieve all registered component classes.

    Example:

    ```py
    # First register components
    registry.register("button", ButtonComponent)
    registry.register("card", CardComponent)
    # Then get all
    registry.all()
    # > {
    # >   "button": ButtonComponent,
    # >   "card": CardComponent,
    # > }
    ```
    """
    comps = {key: entry.cls for key, entry in self._registry.items()}
    return comps

clear ¤

clear() -> None

Clears the registry, unregistering all components.

Example:

# First register components
registry.register("button", ButtonComponent)
registry.register("card", CardComponent)
# Then clear
registry.clear()
# Then get all
registry.all()
# > {}
Source code in src/django_components/component_registry.py
def clear(self) -> None:
    """
    Clears the registry, unregistering all components.

    Example:

    ```py
    # First register components
    registry.register("button", ButtonComponent)
    registry.register("card", CardComponent)
    # Then clear
    registry.clear()
    # Then get all
    registry.all()
    # > {}
    ```
    """
    all_comp_names = list(self._registry.keys())
    for comp_name in all_comp_names:
        self.unregister(comp_name)

    self._registry = {}
    self._tags = {}

get ¤

get(name: str) -> Type[Component]

Retrieve a component class registered under the given name.

Raises NotRegistered if the given name is not registered.

Example:

# First register component
registry.register("button", ButtonComponent)
# Then get
registry.get("button")
# > ButtonComponent
Source code in src/django_components/component_registry.py
def get(self, name: str) -> Type["Component"]:
    """
    Retrieve a component class registered under the given name.

    Raises `NotRegistered` if the given name is not registered.

    Example:

    ```py
    # First register component
    registry.register("button", ButtonComponent)
    # Then get
    registry.get("button")
    # > ButtonComponent
    ```
    """
    if name not in self._registry:
        raise NotRegistered('The component "%s" is not registered' % name)

    return self._registry[name].cls

register ¤

register(name: str, component: Type[Component]) -> None

Register a component with this registry under the given name.

A component MUST be registered before it can be used in a template such as:

{% component "my_comp" %}{% endcomponent %}

Raises AlreadyRegistered if a different component was already registered under the same name.

Example:

registry.register("button", ButtonComponent)
Source code in src/django_components/component_registry.py
def register(self, name: str, component: Type["Component"]) -> None:
    """
    Register a component with this registry under the given name.

    A component MUST be registered before it can be used in a template such as:
    ```django
    {% component "my_comp" %}{% endcomponent %}
    ```

    Raises `AlreadyRegistered` if a different component was already registered
    under the same name.

    Example:

    ```py
    registry.register("button", ButtonComponent)
    ```
    """
    existing_component = self._registry.get(name)
    if existing_component and existing_component.cls._class_hash != component._class_hash:
        raise AlreadyRegistered('The component "%s" has already been registered' % name)

    entry = self._register_to_library(name, component)

    # Keep track of which components use which tags, because multiple components may
    # use the same tag.
    tag = entry.tag
    if tag not in self._tags:
        self._tags[tag] = set()
    self._tags[tag].add(name)

    self._registry[name] = entry

unregister ¤

unregister(name: str) -> None

Unlinks a previously-registered component from the registry under the given name.

Once a component is unregistered, it CANNOT be used in a template anymore. Following would raise an error:

{% component "my_comp" %}{% endcomponent %}

Raises NotRegistered if the given name is not registered.

Example:

# First register component
registry.register("button", ButtonComponent)
# Then unregister
registry.unregister("button")
Source code in src/django_components/component_registry.py
def unregister(self, name: str) -> None:
    """
    Unlinks a previously-registered component from the registry under the given name.

    Once a component is unregistered, it CANNOT be used in a template anymore.
    Following would raise an error:
    ```django
    {% component "my_comp" %}{% endcomponent %}
    ```

    Raises `NotRegistered` if the given name is not registered.

    Example:

    ```py
    # First register component
    registry.register("button", ButtonComponent)
    # Then unregister
    registry.unregister("button")
    ```
    """
    # Validate
    self.get(name)

    entry = self._registry[name]
    tag = entry.tag

    # Unregister the tag from library if this was the last component using this tag
    # Unlink component from tag
    self._tags[tag].remove(name)

    # Cleanup
    is_tag_empty = not len(self._tags[tag])
    if is_tag_empty:
        del self._tags[tag]

    # Only unregister a tag if it's NOT protected
    is_protected = is_tag_protected(self.library, tag)
    if not is_protected:
        # Unregister the tag from library if this was the last component using this tag
        if is_tag_empty and tag in self.library.tags:
            del self.library.tags[tag]

    del self._registry[name]

register ¤

register(name: str, registry: Optional[ComponentRegistry] = None) -> Callable[[_TComp], _TComp]

Class decorator to register a component.

Usage:

@register("my_component")
class MyComponent(Component):
    ...

Optionally specify which ComponentRegistry the component should be registered to by setting the registry kwarg:

my_lib = django.template.Library()
my_reg = ComponentRegistry(library=my_lib)

@register("my_component", registry=my_reg)
class MyComponent(Component):
    ...
Source code in src/django_components/component_registry.py
def register(name: str, registry: Optional[ComponentRegistry] = None) -> Callable[[_TComp], _TComp]:
    """
    Class decorator to register a component.

    Usage:

    ```py
    @register("my_component")
    class MyComponent(Component):
        ...
    ```

    Optionally specify which `ComponentRegistry` the component should be registered to by
    setting the `registry` kwarg:

    ```py
    my_lib = django.template.Library()
    my_reg = ComponentRegistry(library=my_lib)

    @register("my_component", registry=my_reg)
    class MyComponent(Component):
        ...
    ```
    """
    if registry is None:
        registry = _the_registry

    def decorator(component: _TComp) -> _TComp:
        registry.register(name=name, component=component)
        return component

    return decorator