首页 > 解决方案 > Django 和 Chart.js 未正确呈现图形

问题描述

所以我花了周末的时间测试和搜索 SO,最后让 Django 和 Chart.js 工作。有点儿。它呈现图形,但数据不正确。当我遍历对象时,结果不是我所期望的。也许我整个周末都盯着这个眼睛瞎了。将不胜感激任何指针。

以下是我的看法...

class ChartView(LoginRequiredMixin, TemplateView):
    template_name = 'Books/chart.html'

    def get_context_data(self, **kwargs):
        context = super(ChartView, self).get_context_data(**kwargs)
        qs1 = Class.objects.filter(id__in=self.request.user.userprofile.class.all()).order_by('id')
        qs2 = Books.objects.filter(class__in=self.request.user.userprofile.books.all()).distinct()
        context['qs1'] = qs1
        context['qs2'] = qs2
        return context

class ChartData(LoginRequiredMixin,APIView):
    model = Books
    authentication_classes = (SessionAuthentication, BasicAuthentication)
    permission_classes = (IsAuthenticated,)

    def get(self, request, format=None):
        qs_count = Books.objects.filter(class__in=self.request.user.userprofile.class.all()).count()
        labels = []
        default_items = []
        data = {
            "labels": labels,
            "default": default_items,
        }
        return Response(data)

这是我的带有 Javascript 的 HTML ......

{% extends 'base5.html' %}

{% block body_block %}
<div class="box6">
          <h1 class="title">Number of Books By Class</h1>
<canvas id="myChart"></canvas>
<div>

<script>
var endpoint = '{% url "Books:chart_data" %}'
var defaultData = [];
var labels = [];
$.ajax({
    method: "GET",
    credentials: 'same-origin',
    url: endpoint,
    success: function(data){
        labels = data.labels
        defaultData = data.default
        var ctx = document.getElementById("myChart");
        var myChart = new Chart(ctx, {
            type: 'bar',
            data: {
                labels: [{% for i in qs1 %}{{ i.id }},{% endfor %}],
                datasets: [{
                    label: "# of Books",
                     data: [{% for j in qs2 %}
                              {{ j.id }},
                            {% endfor %}],
                    backgroundColor: [
                        'rgba(255, 99, 132, 0.2)',
                        'rgba(255, 99, 132, 0.2)',
                        'rgba(54, 162, 235, 0.2)',
                        'rgba(255, 206, 86, 0.2)',
                        'rgba(75, 192, 192, 0.2)',
                        'rgba(153, 102, 255, 0.2)',
                        'rgba(255, 159, 64, 0.2)'
                    ],
                    borderColor: [
                        'rgba(255,99,132,1)',
                        'rgba(255,99,132,1)',
                        'rgba(54, 162, 235, 1)',
                        'rgba(255, 206, 86, 1)',
                        'rgba(75, 192, 192, 1)',
                        'rgba(153, 102, 255, 1)',
                        'rgba(255, 159, 64, 1)'
                    ],
                    borderWidth: 1
                }]
            }
        })
    },
    error: function(error_data){
        console.log("error")
        console.log(error_data)
    }
})
</script>

{% endblock %}

这是模型。

class Books(models.Model):

    book_name = models.CharField(max_length=80,null=True)
    description = models.TextField(max_length=264,unique=False)
    class = models.ForeignKey(Class,on_delete=models.DO_NOTHING,related_name='classes')

class Class(models.Model):
    class_name = models.CharField(max_length=264,unique=True)
    teacher = models.ForeignKey(User,null=True,
                    on_delete=models.CASCADE,related_name="teacher_name")

我觉得我在 qs2 中的循环逻辑是问题所在。它没有正确循环通过 qs2,因为它正在返回结果,但不是正确的结果。我只是想从与班级匹配的用户那里获取书籍,但它不起作用。此外,我只能让“ID”显示在图表上,而不是实际的外键名称。我也不知道如何显示实际的外键名称。感谢任何关于我做错了什么的帮助或指示。我好近!

标签: djangopython-3.xdjango-templatesdjango-viewschart.js

解决方案


在与 Yusef BH 一起工作了一整天之后,得出了以下关于正确渲染数据的解决方案。值得注意的是,标签仍然没有通过。我为标签打开了一个单独的 SO 问题。这是允许我在图表上正确显示项目的代码。

我的 HTML

{% extends 'base5.html' %}

{% block body_block %}
<div class="box6">
          <h1 class="title">Number of Books By Author</h1>
<canvas id="myChart"></canvas>
<div>

  <script>
  var endpoint = '{% url "Books:chart_data" %}'
  var defaultData = [];
  var labels = [];
  array = {{ procedures3 }}
  $.ajax({
      method: "GET",
      credentials: 'same-origin',
      url: endpoint,
      success: function(data){
          defaultData = data.default
          var ctx = document.getElementById("myChart");
          var myChart = new Chart(ctx, {
              type: 'bar',
              data: {
                  labels: [{% for i in book %}{{ i.id }},{% endfor %}],
                  datasets: [{
                      label: "# of Procedures",
                      data: [{% for j in book_count %}
                               {{ j }},
                             {% endfor %}],
                      backgroundColor: [
                          'rgba(255, 99, 132, 0.2)',
                          'rgba(255, 99, 132, 0.2)',
                          'rgba(54, 162, 235, 0.2)',
                          'rgba(255, 206, 86, 0.2)',
                          'rgba(75, 192, 192, 0.2)',
                          'rgba(153, 102, 255, 0.2)',
                          'rgba(255, 159, 64, 0.2)'
                      ],
                      borderColor: [
                          'rgba(255,99,132,1)',
                          'rgba(255,99,132,1)',
                          'rgba(54, 162, 235, 1)',
                          'rgba(255, 206, 86, 1)',
                          'rgba(75, 192, 192, 1)',
                          'rgba(153, 102, 255, 1)',
                          'rgba(255, 159, 64, 1)'
                      ],
                      borderWidth: 1
                  }]
              }
          })
      },
      error: function(error_data){
          console.log("error")
          console.log(error_data)
      },
  })
  </script>
  {% endblock %}

视图.py

图表视图

class ChartData(LoginRequiredMixin,APIView):
    model = Author
    authentication_classes = (SessionAuthentication, BasicAuthentication)
    permission_classes = (IsAuthenticated,)

    def get(self, request, format=None):
        default_items = []
        labels = []
        data = {
            "labels": labels,
            "default": default_items,
        }
        return Response(data)

图表视图

class ChartView(LoginRequiredMixin, TemplateView): template_name = 'Book/chart.html'

def get_context_data(self, **kwargs):
    context = super(ChartView, self).get_context_data(**kwargs)
    book = Author.objects.filter(id__in=self.request.user.userprofile.author.all()).order_by('id')
    books_count = [ Book.objects.filter(author=cls).count() for cls in book ]
    context['book'] = book
    context['book_count'] = books_count
    return context

推荐阅读