Passing objects from Django to Javascript DOM

前端 未结 14 1119
野的像风
野的像风 2020-12-04 21:26

I\'m trying to pass a Query Set from Django to a template with javascript.

I\'ve tried different approaches to solve this:

1. Normal Approach - Javas

相关标签:
14条回答
  • 2020-12-04 22:12

    Same Question, "Better"(more recent) answer: Django Queryset to dict for use in json

    Answer by vashishtha-jogi:

    A better approach is to use DjangoJSONEncoder. It has support for Decimal.

    import json
    from django.core.serializers.json import DjangoJSONEncoder
    
    prices = Price.objects.filter(product=product).values_list('price','valid_from')
    
    prices_json = json.dumps(list(prices), cls=DjangoJSONEncoder)
    

    Very easy to use. No jumping through hoops for converting individual fields to float.

    Update : Changed the answer to use builtin json instead of simplejson.

    This is answer came up so often in my google searches and has so many views, that it seems like a good idea to update it and save anyone else from digging through SO. Assumes Django 1.5.

    0 讨论(0)
  • 2020-12-04 22:14

    Ok, I found the solution!

    Mostly it was because of not quoting the results. When Javascript was trying to parse the object this wasn't recognized as string.

    So, first step is:

    var js_list = {{django_list}}; 
    

    changed to:

    var js_list = "{{django_list}}";
    

    After this I realized that Django was escaping characters so I had to replace them like this:

     var myJSONList = (("{{json_list}}").replace(/&(l|g|quo)t;/g, function(a,b){
                    return {
                        l   : '<',
                        g   : '>',
                        quo : '"'
                    }[b];
                }));
    
     myData = JSON.parse( myJSONList );
    

    Note: I tried to avoid escaping characters from Django using this:

    var js_list = "{{json_list|safe}}"; 
    

    But this doesn't work because it gets confused with the quotes.

    Finally I found a way to avoid the logic on the backend of converting to JSON before sending it to Javascript:

    var myDjangoList = (("{{django_list |safe}}").replace(/&(l|g|quo)t;/g, function(a,b){
                return {
                    l   : '<',
                    g   : '>',
                    quo : '"'
                }[b];
            }));
    
    myDjangoList = myDjangoList.replace(/u'/g, '\'')
    myDjangoList = myDjangoList.replace(/'/g, '\"')
    
    myData = JSON.parse( myDjangoList );
    

    I'm sure this can be improved, I let this to you ;)

    Thanks for your answers

    Hope it helps to someone else!

    0 讨论(0)
  • 2020-12-04 22:14

    NOTE for django 2.1

    i found this a little confusing on django documentation so simply explaining a little bit easy way.

    we would normally use this like

    {{ my_info }}
    

    or loop over it depending on what we needed. But if we use the following filter,

    json_script 
    

    we can safely output this value as JSON

    {{ my_info|json_script:"my-info" }}
    

    Our data has been added as JSON, wrapped in a script tag, and we can see the data. We can now use this value by looking it up in JavaScript like so:

    info = JSON.parse(document.getElementById('my-info').textContent);
    
    0 讨论(0)
  • 2020-12-04 22:16

    either;

    read object using {{ django_list }} and then remove unwanted characters

    or do;

    {{ django_list | safe}}
    
    0 讨论(0)
  • 2020-12-04 22:19

    Be careful on also making sure that you output JSON data correctly from Django, otherwise all trials on the frontend side will be a waste of time. In my case I could not use JsonResponse as part of the render function so I did the following:

        def view(self, request):
    
            data = []
            machine_data = list(Machine.objects.filter(location__isnull=False).values_list('serial', 'location', 'customer__name'))
            data.append({
                "locations": machine_data,
            })
    
            return render(request, 'admin/company/device/map.html', {
                "machines": data
            })
    

    And on the frontend:

    {% block content %}
    
        {{ machines_with_location|json_script:"machineLocationData" }}
    
        <div id="content-main">
    
            <h1>Title</h1>
    
            <script type="text/javascript">
    
                const locationDataFromJson = JSON.parse(document.getElementById('machineLocationData').textContent);
    
            </script>
    
        </div>
    
    {% endblock %}
    
    0 讨论(0)
  • 2020-12-04 22:20

    Consolidated answer (my env: Django 2.0)

    In views.py

    import json
    data= []
    // fil the list
    context['mydata'] = json.dumps({'data':data})
    

    In template

      <script type="text/javascript">
          var mydataString = "{{mydata|escapejs}}";
          console.log(JSON.parse(mydataString));
      </script>
    
    0 讨论(0)
提交回复
热议问题