0

I have been searching this topic for a couple days, and recently made great progress today via the help of my friends on SO. I couldn't get the data to display properly, and now it does. The last remaining piece is to get the labels to show properly. I found a similar issue, and suspect that I might be able to use an array, but can't quite figure out the syntax. This is the similar issue. passing each element of array in the labels of char.js is the code that is working fine, only it is displaying the ID of the foreign keys, and not the actual name. If I remove the .id from the chart label loop, the chart does not display at all. For whatever reason I can't seem to access the name of the data, only the ID. Thanks in advance for your help.

My 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 %}

ChartView

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)

The ChartView

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

The last piece for me is to figure out how to get the names of the books instead of the foreign key IDs which I'm getting via this line of code:

       labels: [{% for i in book %}{{ i.id }},{% endfor %}],

Can't seem to access the name even if I do i.name, or i.book_name or anything that I can think of. After further searching, I believe I need to do some type of a reverse lookup for the name, still trying multiple approaches. Thanks for your help in advance.

Steve Smith
  • 1,019
  • 3
  • 16
  • 38

1 Answers1

1

The field name to refer to should be defined in your 'models.py' file - it's not clear whether you are confident i.name or i.book_name are already defined or if you are guessing. It's the column name in the source table in the database. If its actually b_name or title or something, you will need to use that specifically.

The other thing is that you might need quotes around strings in the label list, and possibly the built-in template tag 'escapejs' if there are any special characters that might cause problems in a quote-delimited string.

so try something like (title is just my guess):

labels: [{% for i in book %}'{{ i.title|escapejs }}',{% endfor %}]
Atcrank
  • 439
  • 3
  • 11
  • Quotes did the trick! I was aware of the name, I just couldn't get it to come through. Making this simple change did the trick! Thank you so much!!!!!! escapejs was not needed. – Steve Smith Jun 26 '18 at 13:23