сериализовать модель для использования с диаграммой. js in Django - PullRequest
0 голосов
/ 01 апреля 2020

, хотя я видел много ресурсов на подобные темы, ничто не смогло решить мою проблему. самые близкие были Как мне JSON сериализовать словарь Python? и django сериализация модели .

Я пытаюсь построить график из модели на моем внешнем интерфейсе с помощью Chart. js, и я не могу заставить сериализовать свой вид и подгонять аргументы для графика. Я прикрепляю свою страницу model.py, view.py и htlm, а также полученную ошибку.

models.py

class Classification(models.Model):
    Class = models.CharField(max_length=10, primary_key=True)
    inventory_dollars = models.FloatField(default=0)

    def __str__(self):
        return self.Class


class ClassificationSerializer(serializers.ModelSerializer):
    class Meta:
        model = Classification
        fields = "__all"

views.py

class HomeView(View):
    def get(self, request, *args, **kwargs):
        return render(request, 'dashboard/charts.html', {})



class ChartData(APIView):
    authentification_classes = []
    permission_classes = []

    def get(self, request, format=None):
        labels = Classification.Class
        default_items = Classification.inventory_dollars
        data = {
            "labels" : labels,
            "default": default_items
        }

        return HttpResponse(json.dumps(data), content_type = 'application/javascript; charset=utf8')

html

{%  extends 'dashboard/base.html' %}

<script>
{% block jquery %}
var endpoint = '/api/chart/data'
var defaultData = []
var labels = [];
$.ajax({
    method: "GET",
    url: endpoint,
    success: function(data1){
        labels = data1.labels
        defaultData = data1.default
        setChart()


    },
    error: function(error_data){

        console.log(error_data)
    }}
)

function setChart(){

    var ctx = document.getElementById('myChart').getContext('2d');
    var ctx2 = document.getElementById('myChart2').getContext('2d');

    var mychart2 = new Chart(ctx2, {
        type: 'polarArea',
        data: {
            labels: labels,
            datasets: [{
                label: '# of Votes',
                data: defaultData,
                backgroundColor: [
                    '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(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
            }],
            options: {
                scales: {
                    yAxes: [{
                        ticks: {
                            beginAtZero: true
                        }
                    }]
                }
            }


        }
    })


    var myChart = new Chart(ctx, {
        type: 'bar',
        data: {
            labels: labels,
            datasets: [{
                label: '# of Votes',
                data: defaultData,
                backgroundColor: [
                    '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(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
            }],
            options: {
                scales: {
                    yAxes: [{
                        ticks: {
                            beginAtZero: true
                        }
                    }]
                }
            }
        }
    })}

{% endblock %}
</script>

{% block content %}



<div class ='row'>
    <div class="clo-sm-12">
        <h1>Inventory Management Dashboard</h1>
        <canvas id="myChart" width="400" height="100"></canvas>
        <canvas id="myChart2" width="400" height="100"></canvas>
    </div>
</div>

{% endblock content %}

Как видите, мне нужно найти способ указать «метки» и «по умолчанию» в моем представлении для того, чтобы затем построить их в файле html. Вот ошибка, которую я получаю до сих пор:

Request Method: GET
Request URL: http://127.0.0.1:8000/api/chart/data
Django Version: 3.0.4
Python Executable: /Users/pierre/Desktop/Django-app/bin/python
Python Version: 3.7.1
...

Traceback (most recent call last):
  ...
  File "/Users/pierre/Desktop/inventory3/dashboard/views.py", line 67, in get
    return HttpResponse(json.dumps(data), content_type = 'application/javascript; charset=utf8')
  File "/Users/pierre/anaconda3/lib/python3.7/json/__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  ...

Exception Type: TypeError at /api/chart/data
Exception Value: Object of type Manager is not JSON serializable
Request information:
USER: AnonymousUser

GET: No GET data

POST: No POST data

FILES: No FILES data

как я могу решить эту проблему? Спасибо за любую помощь

Я новичок в Django, и я действительно не знаю, что делать дальше.

обновление: благодаря совету @dirkgroten я изменил свой взгляд на это:

class ChartData(APIView):
    authentification_classes = []
    permission_classes = []

    def get(self, request, format=None):
        labels = Classification.objects.all().values_list('Class', flat=True)
        default_items = Classification.objects.all().values_list('inventory_dollars', flat=True)
        data = {
            "labels" : labels,
            "default": default_items
        }

        return HttpResponse(json.dumps(data), content_type = 'application/javascript; charset=utf8')

, что теперь дает мне ошибку:

TypeError: Object of type QuerySet is not JSON serializable

1 Ответ

1 голос
/ 01 апреля 2020

json.dumps() принимает только python list или python dict. Также внутри dict и list вы можете использовать только dict, list и примитивы python типов str, int и float.

Таким образом, вы не можете просто передать его только своим экземплярам модели, если вы сначала не сериализуете их (что и делает ваш ClassificationSerializer). Но на самом деле, кажется, что ваш API графа просто хочет два списка значений, поэтому вы должны получить их, используя labels = Classification.objects.values_list('Class', flat=True).

Наконец, это возвращает QuerySet (labels), поэтому вам нужно сделайте это list первым: list(labels).

Примечание. Я настоятельно рекомендую переименовать поле Class в другое, строчными буквами. На самом деле вы не можете назвать это class, потому что это зарезервированное ключевое слово, но атрибуты в python должны быть строчными. Ваше имя делает для трудно читаемого кода.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...