0

This is the second question in the row about my Django project. The code I use here has parts copied from this question:Stack Overflow

What I aim to achieve is a dynamic table, that loops through objects in a list(currently the interval between records is 3 seconds). Let's say I have 21 records. The table first displays records of 1 to 10, on the displaykala.html table. Then it replaces only the table content with records of 11 to 20(with AJAX, without page refresh. The new contents come from get_more_tables_kala.html, and those table rows coming from there, are appended to the displaykala.html table). At no point should the table be empty (UNLESS there is simply no objects to display).

Finally, the contents of 11-20 are replaced with contents of 21-30. In this case, only one row is displayed.

Basicly it always displays first ten records(even if there is only one). Then the code increments the startindex and endindex of the rows, and checks if there is records between those. If there is more than 10 records, it will empty the table and instantly load up the next records (as long as there is even 1 record). Else, the program should wait X amount of seconds, until checking again.

The code has been going through various experimentations, I'm sorry for any dumb coding. I'm still learning Django and AJAX.

There is a few problems though, but let's focus on the main one When the displaykala.html is loaded, the table is displayed empty first, for 3 seconds. I know this is because the code loads the empty displaykala.html table. If I were to set in views that displaykala.html table should display rows 1 to 10 by default, I run into a rendering problem if there is more than 10 rows.

Those rows are loaded from the get_more_tables_kala.html, but when the code is supposed to switch back to displaykala.html, I'm either forced to reload the page (which is not an option due to network traffic increase), or return a new render with displaykala.html as a parameter, which causes the page to create a "copy" of itself, in the place where the table rows are supposed to be.

What I want is the program to switch between the records, without diplaying empty page in between.

I am open to any kind of optimizations or different ideas, as long as they're somewhat simple to understand. I know that this code is rubbish. I'm just trying to get it to work.

I must have missed something vital to tell you, please comment below if you need more info.

EDIT: Also, when I look at the django server console, the three tables (1-10, 11-20(only two records) and the empty one) produce these rows:

  • [14/Dec/2017 12:33:22] "GET /user/get_more_tables_k HTTP/1.1" 200 2222
  • [14/Dec/2017 12:33:24] "GET /user/get_more_tables_k HTTP/1.1" 200 439
  • [14/Dec/2017 12:33:27] "GET /user/get_more_tables_k HTTP/1.1" 200 1

My code runs between views.py, js_kala.html, displaykala.html and get_more_tables_kala.html.

views.py

from django.shortcuts import render, redirect
from userside.models import Kala
from django.contrib.auth.decorators import login_required
from django.db import connection

@login_required
def displaykala(request):
    return render(request, 'displaykala.html')


@login_required
def get_more_tables_kala(request):

    startind = request.session.get('startind')
    if not startind:
        startind = 0
    request.session['startind'] = startind

    endind = request.session.get('endind')
    if not endind:
        endind = 10
    request.session['endind'] = endind

    kalat = Kala.objects.filter(rivinro__gt=startind, rivinro__lte=endind)
    count = kalat.count()
    if count == 0:
        request.session['startind'] = 0
        request.session['endind'] = 10
        kalat = Kala.objects.filter(rivinro__gt=startind, rivinro__lte=endind)
        return render(request, 'get_more_tables_kala.html', {'kalat': kalat})
    else:
        request.session['startind'] += 10
        request.session['endind'] += 10
        kalat = Kala.objects.filter(rivinro__gt=startind, rivinro__lte=endind)
        return render(request, 'get_more_tables_kala.html', {'kalat': kalat})

js_kala.html

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"> </script>
<script>
    var append_increment = 0;
    setInterval(function() {
        $.ajax({
            type: "GET",
            url: "{% url 'get_more_tables_kala' %}",  // URL to your view that serves new info
            data: {'append_increment': append_increment}
        })
        .done(function(response) {
            $('#_appendHere_kala').html('');
            $('#_appendHere_kala').append(response);
            append_increment += 10;
        });
     }, 3000)
</script>

displaykala.html

<html>
    <META HTTP-EQUIV="PRAGMA" CONTENT="NO-CACHE">
  {% load static %}
    {% include 'loginbar.html' %}
    <head>
      <link rel="stylesheet" type="text/css" href="{% get_static_prefix %}css/style.css">
        <title>Display</title>
    </head>
    <body>
            <h1>Display</h1>
            <table>
                <tr>
                    <th>Rivinumero</th>
                    <th>Tuote</th>
                    <th>Latinankielinen nimi</th>
                    <th>Pyyntialue</th>
                    <th>Pyyntipäivä</th>
                    <th>Tuotantotapa</th>
                    <th>Pyydystyyppi</th>
                </tr>
            </table>
            <table id="_appendHere_kala" class="table table-striped table-condensed">
                        <thead>
                      </thead>
                      {% include 'js_kala.html' %}
                        {% for kala in kalat %}
                        <tr>
                        <tbody id="tbody">
                          <td>{{kala.rivinro}}</td>
                          <td>{{kala.tuote}}</td>
                          <td>{{kala.latinalainen_nimi}}</td>
                          <td>{{kala.pyyntialue}}</td>
                          <td>{{kala.pyyntipaiva|date:"d.m.Y" }}</td>
                          <td>{{kala.tuotantotapa}}</td>
                          <td>{{kala.pyydystyyppi}}</td>
                        </tbody>
                        </tr>
                        {% endfor %}
                      </table>
    </body>
</html>

get_more_tables_kala.html

{% load static %}
{% for kala in kalat %}
<tbody id='tbody'>
    <tr>
        <td>{{kala.rivinro}}</td>
        <td>{{kala.tuote}}</td>
        <td>{{kala.latinalainen_nimi}}</td>
        <td>{{kala.pyyntialue}}</td>
        <td>{{kala.pyyntipaiva|date:"d.m.Y" }}</td>
        <td>{{kala.tuotantotapa}}</td>
        <td>{{kala.pyydystyyppi}}</td>
     </tr>
</tbody>

{% endfor %}
Matrix166
  • 79
  • 3
  • 10

2 Answers2

0

You should fetch data from database in "displaykala" view and throw the data into the template file. The startind should be 0 and endind should be 9 because you are fetching 10 records only.

For the empty table problem, it seems that the setInterval() function would cause the table to be empty for 3 seconds. After calling the setInterval(), it will wait for a period of time (3 seconds in this case) before executing the process. Which means this function makes your program cannot be executed immediately. Here is the process workflow:

  1. Wait for 3 seconds
  2. Run AJAX
  3. Wait for 3 seconds
  4. Run AJAX
  5. Again and again

Which means you should execute the AJAX process once before calling the setInterval().

--Edit-- After asking so many questions, I've found something that might also cause the empty table problem.

In this part,

if count == 0:
    request.session['startind'] = 0
    request.session['endind'] = 10
    kalat = Kala.objects.filter(rivinro__gt=startind, rivinro__lte=endind)
    return render(request, 'get_more_tables_kala.html', {'kalat': kalat})

You still use startind and endind (which are the same arguments used in previous filtering statement) to do filter when the system cannot find any data in the filtering. This makes your system prints nothing.

However, from your code, I cannot see why your system finds nothing from the database in every time you started opening the page. You will have to open debug mode of IDE and DevTools of web browser to see what happens with the session and Python variables.

Alvin Lau
  • 194
  • 2
  • 9
  • If I fetch data in the displaykala view, that works for first 10 records. After G_M_T returns rest of records, how am I supposed to jump back to showing displaykala's records, without a page reload? If I "return render(request, displaykala.html), the table section is replaced with . displaykala.html. I get a page within a page. **The main problem** is that the AJAX script currently causes the table to be empty for 3 seconds, before it executes itself again. I need to have records displayed all the time, UNLESS there is simply no records. – Matrix166 Dec 08 '17 at 07:05
  • I had not noticed your edit. Thanks for the answer, but unfortunately it did not help me much. No matter where I set the 'setinterval' in AJAX, I always get the empty table, either at start or at end of the records. ATM, the code in the original post does this: 1.Empty for 3 seconds 2.Records of 1-10 3.Records of 11-20 4.Empty for 3 seconds 5.Records of 1-10 etc I'm maybe just stupid, but I can't figure it out why it prints out the table empty once. Is the problem at the get_more_tables_kala, where I define the startind and endind, and when to increment them and when to reset them? – Matrix166 Dec 11 '17 at 12:09
  • Did you execute AJAX outside the setInterval() for once before calling setInterval() with the AJAX inside? – Alvin Lau Dec 13 '17 at 10:48
  • Does not work, I'll post another comment with my script code. Is this what you meant? It formats badly but hope you can read it. – Matrix166 Dec 13 '17 at 11:04
  • – Matrix166 Dec 13 '17 at 11:05
  • Sorry I made a mistake in the answer (about the fields of AJAX call). I've deleted it already. – Alvin Lau Dec 13 '17 at 11:38
  • Alright. Got any more ideas where the problem might be? Thanks for your time at this point, I appreciate it. – Matrix166 Dec 13 '17 at 11:55
  • Well, I got a new idea. Please see the edited answer. – Alvin Lau Dec 13 '17 at 13:00
  • Alright, thanks for your edit. I might have understood the session variables wrong. Lets take example, with values of 10 and 20: After incrementing the startind and endind in the 'else' branch, the values should be saved to session, so they should now be 20 and 30? So when the view is entered again, the values that that those variables hold are 20 and 30. We make the query, get 0 records, so we jump to the if. There we reset those values, and then print out the first 10 records. Is this example right? – Matrix166 Dec 13 '17 at 13:15
  • I think it is right. Remember you still have to do bug fix inside the "if count==0:" because you used old data to do querying after you reset the session. Just assign the new values to startind and endind Python variable. – Alvin Lau Dec 13 '17 at 13:28
  • But after incrementing, lets say I have values of 20 and 30, which hold no records in between. The code gets the latest existing values for startind and endind, which should be 20 and 30. The filtering is then done, and the count should be 0, as there are no records in database between 20 and 30. We jump into the if-loop, where we reset startind to be 0, and endind to be 10, which gives us records. Those records should then be shown on the table, without the empty table. I'm sorry but is my code so wrong that I don't see the error myself? Could the error be in the JS, where we empty the table? – Matrix166 Dec 14 '17 at 08:21
  • Edited the start post a bit – Matrix166 Dec 14 '17 at 10:34
  • Sorry, I don't quite get what you mean about the problem you are facing right now. Also, did you use Python debug tools to find out the problem? You will be able to run the program statement by statement and see what value that the variables are holding. Otherwise, we need a lot of luck to guessing a bug. And make sure your database has the records you need (especially 20-30 if you want to display them). – Alvin Lau Dec 14 '17 at 11:27
  • Yes, I'm trying to get into pdb, and I'll report back when I find something. The point in the program is that the end-user can perform CRUD operations on the records. The program shows all the records, 10 records at a time. Atm, I have 12 records in the DB. I want the program to first show ten records, then the next ten(even if there were only two) records, and then show the first 10 records again. This would go on indefinately. There can not be an empty table in between. – Matrix166 Dec 14 '17 at 11:39
  • Alright, I'm still stuck, and could not get pdb to work the way I wanted. – Matrix166 Dec 18 '17 at 12:51
0

Solved for now, got help from elsewhere with a brand new solution.

Matrix166
  • 79
  • 3
  • 10