Hello to all the good people in the forum. Hope you are doing well.
Im a django/python student (by myself, don’t know anyone to feedback or share the learning)
VIEW 1
I have a link in my webapp that returns a template filled with a list of items from the DB (always 17.000 rows aprox) so the view use pagination to show 30 per page (prevent browser for loading all at once)
@login_required()
def connected_list(request):
template = "template.html"
sql = "base sql query like select * from"
with connections['BD'].cursor() as cursor:
cursor.execute(sql)
rows = cursor.fetchall()
registers = []
for row in rows:
register = {}
register['field1'] = row[0]
register['field2'] = row[1]
register['field3'] = row[2]
registers.append(register)
total = len(registers)
p = Paginator(registers, 30)
page = request.GET.get('page')
conjunto = p.get_page(page)
context = {"total" : total,
"conjunto": conjunto,
}
return render(request, template, context)
VIEW 2
The template also have a search bar and a selection for different sorting criteria both inside one form
which send this 2 parameters via POST request (to keep the url nice and not showing the parameters in the url). This form calls a 2nd view for doing another query to the DB with the filtering parameter and/or the sorting parameter and returns it to the same template from the first view and also has pagination by 30 items per page.
@login_required()
def search_connected_list(request):
template = "template.html"
sql = "base sql query like select * from"
#empieza prueba
sorts = ["sort_by_field_1", "sort_by_field_1", "sort_by_field_1"]
search = request.POST.get('searched')
if search == None:
search = ''
if (search != None) and (search != ''):
sql += f" adds more filtering with the variable {search}%')"
sort = request.POST.get('orden')
if sort in sorts:
sql += f" ORDER BY {sort} ASC"
#termina prueba
with connections['BD'].cursor() as cursor:
cursor.execute(sql)
rows = cursor.fetchall()
registers = []
for row in rows:
register = {}
register['field1'] = row[0]
register['field2'] = row[1]
register['field3'] = row[2]
registers.append(register)
total = len(registers)
p = Paginator(registers, 30)
page = request.GET.get('page')
conjunto = p.get_page(page)
context = {"total" : total,
"conjunto": conjunto,
"search" : search,
# "orden" : sort
}
return render(request, template, context)
PROBLEM
pagination dont work when I call the 2nd view, the list of rows returned by the view is ok (filter criteria and sorting, at least the first 30 I see in the template) but when I click on “go to next page” (GET request) suddenly Im in the page 2 (app dont crash) but from the total number of items (like the base query calling all the items in view 1). For example, I filter using a word and get 6000 rows, going to page 2 I see “page 2 from 567” and total rows show 17.000 instead of “page 2 of 200” and total of 6000.
THE TEMPLATE (just in case)
{% extends "base.html" %}
{% load static %}
{% block extra_js %}
<script src="{% static "js/main_jadmin.js"%}"></script>
{% endblock %}
{% block content %}
{% if conjunto %}
<div class="container-fluid mt-5 mb-5">
<div>
<p>Conectados: {{total}}</p>
</div>
<div>
<form action="{% url 'jadmin:busqueda' %}" method="POST">
{% csrf_token %}
<input type="search" class="" name="searched" value={{search}}>
<label for="orden">ordenar por:</label>
<select id="orden" name="orden">
<option value="" selected></option>
<option value="username">Usuario</option>
<option value="acctstarttime">Inicio de sesion</option>
</select>
<button class="btn btn-outline-secondary" type="submit">Buscar</button>
</form>
</div>
<div class="row">
<div class="col-sm-12 col-md-12 col-lg-12 col-xl-12">
<div class="table-responsive">
<table id="datatables_conected" class="table table-striped">
<thead>
<tr>
<th class="centered">Usuario</th>
<th class="centered">Inicio de sesión</th>
<th class="centered">Duración</th>
<th class="centered">Agregador</th>
<th class="centered">VLAN</th>
<th class="centered">IPv4</th>
<th class="centered">IPv6</th>
<th class="centered">Consumo Download</th>
<th class="centered">Consumo Upload</th>
<th class="centered">Mac cliente</th>
<th class="centered">Acciones</th>
</tr>
</thead>
<tbody>
{% for register in conjunto %}
<tr>
<td>{{register.username}}</td>
<td>{{register.start_time|date:"Y-m-d H:i:s"}}</td>
<td>{{register.duration}}</td>
<td>{{register.nas_ip}}</td>
<td>{{register.vlan}}</td>
<td>{{register.ipv4}}</td>
<td>{{register.ipv6}}</td>
<td>{{register.down_usage}}</td>
<td>{{register.up_usage}}</td>
<td>{{register.mac}}</td>
<td>
<div class="button-row">
<a href="#"><button type="submit" class="btn btn-warning"><i class="fa-solid fa-pencil"></i></button></a>
<a href="#"><button type="submit" class="btn btn-danger"><i class="fa-solid fa-trash-can"></i></button></a>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>
{%comment%} paginacion {% if search %}searched={{search}}&{%endif%} {%endcomment%}
{% if conjunto.has_previous %}
<a href="?page=1">Primera</a>
<a href="?page={{conjunto.previous_page_number}}">Anterior</a>
{% endif %}
pagina {{conjunto.number}} de {{conjunto.paginator.num_pages}}
{% if conjunto.has_next %}
<a href="?page={{conjunto.next_page_number}}">Siguiente</a>
<a href="?page={{conjunto.paginator.num_pages}}">Ultima</a>
{% endif %}
{%comment%} paginacion {%endcomment%}
{% else %}
<p>No hay registros disponibles</p>
{% endif %}
</div>
</div>
</div>
</div>
{% endblock %}
any ideas?! Thanks in advance