0

I 'm building a Django project and trying to use AJAX. I need to refresh my template with new data that comes every 5 seconds from a Raspberri Pi. The data is stored in a SQLite database.

I'm new to Django and pretty new to Ajax.I try to begin with something basic and this is my code:

view.py

from django.http import HttpResponse
from django.template import RequestContext,loader
from .models import Results

def index(request):
    return HttpResponse(loader.get_template('mysensor/index.html').render(RequestContext(request,{'latest_results_list':Results.objects.all()})))


def update(request):
     return HttpResponse(loader.get_template('mysensor/index.html').render(RequestContext(request,{'latest_results_list':Results.objects.all()})))

My template:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js">
</script>
 <script type="text/javascript">


    $( document ).ready(function() {
       setInterval(function(){
           $.ajax({
               url:'/mysensor/update' ,
               type: "get",
               cache: true,
               timeout: 30000,
               dataType: 'html',
               success: function(data) {
                   console.log("success");
                   $('#MyTable').html(data);
               },
               error: function(data) {
                   alert("Got an error dude "+data);
               }
           });
       },5000);
    });

 </script>

<table id="MyTable">
<tr>
  <th>Date</th>
  <th>Time</th>
  <th>Temperature</th>
 <th>Humidity</th>
</tr>
{% for b in latest_results_list %}
<tr>
  <td>{{ b.date }}</td>
  <td>{{ b.time }}</td>
  <td>{{ b.temperature }}</td>
<td>{{ b.humidity }}</td>
</tr>
{% endfor %}
</table>

In runtime my web page collapse and analyzing the server logs, the table doesn't refresh every 5 seconds as I expect but it crashes instead.

Fragment of server logs:

[21/Sep/2015 10:43:46] "GET /mysensor/ HTTP/1.1" 200 7517
[21/Sep/2015 10:43:51] "GET /mysensor/update HTTP/1.1" 301 0
[21/Sep/2015 10:43:51] "GET /mysensor/update/ HTTP/1.1" 200 7517
[21/Sep/2015 10:43:56] "GET /mysensor/update/ HTTP/1.1" 200 7517
[21/Sep/2015 10:43:56] "GET /mysensor/update/ HTTP/1.1" 200 7517
[21/Sep/2015 10:44:01] "GET /mysensor/update/ HTTP/1.1" 200 7517
[21/Sep/2015 10:44:01] "GET /mysensor/update/ HTTP/1.1" 200 7517
[21/Sep/2015 10:44:01] "GET /mysensor/update/ HTTP/1.1" 200 7517
[21/Sep/2015 10:44:01] "GET /mysensor/update/ HTTP/1.1" 200 7517
[21/Sep/2015 10:44:06] "GET /mysensor/update/ HTTP/1.1" 200 7517
[21/Sep/2015 10:44:06] "GET /mysensor/update/ HTTP/1.1" 200 7517
[21/Sep/2015 10:44:06] "GET /mysensor/update/ HTTP/1.1" 200 7517
[21/Sep/2015 10:44:06] "GET /mysensor/update/ HTTP/1.1" 200 7517
[21/Sep/2015 10:44:06] "GET /mysensor/update/ HTTP/1.1" 200 7517
[21/Sep/2015 10:44:06] "GET /mysensor/update/ HTTP/1.1" 200 7517
[21/Sep/2015 10:44:06] "GET /mysensor/update/ HTTP/1.1" 200 7517
[21/Sep/2015 10:44:07] "GET /mysensor/update/ HTTP/1.1" 200 7517
[21/Sep/2015 10:44:11] "GET /mysensor/update/ HTTP/1.1" 200 7517
[21/Sep/2015 10:44:11] "GET /mysensor/update/ HTTP/1.1" 200 7517
[21/Sep/2015 10:44:11] "GET /mysensor/update/ HTTP/1.1" 200 7517
[21/Sep/2015 10:44:11] "GET /mysensor/update/ HTTP/1.1" 200 7517
[21/Sep/2015 10:44:11] "GET /mysensor/update/ HTTP/1.1" 200 7517
[21/Sep/2015 10:44:11] "GET /mysensor/update/ HTTP/1.1" 200 7517
[21/Sep/2015 10:44:11] "GET /mysensor/update/ HTTP/1.1" 200 7517

Any suggestion would be appreciated. Thanks in advance.

rxmxn
  • 499
  • 1
  • 5
  • 17
Cyberguille
  • 1,552
  • 3
  • 28
  • 58
  • 1
    You only want to update the table, but `data` returned by the ajax request will contain the entire html, including the scripts. You either want to change the template to only return the table when doing an ajax request, or change the javascript to extract the table contents from `data` before doing `$('#MyTable').html()`. – Alasdair Sep 21 '15 at 15:48
  • @Alasdair right, that's the problem I was not taking into account, I will fix it and look what happen then. By the way what solution do you recommend the best? – Cyberguille Sep 21 '15 at 15:58
  • Extracting the contents using jQuery is probably easiest. See my answer below. – Alasdair Sep 21 '15 at 16:15

3 Answers3

2

This worked for me:

views.py:

from django.http import HttpResponse
from django.template import RequestContext,loader
from .models import Results

from django.http import JsonResponse

def index(request):
    return HttpResponse(loader.get_template('mysensor/index.html').render(RequestContext(request,{'latest_results_list':Results.objects.all()})))

def update(request):
     results = [ob.as_json() for ob in Results.objects.all()]
     return JsonResponse({'latest_results_list':results})

Template:

<script type="text/javascript" src="{{STATIC_URL}}jquery-1.11.3.min.js"> </script>

<script type="text/javascript">   
    $( document ).ready(function() {
       setInterval(function(){
            $.getJSON('/mysensor/update',
                    function (data) {
                        var json = data['latest_results_list'];
                        var tr;
                         $('#myTable tbody').html("");
                        for (var i = 0; i < json.length; i++) {
                            tr = $('<tr/>');
                            tr.append("<td>" + json[i].date + "</td>");
                            tr.append("<td>" + json[i].time + "</td>");
                            tr.append("<td>" + json[i].temperature + "</td>");
                            tr.append("<td>" + json[i].humidity + "</td>");
                             $('#myTable tbody').append(tr);

                        }
                    });
       },5000);
    });

</script>

<table id ='myTable'>
    <thead>
    <tr>
      <th>Date</th>
      <th>Time</th>
      <th>Temperature</th>
      <th>Humidity</th>
    </tr>
    </thead>
    <tbody >
         {% for b in latest_results_list %}
             <tr>
             <td>{{ b.fecha }}</td>
             <td>{{ b.tiempo }}</td>
             <td>{{ b.temperatura }}</td>
             <td>{{ b.humedad }}</td>
             </tr>                 
         {% endfor %}
    </tbody >        
</table>

These answers helped me to find the solution:

Community
  • 1
  • 1
Cyberguille
  • 1,552
  • 3
  • 28
  • 58
1

You only want to update the table, but data returned by the ajax request will contain the entire html, including the scripts.

You either want to change the template to only return the table when doing an ajax request, or change the javascript to extract the table contents from data before updating the table.

The first approach is probably more elegant. You might find the library django-pjax interesting, it does something like this.

However, extracting the table using jQuery is really easy.

var table_html = data.filter('#MyTable').html();
$('#MyTable').html(table_html);
Alasdair
  • 298,606
  • 55
  • 578
  • 516
1

In views.py you probably should return JSON data like this for example

import json
from django.http import HttpResponse
...
def my_ajax(request):
    data = {
        'key1': 'val1',
        'key2': 'val2',
    }
    return HttpResponse(json.dumps(data))
Marc
  • 1,340
  • 2
  • 14
  • 23