Template Tag in Javascript

661 views Asked by At

My Django template tags are not working within my javascript. My latest error is: SyntaxError: expected expression, got '&' var resourceTypes = ['Structural Model', 'X-Ray Diffraction']

How can I get this to work? I need to get these Django variables into the js so that I can create a chart (I'm using Google Charts)

index.html

<script>
  function drawChart() {

    // Create the data table.
    var data = new google.visualization.DataTable();
    data.addColumn('string');
    data.addColumn('number');

    var resourceTypes = {{ "all"|resource_types }}

    {% for x in resourceTypes %}
        data.addRows([
          [x, {{ x|resourceType_count }}],
        ]);
    {% endfor %}

    // Set chart options
    var options = {'title':'Datasets by Type',
                   'width':400,
                   'height':300};

    // Instantiate and draw our chart, passing in some options.
    var chart = new google.visualization.PieChart(document.getElementById('chart_div'));
    chart.draw(data, options);
  }

</script>

templatetags.py

@register.filter(name='resource_types')
def resource_types(data_type):
    resourceTypes = [ str(x.data_type) for x in ResourceType.objects.all() ]
    return resourceTypes

@register.filter(name='resourceType_count')
def resourceType_count(data_type):
    count = Dataset.objects.filter(data_type=ResourceType.objects.get(data_type=data_type)).count()
    return count
1

There are 1 answers

14
Brandon Taylor On BEST ANSWER

You might consider using an assignment tag:

from collections import Counter

@register.assignment_tag(takes_context=True)
def get_resource_types(context):
    values = dict(Counter(list(map(str, ResourceType.objects.values_list('data_type', flat=True)))))
    return {'resource_types': values}

This will give you a count of each data_type string in the values list, such as:

{'data type 1': 3, 'data type 2': 10, 'data type 3': 47}

which you can then pass to the .addRows() function:

{% get_resource_types as resource_types %}

data.addRows([
    {% for data_type, count in resource_types.items %}
    ['{{ data_type }}', {{ count }}],
    {% endfor %}
]);

That should allow you to do everything in a single database query versus having to query for each one. You could also do that with an aggregate count of each type over the queryset. Depending on how much data we're talking about, I can't say for sure which one would be faster.