如何使用外键字段数据在Django管理界面中创建甜甜圈图?

时间:2020-02-27 03:25:25

标签: django django-admin chart.js

我正在创建Django管理界面,其中我在绘制三个甜甜圈图以可视化数据,但在三个图中,只有一个图可以正常工作。我认为问题是其他两个图表正在使用外键字段的数据,我不确定如何调用该数据。请帮助我修改图表代码,我们将不胜感激。以下是我的model.py,admin.py和用于创建界面的模板的代码。

models.py

from django.db import models


AGREEMENT_TYPE = (
    ('MOU', 'MOU'),
    ('MOA', 'MOA'),
    ('Research Collaboration Agreement', 'Research Collaboration Agreement'),
    ('Research Grant Agreement', 'Research Grant Agreement'),
    ('Miscellaneous Agreements', 'Miscellaneous Agreements'),
    ('Collaboration Agreement (General/Various Collaboration)', 'Collaboration Agreement (General/Various Collaboration)'),
    ('Database Subscription Agreement', 'Database Subscription Agreement'), 
    ('Student Scholarship / Sponsorship Agreement', 'Student Scholarship / Sponsorship Agreement'),
    ('Clinical Trial Agreement (USM)', 'Clinical Trial Agreement (USM)'),
    ('Donation / Endowment Agreement', 'Donation / Endowment Agreement'),
    ('Students and Staff Exchange Agreement', 'Students and Staff Exchange Agreement'),
    ('Material Transfer Agreement', 'Material Transfer Agreement'),
    ('Non-Disclosure Agreement / Confidentiality', 'Non-Disclosure Agreement / Confidentiality'),
    ('Academic Programs (Dual Degree /  Joint Degree)', 'Academic Programs (Dual Degree /  Joint Degree)'),
    ('Services', 'Services'),
    ('Academic Collaborations / Exchanges Agreement', 'Academic Collaborations / Exchanges Agreement'),
    ('E-Book Publication / Licencing Agreement (PENERBIT USM)', 'E-Book Publication / Licencing Agreement (PENERBIT USM)'),
    ('Licensing and Commercialization', 'Licensing and Commercialization'),
    ('Off-Shore Program Agreement', 'Off-Shore Program Agreement'),
    ('Industrial Training / Internship Agreement', 'Industrial Training / Internship Agreement'),
    ('Industrial PHD Agreement', 'Industrial PHD Agreement'),
    ('Clinical Trial Agreement (USAINS)', 'Clinical Trial Agreement (USAINS)'),
)


class Country(models.Model):
    country_name = models.CharField('Country', max_length=30)

    def __str__(self):
        return self.country_name

class Agreement_Type(models.Model):
    agreement_name = models.TextField('Agreement Type', choices=AGREEMENT_TYPE)

    def __str__(self):
        return self.agreement_name

class Agreement(models.Model):
    agreement_code = models.CharField('Agreement Code', max_length=10)
    agreement_type = models.ForeignKey(Agreement_Type, on_delete=models.CASCADE)
    organization_name = models.TextField('Organization Name')
    country = models.ForeignKey(Country, on_delete=models.CASCADE)
    date_of_signing = models.DateField('Date Of Signing')
    date_of_expiry = models.DateField('Date Of Expiry')
    year = models.CharField('Year', max_length=10)

    def __str__(self):
        return self.agreement_code

    class Meta:
        verbose_name = ('Agreement')

admin.py

from django.contrib import admin

from InternationalRelations.models import Country
from InternationalRelations.models import Agreement_Type
from InternationalRelations.models import Agreement


class Agreement_TypeAdmin(admin.ModelAdmin):
    save_as = True
    save_on_top = True
    change_list_template = 'change_list_graph.html'

class AgreementAdmin(admin.ModelAdmin):
    list_display = ('agreement_code', 'agreement_type', 'organization_name', 'country', 'date_of_signing', 'date_of_expiry', 'year')
    list_filter = ('agreement_type', 'country', 'year')
    save_as = True
    save_on_top = True
    change_list_template = 'change_list_graph.html'



admin.site.register(Country)
admin.site.register(Agreement_Type, Agreement_TypeAdmin)
admin.site.register(Agreement, AgreementAdmin)

change_list_graph.html(模板)

{% extends "admin/change_list.html" %}
{% load static %}
{% block extrahead %}
    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"/>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.0/Chart.min.js"></script>
    <script>
        var randomColorGenerator = function () {
            return '#' + (Math.random().toString(16) + '0000000').slice(2, 8);
        };
        var options = {
            responsive: true,
            maintainAspectRatio: true,
            legend: {
                display: false
            },
            animation: {
                animateScale: true,
                animateRotate: true
            }
        };

        window.onload = function () {
            var ctx = document.getElementById("agreement_type-chart");
            {% regroup cl.queryset|dictsort:"agreement_type" by get_agreement_type_display as agreement_type_list %}
            var lineChart = new Chart(ctx, {
                type: 'doughnut',
                data: {
                    labels: [{% for agreement_type in agreement_type_list %}'{{ agreement_type.grouper }}',{% endfor %}],
                    datasets: [{
                        data: [{% for agreement_type in agreement_type_list %}'{{ agreement_type.list|length }}',{% endfor %}],
                        backgroundColor: [{% for agreement_type in agreement_type_list %}randomColorGenerator(),{% endfor %}]
                    }]
                }, options: options
            });
            ctx = document.getElementById("country-chart");
            {% regroup cl.queryset|dictsort:"country" by country as country_list %}
            lineChart = new Chart(ctx, {
                type: 'doughnut',
                data: {
                    labels: [{% for country in country_list %}'{{ country.grouper }}',{% endfor %}],
                    datasets: [{
                        data: [{% for country in country_list %}'{{ country.list|length }}',{% endfor %}],
                        backgroundColor: [{% for country in country_list %}randomColorGenerator(),{% endfor %}]
                    }]
                }, options: options
            });
            ctx = document.getElementById("year-chart");
            {% regroup cl.queryset|dictsort:"year" by year as year_list %}
            lineChart = new Chart(ctx, {
                type: 'doughnut',
                data: {
                    labels: [{% for year in year_list %}'{{ year.grouper }}',{% endfor %}],
                    datasets: [{
                        data: [{% for year in year_list %}'{{ year.list|length }}',{% endfor %}],
                        backgroundColor: [{% for year in year_list %}randomColorGenerator(),{% endfor %}]
                    }]
                }, options: options
            });
        }
    </script>
{% endblock %}
{% block content %}
    <h1> Graphs for IMCC Data </h1>
    <hr>
    <div class="row">
        <div class="col-sm-4">
            <canvas id="agreement_type-chart" style="width: 100px !important;"></canvas>
            <h4 align="center"><b> AGREEMENT DISTRIBUTION </b></h4>
        </div>
        <div class="col-sm-4">
            <canvas id="country-chart" style="width: 100px !important;"></canvas>
            <h4 align="center" color="green"><b> COUNTRY DISTRIBUTION </b></h4>
        </div>
        <div class="col-sm-4">
            <canvas id="year-chart" style="width: 100px !important;"></canvas>
            <h4 align="center" color="green"><b> YEARLY DISTRIBUTION </b></h4>
        </div>
    </div>
    {{ block.super }}
{% endblock %}

1 个答案:

答案 0 :(得分:0)

我确定我没有为您的问题提供确切的解决方案。但是我最近发现了Django Jet,发现它非常有趣并且易于配置。使用Jet,在管理控制台中设置甜甜圈图非常容易。如果您不喜欢它,请忽略