Dynamic Charts

Learn to add dynamic charts in your Django admin interface.

We'll cover the following

Dynamic charts

The charts in the previous lesson look nice, but it would be nicer to implement real dynamic charts and not hardcoded ones.

When rendering the change_list.html page, Django uses a method called changelist_view(). You can override this method in your AuthorAdmin class to implement your business logic. As an example, you will display the number of authors updated by date in the AuthorAdmin class defined inside sample_app/admin.py.

def changelist_view(self, request, extra_context=None):
    # Aggregate new authors per day
    chart_data = (
    # Serialize and attach the chart data to the template context
    as_json = json.dumps(list(chart_data), cls=DjangoJSONEncoder)
    print("Json %s"%as_json)
    extra_context = extra_context or {"chart_data": as_json}
    # Call the superclass changelist_view to render the page        
    return super().changelist_view(request, extra_context=extra_context)

When querying your data, then you can convert them as JSON and add them as extra_context in your template.

Now, you will modify your HTML to use the chart_data variable that has been injected into your template (precisely, add below code at line 90 of author/change_list.html).

document.addEventListener('DOMContentLoaded', () => {
    const ctx = document.getElementById('myChart').getContext('2d');
    const chartData = {{ chart_data | safe }};
    // Parse the dates to JS
    chartData.forEach((d) => {d.x = new Date(d.date);});
    // Add your javascript chart presentation below this comment

You will slightly modify the chart presentation and add this code below the comment in the above code snippet.

var myChart = new Chart(ctx, {
    type: 'bar',
    data: {
        datasets: [{
            label: 'number of authors',
            data: chartData,
            backgroundColor: 'rgba(61,61,131,0.5)',
    options: {
        responsive: true,
        scales: {
            xAxes: [{
                type: 'time',
                time: {
                    unit: 'day',
                    round: 'day',
                    displayFormats: {
                        day: 'MMM D',
            }, ],
            yAxes: [{
                ticks: {
                    beginAtZero: true,
            }, ],

And now, if you run your server with this updated code, you will see the following results:

Get hands-on with 1200+ tech skills courses.