Skip to content

Parameters API Reference

All parameter classes live in dj_design_system.parameters. Any new parameter class added to that module will appear here automatically.

dj_design_system.parameters

BaseParam(description=None, *, required=True, default=_MISSING, choices=None, css_class=False, attr=False, data_attr=False, attr_style='string')

Uses the descriptor protocol to define parameters for components, including type validation, default values, and documentation generation.

See https://docs.python.org/3/howto/descriptor.html for more on the descriptor protocol.

Source code in dj_design_system/parameters/base.py
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
def __init__(
    self,
    description: Optional[str] = None,
    *,
    required: Optional[bool] = True,
    default: Optional[Any] = _MISSING,
    choices: Optional[list[Any]] = None,
    css_class: str | bool = False,
    attr: str | bool = False,
    data_attr: str | bool = False,
    attr_style: str = "string",
):
    self.description = description
    self.required = bool(required)
    self.choices = choices
    self.css_class = css_class
    self.attr = attr
    self.data_attr = data_attr
    self.attr_style = attr_style

    if default is not _MISSING:
        self.default = default
        self.validate(default)
    else:
        self.default = None

get_css_classes(param_name, value)

Return CSS classes derived from the parameter value.

Override in subclasses to produce CSS classes from the parameter.

Source code in dj_design_system/parameters/base.py
120
121
122
123
124
125
def get_css_classes(self, param_name: str, value: Any) -> list[str]:
    """Return CSS classes derived from the parameter value.

    Override in subclasses to produce CSS classes from the parameter.
    """
    return []

get_extra_context(param_name, value)

Return additional context variables to add to the component's template context.

Override in subclasses (e.g. ModelParam) to inject extra context derived from the parameter value.

Source code in dj_design_system/parameters/base.py
112
113
114
115
116
117
118
def get_extra_context(self, param_name: str, value: Any) -> dict[str, Any]:
    """Return additional context variables to add to the component's template context.

    Override in subclasses (e.g. ModelParam) to inject extra context
    derived from the parameter value.
    """
    return {}

get_html_attributes(param_name, value)

Return HTML attributes derived from the parameter value.

Source code in dj_design_system/parameters/base.py
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
def get_html_attributes(self, param_name: str, value: Any) -> dict[str, Any]:
    """Return HTML attributes derived from the parameter value."""
    attrs = {}
    if self.attr:
        attr_name = (
            self.attr
            if isinstance(self.attr, str)
            else param_name.replace("_", "-")
        )
        attrs[attr_name] = value
    if self.data_attr:
        attr_name = (
            self.data_attr
            if isinstance(self.data_attr, str)
            else param_name.replace("_", "-")
        )
        attrs[f"data-{attr_name}"] = value
    return attrs

has_been_set(obj)

Return True if the parameter has been explicitly set on the given component instance.

Source code in dj_design_system/parameters/base.py
146
147
148
def has_been_set(self, obj: Any) -> bool:
    """Return True if the parameter has been explicitly set on the given component instance."""
    return hasattr(obj, self.private_name)

ModelParam(description=None, *, required=True, default=_MISSING)

Bases: BaseParam

A parameter that accepts a Django model instance and exposes its attributes.

Subclass this and define a Meta inner class with at least model and fields. model may be a model class or an "app_label.ModelName" string (resolved lazily via Django's app registry). fields should be a list of attribute names or "__all__" (all concrete model fields).

.. warning::

Prefer explicit field lists over ``"__all__"``.  Using ``"__all__"``
exposes every concrete model field in the template context, which may
include sensitive data. It also defers CSS class field validation to
runtime instead of catching mismatches at class definition time.

Optional Meta attributes:

  • bool_css_classes – list of attribute names (or (attr, class_name) tuples) whose truthy values contribute a CSS class.
  • str_css_classes – list of attribute names (or (attr, class_name) tuples) whose string values contribute a CSS class.

All attributes referenced in bool_css_classes and str_css_classes must be present in Meta.fields.

CSS classes are namespaced with the parameter's name on the component to avoid collisions, e.g. user-active, user-name-andrew.

Source code in dj_design_system/parameters/model.py
61
62
63
64
65
66
67
68
69
def __init__(
    self,
    description: Optional[str] = None,
    *,
    required: Optional[bool] = True,
    default: Optional[Any] = _MISSING,
):
    # ModelParam does not support ``choices``.
    super().__init__(description=description, required=required, default=default)

__init_subclass__(**kwargs)

Validate that all subclasses define a Meta class.

Concrete subclasses must have Meta.model and Meta.fields. Abstract intermediates must set Meta.abstract = True.

Source code in dj_design_system/parameters/model.py
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
def __init_subclass__(cls, **kwargs):
    """Validate that all subclasses define a Meta class.

    Concrete subclasses must have ``Meta.model`` and ``Meta.fields``.
    Abstract intermediates must set ``Meta.abstract = True``.
    """
    super().__init_subclass__(**kwargs)
    own_meta = cls.__dict__.get("Meta", None)
    if own_meta is None:
        raise ValueError(
            f"{cls.__name__} must define a Meta class. "
            "Set Meta.abstract = True for intermediate base classes."
        )
    if getattr(own_meta, "abstract", False):
        return
    if getattr(own_meta, "model", None) is None:
        raise ValueError(f"{cls.__name__}.Meta must define a 'model' attribute.")
    if getattr(own_meta, "fields", None) is None:
        raise ValueError(f"{cls.__name__}.Meta must define a 'fields' attribute.")
    cls._validate_css_class_fields(own_meta)

docstring()

Generate a docstring using the resolved model name.

Source code in dj_design_system/parameters/model.py
149
150
151
152
153
154
155
156
157
158
159
160
161
def docstring(self) -> str:
    """Generate a docstring using the resolved model name."""
    model_class = self._resolve_model()
    docstr = self.name
    if self.required:
        docstr += f": {model_class.__name__}"
    else:
        docstr += f": Optional[{model_class.__name__}]"
    if self.default is not None:
        docstr += f" (default: {self.default})"
    if self.description:
        docstr += f" - {self.description}"
    return docstr

get_css_classes(param_name, value)

Generate namespaced CSS classes from model attributes configured in Meta.

Delegates to shared CSS class generation logic for both boolean and string attributes, adding a {param_name}- prefix for namespacing.

Source code in dj_design_system/parameters/model.py
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
def get_css_classes(self, param_name: str, value: Any) -> list[str]:
    """Generate namespaced CSS classes from model attributes configured in Meta.

    Delegates to shared CSS class generation logic for both boolean and string attributes,
    adding a {param_name}- prefix for namespacing.
    """
    classes: list[str] = super().get_css_classes(param_name, value)
    if value is None:
        return classes

    for item in getattr(self.__class__.Meta, "bool_css_classes", []):  # type: ignore[attr-defined]
        attr, class_name = self._normalise_css_entry(item)
        attr_value = getattr(value, attr, False)
        for cls_name in generate_bool_css_class(class_name, attr_value):
            classes.append(f"{param_name}-{cls_name}")

    for item in getattr(self.__class__.Meta, "str_css_classes", []):  # type: ignore[attr-defined]
        attr, class_name = self._normalise_css_entry(item)
        attr_value = getattr(value, attr, None)
        for raw_class in generate_str_css_class(attr_value):
            classes.append(f"{param_name}-{class_name}-{raw_class}")

    return classes

get_extra_context(param_name, value)

Flatten model attributes into the template context.

Each attribute listed in Meta.fields is added as {param_name}_{attribute}.

Source code in dj_design_system/parameters/model.py
171
172
173
174
175
176
177
178
179
180
181
182
def get_extra_context(self, param_name: str, value: Any) -> dict[str, Any]:
    """Flatten model attributes into the template context.

    Each attribute listed in ``Meta.fields`` is added as
    ``{param_name}_{attribute}``.
    """
    context: dict[str, Any] = super().get_extra_context(param_name, value)
    if value is None:
        return context
    for field_name in self._get_fields():
        context[f"{param_name}_{field_name}"] = getattr(value, field_name, None)
    return context

validate(value)

Check that value is an instance of the configured model.

Source code in dj_design_system/parameters/model.py
139
140
141
142
143
144
145
146
147
def validate(self, value):
    """Check that *value* is an instance of the configured model."""
    if value is None and not self.required:
        return
    model_class = self._resolve_model()
    if not isinstance(value, model_class):
        raise TypeError(
            f"Expected {model_class.__name__} instance but got {type(value)}."
        )

UserParam(description=None, *, required=True, default=_MISSING)

Bases: ModelParam

A ModelParam pre-configured for the project's User model.

Exposes common user attributes and marks is_active as a boolean CSS class (rendered as {param_name}-active when truthy).

Source code in dj_design_system/parameters/model.py
61
62
63
64
65
66
67
68
69
def __init__(
    self,
    description: Optional[str] = None,
    *,
    required: Optional[bool] = True,
    default: Optional[Any] = _MISSING,
):
    # ModelParam does not support ``choices``.
    super().__init__(description=description, required=required, default=default)

options: members: true show_root_heading: false show_source: true show_symbol_type_heading: true show_symbol_type_toc: true docstring_style: google merge_init_into_class: true group_by_category: true