summaryrefslogtreecommitdiff
path: root/ishtar_common
diff options
context:
space:
mode:
Diffstat (limited to 'ishtar_common')
-rw-r--r--ishtar_common/migrations/0273_searchcache.py31
-rw-r--r--ishtar_common/models.py14
-rw-r--r--ishtar_common/models_common.py6
-rw-r--r--ishtar_common/views_item.py38
4 files changed, 83 insertions, 6 deletions
diff --git a/ishtar_common/migrations/0273_searchcache.py b/ishtar_common/migrations/0273_searchcache.py
new file mode 100644
index 000000000..00b2f1fb1
--- /dev/null
+++ b/ishtar_common/migrations/0273_searchcache.py
@@ -0,0 +1,31 @@
+# Generated by Django 4.2.19 on 2026-03-17 16:02
+
+from django.db import migrations, models
+import django.db.models.deletion
+import django.utils.timezone
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('contenttypes', '0002_remove_content_type_name'),
+ ('ishtar_common', '0272_ishtarsiteprofile_statementcondition'),
+ ]
+
+ operations = [
+ migrations.CreateModel(
+ name='SearchCache',
+ fields=[
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+ ('query', models.TextField(blank=True, default='', verbose_name='Query')),
+ ('count', models.IntegerField(verbose_name='Count')),
+ ('updated', models.DateTimeField(default=django.utils.timezone.now)),
+ ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.contenttype')),
+ ('ishtar_user', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='ishtar_common.ishtaruser')),
+ ],
+ options={
+ 'verbose_name': 'Cache - Search count',
+ 'verbose_name_plural': 'Cache - Search counts',
+ },
+ ),
+ ]
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index b9c00e1cd..65dddc051 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -95,7 +95,6 @@ from ishtar_common.utils import (
task,
generate_pdf_preview,
revoke_old_task,
- InlineClass
)
from ishtar_common.utils_secretary import IshtarSecretaryRenderer
from ishtar_common.views_item import get_item
@@ -2183,6 +2182,19 @@ class Dashboard(object):
return v
+class SearchCache(models.Model):
+ content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
+ query = models.TextField(_("Query"), default="", blank=True)
+ ishtar_user = models.ForeignKey("IshtarUser", blank=True, null=True,
+ on_delete=models.CASCADE)
+ count = models.IntegerField(_("Count"))
+ updated = models.DateTimeField(default=timezone.now)
+
+ class Meta:
+ verbose_name = _("Cache - Search count")
+ verbose_name_plural = _("Cache - Search counts")
+
+
EXPORT_FORMATS = [("", "---")]
EXPORT_FORMATS_CONTENT_TYPE = {
"xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
diff --git a/ishtar_common/models_common.py b/ishtar_common/models_common.py
index c90ca7309..a2708945f 100644
--- a/ishtar_common/models_common.py
+++ b/ishtar_common/models_common.py
@@ -5145,6 +5145,12 @@ class IdentifierItem(models.Model):
super().save(*args, **kwargs)
self.regenerate_all_ids()
+ # search cache clean
+ SearchCache = apps.get_model("ishtar_common", "SearchCache")
+ SearchCache.objects.filter(
+ content_type=ContentType.objects.get_for_model(self.__class__)
+ ).delete()
+
def regenerate_all_ids(self, save=True):
if getattr(self, "_prevent_loop", False):
return {}
diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py
index 82eb4c7a8..18e3f5576 100644
--- a/ishtar_common/views_item.py
+++ b/ishtar_common/views_item.py
@@ -2908,13 +2908,41 @@ def get_item(
if col.startswith(k):
count_values.append(v)
break
- try:
- q = items.values(*count_values)
- items_nb = q.count() or 0
- except ProgrammingError:
- items_nb = 0
+
+ # count in cache
+ n = datetime.datetime.now()
+
+ search_vector = request_items.get("search_vector", "").strip()
+
+ # cache only for GUI search
+ cache_search = search_vector or "submited" in request_items
+ q_cached_count = None
+ if cache_search:
+ q_cached_count_attrs = {
+ "content_type": ContentType.objects.get_for_model(model),
+ "query": search_vector,
+ "updated__gt": timezone.now() - datetime.timedelta(hours=24)
+ }
+ if own:
+ q_cached_count_attrs["ishtar_user_id"] = ishtaruser.user_ptr_id
+ SearchCache = apps.get_model("ishtar_common", "SearchCache")
+ q_cached_count = SearchCache.objects.filter(**q_cached_count_attrs)
+ if cache_search and q_cached_count.exists():
+ items_nb = q_cached_count.all()[0].count
+ else:
+ try:
+ q = items.values(*count_values)
+ items_nb = q.count() or 0
+ except ProgrammingError:
+ items_nb = 0
+ if cache_search:
+ q_cached_count_attrs.pop("updated__gt")
+ q_cached_count_attrs["count"] = items_nb
+ SearchCache.objects.create(**q_cached_count_attrs)
+
if count:
return items_nb
+
# print(str(items.values("id").query))
if data_type == "json-stats":