From aa31aefb4235c5678bfc299ce199c347f6829bd1 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 2 Oct 2024 12:13:05 +0200 Subject: [PATCH 1/3] Pagination for list of devices in dashboard and lots --- dashboard/mixins.py | 28 ++++++++++- dashboard/templates/unassigned_devices.html | 7 +++ dashboard/templatetags/__init__.py | 0 dashboard/templatetags/paginacion.py | 19 ++++++++ dashboard/templatetags/range.py | 23 ++++++++++ dashboard/views.py | 19 +++----- device/models.py | 51 ++++++++++++++++----- prevision.txt | 23 ---------- 8 files changed, 121 insertions(+), 49 deletions(-) create mode 100644 dashboard/templatetags/__init__.py create mode 100644 dashboard/templatetags/paginacion.py create mode 100644 dashboard/templatetags/range.py delete mode 100644 prevision.txt diff --git a/dashboard/mixins.py b/dashboard/mixins.py index c28dcf8..3ebac58 100644 --- a/dashboard/mixins.py +++ b/dashboard/mixins.py @@ -1,5 +1,5 @@ from django.urls import resolve -from django.shortcuts import get_object_or_404, redirect +from django.shortcuts import get_object_or_404, redirect, Http404 from django.utils.translation import gettext_lazy as _ from django.core.exceptions import PermissionDenied from django.contrib.auth.mixins import LoginRequiredMixin @@ -44,7 +44,6 @@ class DashboardView(LoginRequiredMixin): return context def get_session_devices(self): - # import pdb; pdb.set_trace() dev_ids = self.request.session.pop("devices", []) self._devices = [] @@ -82,3 +81,28 @@ class InventaryMixin(DashboardView, TemplateView): except Exception: pass return super().get(request, *args, **kwargs) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + limit = self.request.GET.get("limit", 10) + page = self.request.GET.get("page", 1) + if limit: + try: + limit = int(limit) + page = int(page) + except: + raise Http404 + + offset = (page - 1) * limit + devices, count = self.get_devices(self.request.user, offset, limit) + total_pages = (count + limit - 1) // limit + + context.update({ + 'devices': devices, + 'count': count, + "limit": limit, + "offset": offset, + "page": page, + "total_pages": total_pages, + }) + return context diff --git a/dashboard/templates/unassigned_devices.html b/dashboard/templates/unassigned_devices.html index c21a2be..cb8a42c 100644 --- a/dashboard/templates/unassigned_devices.html +++ b/dashboard/templates/unassigned_devices.html @@ -1,5 +1,7 @@ {% extends "base.html" %} {% load i18n %} +{% load paginacion %} + {% block content %}
@@ -55,4 +57,9 @@
+
+
+ {% render_pagination page total_pages %} +
+
{% endblock %} diff --git a/dashboard/templatetags/__init__.py b/dashboard/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dashboard/templatetags/paginacion.py b/dashboard/templatetags/paginacion.py new file mode 100644 index 0000000..7a50113 --- /dev/null +++ b/dashboard/templatetags/paginacion.py @@ -0,0 +1,19 @@ +from django import template + +register = template.Library() + +@register.inclusion_tag('pagination.html') +def render_pagination(page_number, total_pages): + """ + Template tag for render pagination + + Args: + - page_number: number of actual page + - total_pages: total pages. + + Use it template: {% render_pagination page_number total_pages %} + """ + return { + 'page_number': page_number, + 'total_pages': total_pages, + } diff --git a/dashboard/templatetags/range.py b/dashboard/templatetags/range.py new file mode 100644 index 0000000..7e4a724 --- /dev/null +++ b/dashboard/templatetags/range.py @@ -0,0 +1,23 @@ +from django import template + +register = template.Library() + + +@register.filter +def range_filter(value, page): + m = 11 + mind = page -1 - m // 2 + maxd = page + 1 + m // 2 + if mind < 0: + maxd += abs(mind) + if maxd > value: + mind -= abs(maxd-value-1) + total_pages = [x for x in range(1, value + 1) if maxd > x > mind] + + if value > m: + if total_pages[0] > 1: + total_pages = ["..."] + total_pages + if total_pages[-1] < value: + total_pages = total_pages + ["..."] + + return total_pages diff --git a/dashboard/views.py b/dashboard/views.py index 79b9346..5384cc4 100644 --- a/dashboard/views.py +++ b/dashboard/views.py @@ -1,4 +1,6 @@ from django.utils.translation import gettext_lazy as _ +from django.shortcuts import Http404 + from dashboard.mixins import InventaryMixin, DetailsMixin from device.models import Device from lot.models import Lot @@ -10,15 +12,8 @@ class UnassignedDevicesView(InventaryMixin): title = _("Unassigned Devices") breadcrumb = "Devices / Unassigned Devices" - def get_context_data(self, **kwargs): - context = super().get_context_data(**kwargs) - devices = Device.get_unassigned(self.request.user) - - context.update({ - 'devices': devices, - }) - - return context + def get_devices(self, user, offset, limit): + return Device.get_unassigned(self.request.user, offset, limit) class LotDashboardView(InventaryMixin, DetailsMixin): @@ -30,14 +25,12 @@ class LotDashboardView(InventaryMixin, DetailsMixin): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - devices = self.get_devices() lot = context.get('object') context.update({ - 'devices': devices, 'lot': lot, }) return context - def get_devices(self): + def get_devices(self, user, offset, limit): chids = self.object.devicelot_set.all().values_list("device_id", flat=True).distinct() - return [Device(id=x) for x in chids] + return [Device(id=x) for x in chids], chids.count() diff --git a/device/models.py b/device/models.py index f1b1ee7..6264130 100644 --- a/device/models.py +++ b/device/models.py @@ -1,4 +1,4 @@ -from django.db import models +from django.db import models, connection from utils.constants import STR_SM_SIZE, STR_SIZE, STR_EXTEND_SIZE, ALGOS from evidence.models import Annotation, Evidence @@ -113,17 +113,46 @@ class Device: self.lots = [x.lot for x in DeviceLot.objects.filter(device_id=self.id)] @classmethod - def get_unassigned(cls, user): - chids = DeviceLot.objects.filter(lot__owner=user).values_list("device_id", flat=True).distinct() - annotations = Annotation.objects.filter( - owner=user, - type=Annotation.Type.SYSTEM, - ).exclude(value__in=chids).values_list("value", flat=True).distinct() - return [cls(id=x) for x in annotations] + def get_unassigned(cls, user, offset=0, limit=None): - # return cls.objects.filter( - # owner=user - # ).annotate(num_lots=models.Count('lot')).filter(num_lots=0) + sql = """ + SELECT DISTINCT t1.value from evidence_annotation as t1 + left join lot_devicelot as t2 on t1.value = t2.device_id + where t2.device_id is null and owner_id=={user} and type=={type} + """.format( + user=user.id, + type=Annotation.Type.SYSTEM, + ) + if limit: + sql += " limit {} offset {}".format(int(limit), int(offset)) + + sql += ";" + + annotations = [] + with connection.cursor() as cursor: + cursor.execute(sql) + annotations = cursor.fetchall() + + devices = [cls(id=x[0]) for x in annotations] + count = cls.get_unassigned_count(user) + return devices, count + + + @classmethod + def get_unassigned_count(cls, user): + + sql = """ + SELECT count(DISTINCT t1.value) from evidence_annotation as t1 + left join lot_devicelot as t2 on t1.value = t2.device_id + where t2.device_id is null and owner_id=={user} and type=={type}; + """.format( + user=user.id, + type=Annotation.Type.SYSTEM, + ) + + with connection.cursor() as cursor: + cursor.execute(sql) + return cursor.fetchall()[0][0] @property def is_websnapshot(self): diff --git a/prevision.txt b/prevision.txt deleted file mode 100644 index b1ad84d..0000000 --- a/prevision.txt +++ /dev/null @@ -1,23 +0,0 @@ -4 login -8 device models -4 inventory template -4 upload snapshots -16 parse snapshots -16 build devices -8 action models -8 view actions -8 lot models -16 view lots -8 edit device -16 documents -8 tag -8 print label -4 server erase -4 profile -8 erase views -8 erase certificate -4 inventory snapshots -8 search -join split devices - -168 horas => 21 dias From 2b4b469b0e2452ed7a651b064d952c7d4325e27c Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 2 Oct 2024 12:27:20 +0200 Subject: [PATCH 2/3] fix pagination in lots --- dashboard/views.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dashboard/views.py b/dashboard/views.py index 5384cc4..6153675 100644 --- a/dashboard/views.py +++ b/dashboard/views.py @@ -33,4 +33,5 @@ class LotDashboardView(InventaryMixin, DetailsMixin): def get_devices(self, user, offset, limit): chids = self.object.devicelot_set.all().values_list("device_id", flat=True).distinct() - return [Device(id=x) for x in chids], chids.count() + chids_page = chids[offset:offset+limit] + return [Device(id=x) for x in chids_page], chids.count() From 2f17d01780937793f951af3faa68bd740f9eabb3 Mon Sep 17 00:00:00 2001 From: Cayo Puigdefabregas Date: Wed, 2 Oct 2024 12:51:40 +0200 Subject: [PATCH 3/3] fix pagination --- dashboard/mixins.py | 20 +++++---- dashboard/templates/pagination.html | 47 +++++++++++++++++++++ dashboard/templates/unassigned_devices.html | 4 +- dashboard/templatetags/paginacion.py | 3 +- lot/templates/list_lots.html | 2 +- 5 files changed, 64 insertions(+), 12 deletions(-) create mode 100644 dashboard/templates/pagination.html diff --git a/dashboard/mixins.py b/dashboard/mixins.py index 3ebac58..07004ee 100644 --- a/dashboard/mixins.py +++ b/dashboard/mixins.py @@ -84,14 +84,18 @@ class InventaryMixin(DashboardView, TemplateView): def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - limit = self.request.GET.get("limit", 10) - page = self.request.GET.get("page", 1) - if limit: - try: - limit = int(limit) - page = int(page) - except: - raise Http404 + limit = self.request.GET.get("limit") + page = self.request.GET.get("page") + try: + limit = int(limit) + page = int(page) + if page < 1: + page = 1 + if limit < 1: + limit = 10 + except: + limit = 10 + page = 1 offset = (page - 1) * limit devices, count = self.get_devices(self.request.user, offset, limit) diff --git a/dashboard/templates/pagination.html b/dashboard/templates/pagination.html new file mode 100644 index 0000000..7a20679 --- /dev/null +++ b/dashboard/templates/pagination.html @@ -0,0 +1,47 @@ +{% load i18n %} +{% load range %} + + diff --git a/dashboard/templates/unassigned_devices.html b/dashboard/templates/unassigned_devices.html index cb8a42c..6df36a7 100644 --- a/dashboard/templates/unassigned_devices.html +++ b/dashboard/templates/unassigned_devices.html @@ -54,12 +54,12 @@ {% endfor %} - +
- {% render_pagination page total_pages %} + {% render_pagination page total_pages limit %}
{% endblock %} diff --git a/dashboard/templatetags/paginacion.py b/dashboard/templatetags/paginacion.py index 7a50113..94ff5fc 100644 --- a/dashboard/templatetags/paginacion.py +++ b/dashboard/templatetags/paginacion.py @@ -3,7 +3,7 @@ from django import template register = template.Library() @register.inclusion_tag('pagination.html') -def render_pagination(page_number, total_pages): +def render_pagination(page_number, total_pages, limit=10): """ Template tag for render pagination @@ -16,4 +16,5 @@ def render_pagination(page_number, total_pages): return { 'page_number': page_number, 'total_pages': total_pages, + 'limit': limit } diff --git a/lot/templates/list_lots.html b/lot/templates/list_lots.html index d11fb3c..4024387 100644 --- a/lot/templates/list_lots.html +++ b/lot/templates/list_lots.html @@ -26,7 +26,7 @@ {% endfor %} {% endfor %} - + {% endblock %}