DCR Core Framework | yassi.dev
After building five DCR panels that now receive tens of thousands of downloads per month, I found myself repeatedly implementing the same concepts around building internal tools and surfacing them through the Django admin. While a lot of this repetition has been facilitated by a cookiecutter template, it is now prudent to establish a new core library and package dj-control-room-base.
This new package centralizes some of the common DNA around creating panels but also adds some new important changes like more granular permissions, MCP tool definitions and a design system. These new changes are aimed at making it much easier to develop new internal tools in the Django admin
Aside: the Django Control Room(DCR) is composed of several tools called panels(such as dj-redis-panel) as well as a central hub package dj-control-room that aggregates panels into a single place.
DCR can also be used as a framework for building your own internal tools. Rather than creating standalone Django applications, teams can build their own suite of custom operation interfaces directly inside the Django admin.
Panel Configuration
At the center of the package is the introduction of a standardized way to express panel settings. Permissions, tool definitions, context generation, and settings resolution are all built around this single abstraction. A new core class, PanelConfig encapsulates and empowers these functions in a simple interface.
1from dj_control_room_base.core import PanelConfig<br>3panel_config = PanelConfig(<br>4 settings_key="MYPANEL_SETTINGS", # defines where to look for settings<br>5 defaults={<br>6 "SOMETHING": "the default value for something"<br>7 },<br>8 tools=[],<br>9)
Panel authors should define a PanelConfig object in their codebase and then use it within views to generate the appropriate context, access panel settings, and scope access to the view with a permission decorator.
1from django.shortcuts import render<br>2from mypanel.conf import panel_config # this panel's PanelConfig<br>4@panel_config.permission_required("myscope") # panel config exposes a decorator for permissions<br>5def index(request):<br>6 # generate appropriate context for admin based view<br>7 context = panel_config.get_context(request, title="My Panel Title")<br>9 # fetch a setting defined for this panel<br>10 something = panel_config.get_settings("SOMETHING")<br>11<br>12 # context object is just a dict as usual<br>13 context["thing"] = something<br>14 return render(request, "admin/mypanel/index.html", context)
Permissions
Currently, all panel views are using Django’s @staff_member_required - this limits views to only users that have access to the admin. This works well for many cases, but multiple github issues have been opened asking for a more granular permission system. A new role/scope based permission system has been introduced:
1from mypanel.conf import panel_config # each panel defines a panel_config<br>3@panel_config.permission_required("dashboard")<br>4def dashboard(request):<br>5 context = panel_config.get_context(request, title="Dashboard")<br>6 return render(request, "mypanel/dashboard.html", context)
the dashboard string here is a scope that is being defined for this view. You can then use the panel’s settings to control access for any scope. In the example below, any user in the ops-users group will be able to load this view. This uses the standard groups app that comes standard with Django. Separately, another scope named super-secret-area has been locked down to only allow super users.
1MYPANEL_SETTINGS = {<br>2 "SCOPE_PERMISSIONS": {<br>3 "dashboard": {<br>4 "ALLOWED_GROUPS": ["ops-users"],<br>5 },<br>6 "super-secret-area": {<br>7 "REQUIRE_SUPERUSER": True,<br>8 },<br>9 },<br>10}
It’s up to panel authors to define scopes and decorate their views appropriately. Panel users are then responsible for setting up access given scopes by specifying groups in their Django settings like the example above.
Styles
When building internal tools, the focus should always be on functionality. That doesn’t mean that internal tools should look terrible. The base package introduces a new set of styles and templates<br>that can be used to help ease any styling decisions when building new panels. The easiest way to use them is to define templates that inherit from the base package’s panel_base.html template.
1{% extends "admin/dj_control_room_base/panel_base.html" %}<br>3{% block panel_content %}<br>4 div class="dcr-page-header"><br>5 h1 class="dcr-page-header__title">My Panelh1><br>6 div><br>8{% endblock %}
You can check out the new styles available in the base package here: Design System
LLM tools
A new PanelTool class has been developed to define mcp tools that can be called via LLM agents. These work by using the new PanelConfig class to attach an array of tools into your panel.<br>When using dj-control-room, the hub now aggregates all of the tools from all installed panels and surfaces new MCP endpoints to serve agents.
1panel_config = PanelConfig(<br>2...