Skip to content

How to pass aggregate array to JavaScript?

I have a list in Django views, and I want to pass it to JavaScript for iteration, I’ve tried serveral way but seems like the data can’t be used by the JavaScript, could anyone have a look, please?

views.py

”’

def visualisation(request, project_id):

project = Project.objects.get(id=project_id)

todos = project.todo_set.filter(status='to_do')
progresses = project.todo_set.filter(status='in_progress')
dones = project.todo_set.filter(status='done')

counts_data = Todo.objects.aggregate(
    to_do_count = Count('pk', filter=Q(status='to_do')),
    in_progress_count = Count('pk', filter=Q(status='in_progress')),
    done_count = Count('pk', filter=Q(status='done'))
    )

return render(request, 'todo_lists/progress.html', counts_data)

”’

html

”’

data: {
    labels: ['todo','inprogress','done'],
    
    datasets: [{
        label: '# of Votes',

        data: [{% for todo in data %} {{ todo }}, {% endfor %}],
        
        backgroundColor: [
            'rgba(255, 99, 132, 0.2)',
            'rgba(54, 162, 235, 0.2)',
            'rgba(255, 206, 86, 0.2)'
        ],
        borderColor: [
            'rgba(255, 99, 132, 1)',
            'rgba(54, 162, 235, 1)',
            'rgba(255, 206, 86, 1)'
        ],
        borderWidth: 1
    }]
}

”’

Answer

import json

def visualisation(request, project_id):

    project = Project.objects.get(id=project_id)

    todos = project.todo_set.filter(status='to_do')
    progresses = project.todo_set.filter(status='in_progress')
    dones = project.todo_set.filter(status='done')

    counts_data = Todo.objects.aggregate(
        to_do_count = Count('pk', filter=Q(status='to_do')),
        in_progress_count = Count('pk', filter=Q(status='in_progress')),
        done_count = Count('pk', filter=Q(status='done'))
    )
    counts_data_json = json.dumps(counts_data)

    return render(request, 'todo_lists/progress.html', {"counts_data":counts_data_json})

template

<script>
    var counts_data = JSON.parse(`{{ counts_data | escapejs }}`);
</script>
<script>
var your_datadata = {
    labels: ['todo','inprogress','done'],
    
    datasets: [{
        label: '# of Votes',

        data: counts_data,# you don't need to use the template tag anymore
        
        backgroundColor: [
            'rgba(255, 99, 132, 0.2)',
            'rgba(54, 162, 235, 0.2)',
            'rgba(255, 206, 86, 0.2)'
        ],
        borderColor: [
            'rgba(255, 99, 132, 1)',
            'rgba(54, 162, 235, 1)',
            'rgba(255, 206, 86, 1)'
        ],
        borderWidth: 1
    }]
}
</script>