Solution 1 :

You have got a number of issues in your code.

What your current AJAX call does: It calls your displayUser view. This view renders the whole crud.html template (including the javascript!) and returns it. Your javascript puts this in the place you defined. So after the first AJAX call you’ve got some nested table structure with two javascript blocks, both running in parrallel.

And then these two functions start calling the view again receiving fully rendered pages. So after some time you have got a muddled up web page with multiple scripts running in parrallel, putting fully rendered pages all over the place. This will surely eat up memory.

What you could do is check whether your request is an ajax request and in that case render only the inner table and return this back to your javascript:

def displayUser(request):
    users = CrudUser.objects.all()
    context = {
        'users': users
    }

    if request.is_ajax():
        data = {'rendered_table': render_to_string('table_contents.html', context=context)}
        return JsonResponse(data)

    return render(request, 'crud.html', context) 

The sub template for the inner table:

# table_contents.html
<tr>
    <th>Name</th>
    <th>Address</th>
    <th>Age</th>
</tr>
{% for user in users %}
    <tr>
        <td>{{ user.name }}</td>
        <td>{{ user.address }}</td>
        <td>{{ user.age }}</td>
    </tr>
{% endfor %}

Now you can put that in your template in your javascript

$('#_appendHere').html(data.rendered_table);

One final note: In your ajax function I think it should be data_type and not dataType.

Problem :

Ok, I tried to understand all the posts here, but I couldn’t. Some are outdated, some are not similar to my problem.

Don’t mind me for asking again.

I have a simple HTML table, with some data in it, and I just need to update the data, when it’s changed, without refreshing it.

The object has ‘is_locked’ field, and what I need to do is, when an object is locked(is_locked=True), a small locker icon shows. I can do all of that but after a manual refresh, which is not good.

So when a user, locks an object, after a redirect(page refreshes), locker icon shows. But I need that in a real-time, so when the two users look at the same table, at the same time, after an object lock(from one user), that icon needs to appear on the other user’s browser, without refreshing the page.

I just need that ‘extra’ content(locker icon) to show up in real-time, when the user locks an object.

Try to ignore the custom names(they’re not in English)


My models.py :

from django.db import models

class OpportunityList(models.Model):
    name = models.CharField(max_length=30, blank=True)
    address = models.CharField(max_length=100, blank=True)
    age = models.IntegerField(blank=True, null=True)
    is_locked = models.BooleanField(blank=True, null=True)
    ...

views.py :

from django.http import JsonResponse
from django.shortcuts import render

from .models import OpportunityList
...
@login_required(login_url='registration/login')
def OptikaList(request):
    optika = OpportunityList.objects.all().filter(opp_type='optika')
    context = {
        'optika': optika
    }

    if request.is_ajax():
        data = {'rendered_table':render_to_string('opportunity/get_more_tables.html', context=context)}
        return JsonResponse(data)

    return render(request, 'opportunity/opp_optika.html', context)


def updateTable(request):
    qs = OpportunityList.objects.all().values()
    return JsonResponse({'users': list(qs)})

urls.py :

from django.urls import path
from .views import *

urlpatterns = [
    ...
    path('optika/', OptikaList, name='optika'),
    path('ajax/update/', update_table, name='update_table'),
    ...

opp_optika.html, where the table is, with ajax script.

{% extends 'base.html' %}
{% load static %}
{% block title %} Optika {% endblock %}
{% block content_row %}

    {% if messages %}
        {% for message in messages %}
            <div class=" container-fluid alert alert-success alert-dismissible" role="alert">
                <button type="button" class="close" data-dismiss="alert">&times;</button>
                <h4 class="alert-heading">Uspešno!</h4>
                <hr>
                <p class="mb-0">{{ message }}</p>
            </div>
        {% endfor %}
    {% endif %}

    <div class="card-body">
        <div class="table-responsive">
            <table class="table table-bordered table table-hover dt-responsive" id="dataTable">
                {% include 'opportunity/opp_breadcrumb.html' %}
                <h2 style="margin-left: 50%;">OPTIKA</h2>

                <thead>
                <tr>
                    <th>Adresa Korisnika</th>
                    <th>Područje</th>
                    <th>Korisnik</th>
                    <th>TIS</th>
                    <th>Napomena</th>
                    <th>Akcije</th>
                    <th style="width: 5px">STATUS</th>
                </tr>
                </thead>
                <tbody>
                {% for opp in optika %}
                    <tr>
                        <td>{{ opp.optika_korisnik_adr }}</td>
                        <td>{{ opp.oppc_place }}</td>
                        <td>{{ opp.optika_korisnik }}</td>
                        <td>{{ opp.optika_korisnik_tis_id }}</td>
                        <td>{% if opp.oppc_comment %}{{ opp.oppc_comment }}{% else %}Bez napomene{% endif %}</td>
                        <td>
                            <button type="button" class="btn btn-success btn-sm" data-toggle="modal"
                                    data-target="#detalji_modal{{ opp.pk }}">
                                Detalji
                            </button>
                        </td>
                        <td>
                            {% if opp.is_locked %}
                                <form action="{% url 'opportunity:delete_locked' opp.pk %}" method="POST"
                                      style="display: table-cell">
                                    {% csrf_token %}
                                    <button class="btn"><i style="width: 50px;color: red" class="fa fa-lock"
                                                           aria-hidden="true"></i></button>
                                </form>
                            {% endif %}
                        </td>
                    </tr>
                    <!------------------------------------- DETALJIMODAL ---------------------------------------------->
                    <div class="modal fade bd-example-modal-lg" tabindex="-1" role="dialog"
                         id="detalji_modal{{ opp.pk }}"
                         aria-labelledby="detalji_modalLabel">
                        <div class="modal-dialog modal-lg" role="document">
                            <div class="modal-content">
                                <div class="modal-header">
                                    <h5 class="modal-title" id="detalji_modalLabel">Detalji</h5>
                                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                                        <span aria-hidden="true">&times;</span>
                                    </button>
                                </div>
                                <div class="modal-body" id="">
                                    <div class="container-fluid">
                                        <h5>{{ opp.optika_korisnik }}</h5>
                                        <p>{{ opp.optika_korisnik_adr.title }}</p>
                                        <p>Broj linije : {{ opp.optika_broj_linije }}</p>
                                        <p>Kontakt : {{ opp.optika_kontakt_tel1 }}</p>
                                        <hr>
                                        <p>Okvirni Datum : {{ opp.optika_instal_okvirni_datum }}</p>
                                        <p>TIS Posla : {{ opp.optika_posao_tis_id }}</p>
                                        <p>Zahtev Info : {{ opp.optika_zahev_uneo }}</p>
                                        <hr>
                                        <p>Datum Unosa : {{ opp.optika_zahtev_datum_unosa }}</p>
                                        <hr>
                                        <p>Napomena : <br> <br>
                                            {% if opp.oppc_comment %} {{ opp.oppc_comment }} {% else %} Nema
                                                napomene za korisnika {{ opp.optika_korisnik|title }}. {% endif %}
                                        </p>
                                    </div>
                                </div>
                                <div class="modal-footer">
                                    <p style="margin-right: auto">Zahtev uneo/la : {{ opp.optika_zahev_uneo }}</p>
                                    {% if not opp.is_locked %}
                                        <form action="{% url 'opportunity:poziv' opp.pk %}" method="POST">
                                            {% csrf_token %}
                                            <button type="submit" name="poziv" class="btn btn-outline-danger">
                                                Poziv
                                            </button>
                                        </form>
                                    {% endif %}
                                    {% if opp.is_locked %}
                                        <form action="{% url 'opportunity:delete_locked' opp.pk %}" method="POST"
                                              style="display: table-cell">
                                            {% csrf_token %}
                                            <button type="submit" class="btn btn-dark">
                                                <i class="fas fa-lock-open"></i>
                                                Otključaj
                                            </button>
                                        </form>
                                    {% endif %}
                                    <button type="button" class="btn btn-outline-primary" data-dismiss="modal">
                                        Zatvori
                                    </button>
                                </div>
                            </div>
                        </div>
                    </div>
                    <!------------------------------------ DETALJI ENDMODAL ------------------------------------------->
                {% endfor %}
                </tbody>
            </table>
        </div>
        <script>
            $(document).ready(function () {
                setInterval(function () {
                    $.ajax({
                        url: '{% url 'opportunity:optika' %}',
                        type: "get",
                        cache: true,
                        dataType: 'html',
                        success: function (data) {
                            console.log("success");
                            $('#dataTable').html(data.rendered_table);
                        },
                        error: function (data) {
                            alert("Got an error dude " + data);
                        }
                    });
                }, 5000);
            });
        </script>
{% endblock content_row %}

get_more_tables.html :

<tr>
    <th>Adresa Korisnika</th>
    <th>Područje</th>
    <th>Korisnik</th>
    <th>TIS</th>
    <th>Napomena</th>
    <th>Akcije</th>
    <th style="width: 5px">STATUS</th>
</tr>
{% for opp in optika %}
    <tr>
        <td>{{ opp.optika_korisnik_adr }}</td>
        <td>{{ opp.oppc_place }}</td>
        <td>{{ opp.optika_korisnik }}</td>
        <td>{{ opp.optika_korisnik_tis_id }}</td>
        <td>{% if opp.oppc_comment %}{{ opp.oppc_comment }}{% else %}Bez napomene{% endif %}</td>
        <td>
            <button type="button" class="btn btn-success btn-sm" data-toggle="modal"
                    data-target="#detalji_modal{{ opp.pk }}">
                Detalji
            </button>
        </td>
        <td>
            {% if opp.is_locked %}
                <form action="{% url 'opportunity:delete_locked' opp.pk %}" method="POST"
                      style="display: table-cell">
                    {% csrf_token %}
                    <button class="btn"><i style="width: 50px;color: red" class="fa fa-lock"
                                           aria-hidden="true"></i></button>
                </form>
            {% endif %}
        </td>
    </tr>
    <!------------------------------------- DETALJIMODAL ---------------------------------------------->
    <div class="modal fade bd-example-modal-lg" tabindex="-1" role="dialog"
         id="detalji_modal{{ opp.pk }}"
         aria-labelledby="detalji_modalLabel">
        <div class="modal-dialog modal-lg" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="detalji_modalLabel">Detalji</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body" id="">
                    <div class="container-fluid">
                        <h5>{{ opp.optika_korisnik }}</h5>
                        <p>{{ opp.optika_korisnik_adr.title }}</p>
                        <p>Broj linije : {{ opp.optika_broj_linije }}</p>
                        <p>Kontakt : {{ opp.optika_kontakt_tel1 }}</p>
                        <hr>
                        <p>Okvirni Datum : {{ opp.optika_instal_okvirni_datum }}</p>
                        <p>TIS Posla : {{ opp.optika_posao_tis_id }}</p>
                        <p>Zahtev Info : {{ opp.optika_zahev_uneo }}</p>
                        <hr>
                        <p>Datum Unosa : {{ opp.optika_zahtev_datum_unosa }}</p>
                        <hr>
                        <p>Napomena : <br> <br>
                            {% if opp.oppc_comment %} {{ opp.oppc_comment }} {% else %} Nema
                                napomene za korisnika {{ opp.optika_korisnik|title }}. {% endif %}
                        </p>
                    </div>
                </div>
                <div class="modal-footer">
                    <p style="margin-right: auto">Zahtev uneo/la : {{ opp.optika_zahev_uneo }}</p>
                    {% if not opp.is_locked %}
                        <form action="{% url 'opportunity:poziv' opp.pk %}" method="POST">
                            {% csrf_token %}
                            <button type="submit" name="poziv" class="btn btn-outline-danger">
                                Poziv
                            </button>
                        </form>
                    {% endif %}
                    {% if opp.is_locked %}
                        <form action="{% url 'opportunity:delete_locked' opp.pk %}" method="POST"
                              style="display: table-cell">
                            {% csrf_token %}
                            <button type="submit" class="btn btn-dark">
                                <i class="fas fa-lock-open"></i>
                                Otključaj
                            </button>
                        </form>
                    {% endif %}
                    <button type="button" class="btn btn-outline-primary" data-dismiss="modal">
                        Zatvori
                    </button>
                </div>
            </div>
        </div>
    </div>
    <!------------------------------------ DETALJI ENDMODAL ------------------------------------------->
{% endfor %}

Comments

Comment posted by dev.ink

Great, that actually helped. But now, when I try to implement that into the real project, it seems that nothing happens. I get the ‘success’ message from the console log, from ajax, but when I lock an object, that locker icon doesn’t appear into the table. After I refresh the page manually, then it appears. I edited my code to the actual version.

Comment posted by Chris

I will give your code a look. A polite remark: IMHO it would have been better to post your new question as a new question rather than changing your original question: Now the current answer does not reflect your current question

Comment posted by dev.ink

Yeah, sorry for that one. I figured that out when i overwrote the original one 🙁

Comment posted by Chris

Can you rollback your edit to a previouse version? I think it is possible to rollback your own edits by clicking on the ‘edited’ link in your post

Comment posted by dev.ink

Sure, i can. I’m on my phone now, so I’ll do it later. In the meanwhile, can i politely ask you to review this one? ^^

By