17

How do I refresh a certain element within a django template?
Example:

{% if object.some_m2m_field.all %}
    <h3>The stuff I want to refresh is below</h3>
    <div id="the-div-that-should-be-refreshed">
    {% for other_object in object.some_m2m_field.all %}
        <a href="www.example.com">{{ other_object.title }}</a>
        &nbsp;
    {% endfor %}
    </div>
{% endif %}

Lets say some other element in the page triggers a javascript that should refresh the div above. Is there a way to cause django to refresh this specific element within the template?

If not, I'll have to monkey-patch the div using regular JS or jQuery methods and not use the great power of django's template layer. Also, the above code is a simplification of the actual template, I use much of the template's power, so monkey-patching the resulting html will be a nightmare...

Jonathan Livni
  • 101,334
  • 104
  • 266
  • 359

3 Answers3

35

You could use an async request to fill the div element. The async request is answered by Django using the template engine.

In this case, you would have to outsource the template code of the div element into a separate template file.

UPDATED WITH EXAMPLE:

Javascript:
For refreshing the view asynchronously, use JQuery for example:

$.ajax({
  url: '{% url myview %}',
  success: function(data) {
  $('#the-div-that-should-be-refreshed').html(data);
  }
});

Async View:

def myview(request):
    object = ...
    return render_to_response('my_template.html', { 'object': object })

Template:

{% for other_object in object.some_m2m_field.all %}
    <a href="www.example.com">{{ other_object.title }}</a>
    &nbsp;
{% endfor %}
Anton Menshov
  • 2,266
  • 14
  • 34
  • 55
o.elias
  • 473
  • 4
  • 8
  • This sounds great, I didn't think of using a "sub"-template. Could you be more specific - what asynch request do you mean and how would it initiate a rerendering of the sub-template? – Jonathan Livni Aug 27 '10 at 20:57
  • 1
    Hi Jonathan, I added an example to my answer. Best regards! – o.elias Aug 28 '10 at 14:04
  • This is just a splendid answer. One thing though, it seems that javascript isn't escaping `{% url myview %}`, meaning it's requesting this one literally without evaluating url and the view name. – zerohedge Dec 15 '17 at 18:18
4

You can have a look at eg. this Ajax with Django tutorial. Anyways as mentioned above you can always use django's template engine, no matter if the view is called in a normal or an ajax request! If you have to use ajax with django more frequently it makes sense to have a look at something like dajax, which is an ajax library for django (have a look at the tutorials there).

Bernhard Vallant
  • 49,468
  • 20
  • 120
  • 148
1

What i did was to put all the code into a set interval function, in this way I will render a location every 5 seconds

The base
setInterval(() => {
    //code to execute
            }, 5000);


Applying to my div
setInterval(() => {
                console.log("interval")
                    $.ajax({
                    url: window.location.pathname,
                    async: false,
                    type: 'POST',
                    data: {
                        'action': 'graph_ubicacion',
                        'id': id
                    },
                    dataType: 'json',
                    
                    
                }).done(function (data) {
                    //console.log("DEBUG 83 === ", data)
                    
                    if (!data.hasOwnProperty('error')) {
                        //Proceso cuando se elije una ubicacion (después de tener una respuesta
                        dataCharArray = [
                            ['Nombre', 'X', 'Y', 'Tipo'],
                        ];
                        
                        if (data.hasOwnProperty('todas')) {
                            data['todas'].forEach(function (elemento) {
                                dataCharArray[dataCharArray.length] = elemento;
                                //console.log("DEBUG 91 === ", elemento)
                                
                            });
                        }
                    
                        if (data.hasOwnProperty('target')) {
                            data['target'].forEach(function (elemento) {
                                dataCharArray[dataCharArray.length] = elemento;
                                    console.log("DEBUG 102 === ", elemento, "\n")
                                    console.log("DEBUG 102 === ", elemento[0], "\n")
                                    console.log("DEBUG 102 === ", elemento[1], "\n")
                                    console.log("DEBUG 102 === ", elemento[2], "\n")
                                    console.log("DEBUG 102 === ", elemento[3], "\n")
                                
                                
                            });
                            
                        }

                        if(data['todas'].length > 0 && data['target'].length > 0){
                            google.charts.load('current', {
                                    'packages': ['corechart']
                                }
                            );
                            google.charts.setOnLoadCallback(drawSeriesChart);

                        }else{
                            if(data['todas'].length === 0 && data['target'].length === 0){
                                //MensajeAlerta("No hay Datos para mostrar");
                                console.log("No hay datos para mostrar")
                            }else{
                                if(data['todas'].length === 0){
                                    MensajeAlerta("No hay Balizas para mostrar");
                                }
                                if(data['target'].length === 0){
                                    MensajeAlerta("No hay Historial de datos de Pulseras para mostrar.");
                                }
                            }
                        }
                        return false;
                    } else {
                        MensajeError(data['error']);
                    }
                    
                }).fail(function (jqXHR, textStatus, errorThrown) {
                    MensajeError(textStatus + ': ' + errorThrown);
                }).always(function (data) {

                })

            }, 5000);