Core Concepts: Widgets
Widget
is the base class for all display elements on a dashboard. It's designed to be flexible and can fetch and display data from various sources.
Base Widget Properties
Here are the most common properties you can define on a widget class:
title
: The display title of the widget. If not provided, the class name is used.model
: The Django model associated with this widget. This is used byget_queryset()
ifqueryset
is not defined, and helps in generating admin URLs.queryset
: A DjangoQuerySet
to use as the data source. If provided, it overridesmodel
.limit_to
: An integer to limit the number of items returned by the defaultvalues()
method. Defaults to10
.width
: The widget's width in the grid system. Defaults towidgets.MEDIUM
. See Dashboards for more details.height
: An integer specifying themax-height
of the widget's body in pixels. If the content exceeds this, it becomes scrollable.cache_timeout
: Cache the widget's rendered body for a specified number of seconds. Default isNone
(no caching).-
changelist_url
: Adds a link from the widget to a model's admin changelist page. This is highly flexible:from .models import MyModel from controlcenter import widgets class MyWidget(widgets.ItemList): # 1. Simple model link changelist_url = MyModel # 2. Link with GET parameters from a dictionary changelist_url = (MyModel, {'status__exact': 0, 'o': '-7.-1'}) # 3. Link with GET parameters from a string changelist_url = (MyModel, 'status__exact=0&o=-7.-1') # 4. A hardcoded internal or external URL changelist_url = '/admin/some/custom/view/'
Key Methods
-
get_queryset()
: Returns the queryset for the widget. The default implementation returnsself.queryset.all()
ifqueryset
is set, otherwiseself.model._default_manager.all()
. You can override this to provide custom filtering.class MyOrdersWidget(widgets.ItemList): model = Order def get_queryset(self): # Start with the default queryset queryset = super(MyOrdersWidget, self).get_queryset() # Filter based on the logged-in user if not self.request.user.is_superuser: return queryset.filter(manager=self.request.user) return queryset
-
values()
: This is the primary method for fetching data. By default, it returns the result ofget_queryset()
, applying thelimit_to
slice. This method is automatically wrapped with Django'scached_property
, meaning it runs only once per widget instance, and the result is cached. This prevents multiple database queries if you access the data more than once during rendering.Important Notes on
values()
:- Because it's a
cached_property
, you access it without parentheses:self.values
notself.values()
. - Do not use
yield
or return a generator, as they cannot be cached.
class MyChartWidget(widgets.LineChart): def labels(self): # Access cached values return [item.date for item in self.values] def series(self): # Access cached values again without a new DB query return [[item.count for item in self.values]] def values(self): # Note: accessed as a property in other methods # This code runs only once. queryset = super(MyChartWidget, self).get_queryset() return queryset.order_by('date')
- Because it's a