Dynamic dashboards#
Instead of defining the components for your Dashboard statically you can
generate them on the fly as part of the __init__()
function.
This allows you to tailor the components you show.
First define you Dashboard with an __init__ function:
# dashboards.py
from dashboards.dashboard import Dashboard
class DynamicDashboard(Dashboard):
def __init__(self, request: HttpRequest, *args, **kwargs):
super().__init__(request=request, *args, **kwargs)
...
You can then manually add any components to the self.components
dictionary:
# dashboards.py
from dashboards.dashboard import Dashboard
class DynamicDashboard(Dashboard):
def __init__(self, request: HttpRequest, *args, **kwargs):
super().__init__(request=request, *args, **kwargs)
# Generated components
for r in range(1, 3):
self.components[f"dynamic_component_{r}"] = Text(
value=f"Rendered Dynamically via __init__: {r}")
You can also mix and match how you define components:
...
class DynamicDashboard(Dashboard):
normal_component = Text(value="hello")
def __init__(self, request: HttpRequest, *args, **kwargs):
super().__init__(request=request, *args, **kwargs)
# Generated components
for r in range(1, 3):
self.components[f"dynamic_component_{r}"] = Text(
value=f"Rendered Dynamically via __init__: {r}")
This creates a dashboard with 4 components: normal_component
, dynamic_component_1
, dynamic_component_2
, dynamic_component_3
This is a simplistic example but a real use case could be if you wanted to hide
components for certain users. This is possible as the init function
has access the the request
object:
class DynamicDashboard(Dashboard):
normal_component = Text(value="hello")
def __init__(self, request: HttpRequest, *args, **kwargs):
super().__init__(request=request, *args, **kwargs)
# only add this component for staff
if request.user.is_staff:
self.components["component_for_staff"] = Text(
value="Only for staff users"
)
This would show normal_component
to everyone but only include component_for_staff
if the user had the is_staff
flag set.
Another good example of how this could be helpful is if you wish to share data between components but don’t want to have to make multiple calls to the same datasource:
class DynamicDashboard(Dashboard):
def __init__(self, request: HttpRequest, *args, **kwargs):
super().__init__(request=request, *args, **kwargs)
# run super slow fetch
data = get_large_dataset()
self.components["component_for_row0"] = Text(
value=data[0]["field1"]
)
self.components["component_for_row1"] = Text(
value=data[1]["field1"]
)
This calls the get_large_dataset()
function once but then passes it to both
component_for_row0
and component_for_row1
to render.