Django Template - Convert a Python list into a JavaScript object

后端 未结 4 1476
谎友^
谎友^ 2020-12-30 02:19

I am working on a Django / Python website. I have a page where I want to display a table of search results. The list of results is passed in to the template as normal.

相关标签:
4条回答
  • 2020-12-30 02:55

    New in Django 2.1: json_script

    Django 2.1 introduced a new template tag: json_script. It is almost exactly what you are looking for, it might be even better. It converts a Python value into JSON, wrapped in a <script> tag. So this template:

    {{ value|json_script:"foobar" }}
    

    ... would produce this:

    <script id="foobar" type="application/json">{"example": "example"}</script>
    

    This is not a normal Javascript <script> tag, it doesn't run, it's just JSON. If you want to access the contents in your Javascript, you can do so like this:

    var value = JSON.parse(document.getElementById('foobar').textContent);
    

    This tag has been coded so that it is properly escaped, a string with </script> in it won't break anything, for instance.

    0 讨论(0)
  • 2020-12-30 02:59

    Solution

    I created a custom template filter, see custom template tags and filters.

    from django.core.serializers import serialize
    from django.db.models.query import QuerySet
    from django.utils import simplejson
    from django.utils.safestring import mark_safe
    from django.template import Library
    
    register = Library()
    
    def jsonify(object):
        if isinstance(object, QuerySet):
            return mark_safe(serialize('json', object))
        return mark_safe(simplejson.dumps(object))
    
    register.filter('jsonify', jsonify)
    jsonify.is_safe = True   
    

    The calls to mark_safe are important. Otherwise Django will escape it.

    In the template:

    //Without template filter (you'll need to serialise in the view)
    var data = jQuery.parseJSON('{{ json_data|safe }}');
    alert(data.length);
    
    //Using the template filter    
    var data2 = jQuery.parseJSON('{{ record_list|jsonify }}');
    alert(data2.length);
    

    Note the single quotes around the template tag.

    Although my next question would be - is it REALLY safe?

    Update

    An updated version working in django 1.8 of the above template tag that also handles being passed a flat values list, ie. values_list('myfield', flat=True):

    from django.core.serializers import serialize
    from django.db.models.query import QuerySet, ValuesListQuerySet
    from django.template import Library
    
    import json
    
    register = Library()
    
    @register.filter( is_safe=True )
    def jsonify(object):
    
        if isinstance(object, ValuesListQuerySet):
            return json.dumps(list(object))
        if isinstance(object, QuerySet):
            return serialize('json', object)
        return json.dumps(object)
    
    0 讨论(0)
  • 2020-12-30 02:59

    Look this answer too.

    But it isn't highload way. You must:

    a) Create JSON files, place to disk or S3. In case is JSON static

    b) If JSON is dynamic. Generate JSON on separately url (like API) in your app.

    And, load by JS directly in any case. For example:

    $.ajax('/get_json_file.json')

    P.S.: Sorry for my English.

    0 讨论(0)
  • 2020-12-30 03:01

    How about a filter that dumps a Python value to JSON? Here's a sample implementation:

    http://djangosnippets.org/snippets/201/

    Since a JSON value also happens to be a valid right-hand side for a Javascript assignment, you can simply put something like...

    var results = {{results|jsonify}};
    

    inside your script.

    0 讨论(0)
提交回复
热议问题