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 = (
Author.objects.annotate(date=TruncDay("updatedDate"))
.values("date")
.annotate(y=Count("id"))
.order_by("-date")
)
# 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
).
<script>
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
});
</script>
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 1400+ tech skills courses.