Django admin에 차트 추가
36274 단어 djangopythonchartsjavascript
소개
Django는 데이터베이스 관리를 위한 CRUD 인터페이스가 있는 기존 기능 관리 UI를 제공합니다.이것은 기본 내용과 사용자 관리 시스템의 대다수 용례를 포함한다.그러나 요약이나 역사적 추세를 탐색하는 보기가 없습니다. 이것은 관리 대시보드에서 기대하는 것입니다.
다행히도django 관리 프로그램은 확장이 가능합니다. 조금만 조정하면 상호작용식 자바스크립트 도표를 관리 프로그램에 추가할 수 있습니다.
문제
나는 findwork.dev 에서 전자 우편 구독자의 시간에 따라 변화하는 도형 개관을 얻고 싶다.이 사이트는 전자 우편 구독자 방면에서 증가하고 있습니까 아니면 정체되어 있습니까?지난달에 우리는 몇 명의 사용자가 있었습니까?우리는 어느 주에 가장 많은 구독자를 얻었습니까?모든 구독자가 그들의 이메일을 검증하고 있습니까?
탐색적 도표를 사용하면 우리는 우리 사이트의 역사적 표현을 이해할 수 있다.
내가 최초로 탐색한 것은 기존의 Django 관리 응용 프로그램과 계기판이었다.그 요구는 도표를 그리는 능력을 포함하고 좋은 기록을 가지고 있어 보기 좋다는 것이다.내가 실험한 모든 응용 프로그램은 스타일 면에서 기본 관리자보다 낫지만, 문서가 부족하거나 유지 보수가 없다.
xadmin - 영어 문서 없음
django-jet - 부터
핵심 팀이 개발 중SaaS alternative
django-grapinelli - 아니요
도면 제작 능력
확장django admin
django admin 응용 프로그램은 ModelAdmin classes 으로 구성되어 있습니다.이러한 표현은 관리 인터페이스에서 모델의 시각적 뷰를 나타냅니다.기본적으로 ModelAdmin 클래스에는 5개의 기본 뷰가 있습니다.
e-메일 구독자 모델이 있다고 가정합니다.
# web/models.py
from django.db import models
class EmailSubscriber(models.Model):
email = models.EmailField()
created_at = models.DateTimeField()
관리 응용 프로그램에 전자 우편 구독자를 표시하기 위해서는 django.contrib.admin.ModelAdmin
에서 확장된 클래스를 만들어야 합니다.기본 ModelAdmin은 다음과 같이 보입니다.
# web/admin.py
from django.contrib import admin
from .models import EmailSubscriber
@admin.register(EmailSubscriber)
class EmailSubscriberAdmin(admin.ModelAdmin):
list_display = ("id", "email", "created_at") # display these table columns in the list view
ordering = ("-created_at",) # sort by most recent subscriber
구독자를 추가하면 다음과 같은 초기 데이터 세트가 제공됩니다.$ ./manage.py shell
Python 3.7.3 (default, Apr 9 2019, 04:56:51)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
from web.models import EmailSubscriber
from django.utils import timezone
from datetime import timedelta
import random
for i in range(0, 100):
EmailSubscriber.objects.create(email=f"user_{i}@email.com", created_at=timezone.now() - timedelta(days=random.randint(0, 100)))
...
<EmailSubscriber: EmailSubscriber object (1)>
<EmailSubscriber: EmailSubscriber object (2)>
<EmailSubscriber: EmailSubscriber object (3)>
...
변경 목록 보기에 들어가면 랜덤 생성 시간을 100개 추가한 새 구독자 http://localhost:8000/admin/web/emailsubscriber/ 를 볼 수 있습니다.만약에 우리가 도표를 추가하고 싶다면, 이 도표는 한동안 줄무늬 도표의 구독자 수를 정리했다.우리는 그것을 구독자 목록 위에 놓고 싶다. 이렇게 하면 네가 사이트에 들어가자마자 그것을 볼 수 있다.
아래의 빨간색 구역은 내가 직관적으로 도표를 놓고 싶은 위치를 그려냈다.
새 파일을 만들면, 기본 템플릿이 아닌django 관리자에게 템플릿을 불러올 수 있습니다.에서 빈 파일을 만듭니다.
web/templates/admin/web/emailsubscriber/change_list.html
. {{app}}/templates/admin/{{app}}/{{model}}/change_list.html
. 기본 변경 목록 보기를 확장하고 사용자 정의 텍스트를 추가합니다.
# web/templates/admin/web/emailsubscriber/change_list.html
{% extends "admin/change_list.html" %}
{% load static %}
{% block content %}
<h1>Custom message!</h1>
<!-- Render the rest of the ChangeList view by calling block.super -->
{{ block.super }}
{% endblock %}
멋지다. 우리는 현재 관리 UI를 성공적으로 맞춤 제작했다.더 나아가 Chart.js 를 사용하여 Javascript 차트를 추가합니다.스크립트와 스타일 요소를load Chart에 추가하려면 extrahead 블록을 덮어써야 합니다.제목에 있는 js.
도표.js 코드는 그들이 찾은 프레젠테이션 그래프here를 기반으로 한다.나는 X축의 시간 시퀀스 데이터를 읽기 위해 그것을 약간 수정했다.
# web/templates/admin/web/emailsubscriber/change_list.html
{% extends "admin/change_list.html" %}
{% load static %}
<!-- Override extrahead to add Chart.js -->
{% block extrahead %}
{{ block.super }}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', () => {
const ctx = document.getElementById('myChart').getContext('2d');
// Sample data
const chartData = [
{"date": "2019-08-08T00:00:00Z", "y": 3},
{"date": "2019-08-07T00:00:00Z", "y": 10},
{"date": "2019-08-06T00:00:00Z", "y": 15},
{"date": "2019-08-05T00:00:00Z", "y": 4},
{"date": "2019-08-03T00:00:00Z", "y": 2},
{"date": "2019-08-04T00:00:00Z", "y": 11},
{"date": "2019-08-02T00:00:00Z", "y": 3},
{"date": "2019-08-01T00:00:00Z", "y": 2},
];
// Parse the dates to JS
chartData.forEach((d) => {
d.x = new Date(d.date);
});
// Render the chart
const chart = new Chart(ctx, {
type: 'bar',
data: {
datasets: [
{
label: 'new subscribers',
data: chartData,
backgroundColor: 'rgba(220,20,20,0.5)',
},
],
},
options: {
responsive: true,
scales: {
xAxes: [
{
type: 'time',
time: {
unit: 'day',
round: 'day',
displayFormats: {
day: 'MMM D',
},
},
},
],
yAxes: [
{
ticks: {
beginAtZero: true,
},
},
],
},
},
});
});
</script>
{% endblock %}
{% block content %}
<!-- Render our chart -->
<div style="width: 80%;">
<canvas style="margin-bottom: 30px; width: 60%; height: 50%;" id="myChart"></canvas>
</div>
<!-- Render the rest of the ChangeList view -->
{{ block.super }}
{% endblock %}
봐라, 우리는 지금 이미 도표를 하나 그렸다.js 그래프를 django 관리자로 변환합니다.유일한 문제는 데이터가 백엔드에서 파생된 것이 아니라 하드코딩된 것이다.
관리 템플릿에 차트 데이터 주입
ModelAdmin 클래스에는 changelist_view 라는 방법이 있습니다.이 방법은 변경 목록 페이지를 보여주는 것을 책임진다.이 방법을 다시 쓰면 도표 데이터를 템플릿 상하문에 주입할 수 있습니다.
아래의 코드는 대체적으로 이 점을 실현했다.
# django_admin_chart_js/web/admin.py
import json
from django.contrib import admin
from django.core.serializers.json import DjangoJSONEncoder
from django.db.models import Count
from django.db.models.functions import TruncDay
from .models import EmailSubscriber
@admin.register(EmailSubscriber)
class EmailSubscriberAdmin(admin.ModelAdmin):
list_display = ("id", "email", "created_at")
ordering = ("-created_at",)
def changelist_view(self, request, extra_context=None):
# Aggregate new subscribers per day
chart_data = (
EmailSubscriber.objects.annotate(date=TruncDay("created_at"))
.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)
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)
기술적으로 말하자면, 데이터는 템플릿 상하문에 추가되어야 하지만, 우리는 현재 하드코딩된 데이터가 아니라 도표에서 그것을 사용해야 한다.chartData 변수의 하드 인코딩 데이터를 백엔드의 데이터로 대체합니다.
// django_admin_chart_js/web/templates/admin/web/emailsubscriber/change_list.html
const chartData = {{ chart_data | safe }};
아름다운 도표를 보기 위해 페이지를 다시 불러옵니다.JS를 사용하여 데이터 동적 로드
위의 예시에서 우리는 초기 도표 데이터를 html 템플릿에 직접 주입할 것이다.초기 페이지를 불러오면 우리는 더욱 상호작용을 가지고 데이터를 얻을 수 있다.이를 위해서는 다음과 같은 작업이 필요합니다.
사용자 정의 URL은 기본 URL 앞에 있어야 합니다.기본값은 허용되며, 모든 내용과 일치하기 때문에 요청은 우리의 사용자 정의 방법을 통과하지 않습니다.
우리의python 코드는 지금 이렇게 해야 한다.
# web/admin.py
import json
from django.contrib import admin
from django.core.serializers.json import DjangoJSONEncoder
from django.db.models import Count
from django.db.models.functions import TruncDay
from django.http import JsonResponse
from django.urls import path
from .models import EmailSubscriber
@admin.register(EmailSubscriber)
class EmailSubscriberAdmin(admin.ModelAdmin):
list_display = ("id", "email", "created_at")
ordering = ("-created_at",)
...
def get_urls(self):
urls = super().get_urls()
extra_urls = [
path("chart_data/", self.admin_site.admin_view(self.chart_data_endpoint))
]
# NOTE! Our custom urls have to go before the default urls, because they
# default ones match anything.
return extra_urls + urls
# JSON endpoint for generating chart data that is used for dynamic loading
# via JS.
def chart_data_endpoint(self, request):
chart_data = self.chart_data()
return JsonResponse(list(chart_data), safe=False)
def chart_data(self):
return (
EmailSubscriber.objects.annotate(date=TruncDay("created_at"))
.values("date")
.annotate(y=Count("id"))
.order_by("-date")
)
단추를 눌렀을 때 도표 데이터를 다시 불러오고 도표를 다시 보이기 위해 Javascript 논리를 추가해야 합니다.차트 변수 선언 아래에 다음 행을 추가합니다. // django_admin_chart_js/web/templates/admin/web/emailsubscriber/change_list.html
const chart = new Chart...
...
// Reload chart data from the backend on button click
const btn = document.querySelector('#reload');
btn.addEventListener('click', async() => {
const res = await fetch("/admin/web/emailsubscriber/chart_data/");
const json = await res.json();
json.forEach((d) => {
d.x = new Date(d.date);
});
chart.data.datasets[0].data = json;
chart.update();
});
아래 도표에 html 단추를 추가합니다.{% block content %}
<!-- Render our chart -->
<div style="width: 80%;">
<canvas style="margin-bottom: 30px; width: 60%; height: 50%;" id="myChart"></canvas>
</div>
<button id="reload" style="margin: 1rem 0">Reload chart data</button>
<!-- Render the rest of the ChangeList view -->
{{ block.super }}
{% endblock %}
도표js는 서로 다른 기존의 가시화를 제공했다.기본 도표를 사용하면 쉽고 필요에 따라 맞춤형으로 제작할 수 있습니다.
도표.js 문서는 here, Django 관리 문서는 here입니다.
전체 예시 코드는 Github 에서 찾을 수 있습니다.
Reference
이 문제에 관하여(Django admin에 차트 추가), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/danihodovic/integrating-chart-js-with-django-admin-1kjb텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)