summaryrefslogtreecommitdiff
path: root/ishtar_common
diff options
context:
space:
mode:
Diffstat (limited to 'ishtar_common')
-rw-r--r--ishtar_common/admin.py8
-rw-r--r--ishtar_common/models.py4
-rw-r--r--ishtar_common/models_common.py31
-rw-r--r--ishtar_common/models_imports.py35
-rw-r--r--ishtar_common/templates/ishtar/blocks/sheet_relations.html22
-rw-r--r--ishtar_common/tests.py2
-rw-r--r--ishtar_common/version.py4
-rw-r--r--ishtar_common/views.py6
-rw-r--r--ishtar_common/views_item.py16
9 files changed, 88 insertions, 40 deletions
diff --git a/ishtar_common/admin.py b/ishtar_common/admin.py
index 8f9d4d0a9..691525c10 100644
--- a/ishtar_common/admin.py
+++ b/ishtar_common/admin.py
@@ -1135,7 +1135,7 @@ class ImportActionAdmin(admin.ModelAdmin):
def get_urls(self):
urls = super(ImportActionAdmin, self).get_urls()
my_urls = [
- re_path(r"^import-from-csv/$", self.import_generic),
+ re_path(r"^import-from-csv/$", self.admin_site.admin_view(self.import_generic)),
]
return my_urls + urls
@@ -1293,7 +1293,7 @@ class ImportGEOJSONActionAdmin(object):
def get_urls(self):
urls = super(ImportGEOJSONActionAdmin, self).get_urls()
my_urls = [
- re_path(r"^import-from-geojson/$", self.import_geojson),
+ re_path(r"^import-from-geojson/$", self.admin_site.admin_view(self.import_geojson)),
]
return my_urls + urls
@@ -1519,7 +1519,7 @@ class ImportJSONActionAdmin(admin.ModelAdmin):
def get_urls(self):
urls = super(ImportJSONActionAdmin, self).get_urls()
my_urls = [
- re_path(r"^import-from-json/$", self.import_json),
+ re_path(r"^import-from-json/$", self.admin_site.admin_view(self.import_json)),
]
return my_urls + urls
@@ -1788,7 +1788,7 @@ class CreateDepartmentActionAdmin(GeneralTypeAdmin):
def get_urls(self):
urls = super(CreateDepartmentActionAdmin, self).get_urls()
my_urls = [
- re_path(r"^create-department/$", self.create_area),
+ re_path(r"^create-department/$", self.admin_site.admin_view(self.create_area)),
]
return my_urls + urls
diff --git a/ishtar_common/models.py b/ishtar_common/models.py
index 5b06baba2..0d9155aef 100644
--- a/ishtar_common/models.py
+++ b/ishtar_common/models.py
@@ -887,6 +887,9 @@ class GeneralRecordRelations(Imported):
class Meta:
abstract = True
+ def __str__(self):
+ return f"{self.left_record} - {self.relation_type} - {self.right_record}"
+
@classmethod
def general_types(cls):
return ["relation_type"]
@@ -5544,6 +5547,7 @@ class Document(
def set_main_image(self, __, value):
"""
Post importer action - set the imported image as a main image for associated "value" items
+ For instance: use "finds" to set this image as main for associated finds
"""
for item in getattr(self, value).all():
item.main_image = self
diff --git a/ishtar_common/models_common.py b/ishtar_common/models_common.py
index 0161aadad..4b0f1b160 100644
--- a/ishtar_common/models_common.py
+++ b/ishtar_common/models_common.py
@@ -803,14 +803,29 @@ class HierarchicalType(GeneralType):
has_full_label = True
def full_label(self):
- lbls = [self.label]
- item = self
- parents = [self.pk] # prevent loop
- while item.parent and item.parent_id not in parents:
- parents.append(item.parent_id)
- item = item.parent
- lbls.append(item.label)
- return " > ".join(reversed(lbls))
+ return " > ".join(reversed(self.get_label_hierarchy()))
+
+ def _get_label_hierarchy(self, labels, pk, parents):
+ if not pk or pk in parents:
+ return labels
+ parents.add(pk)
+ q = self.__class__.objects.filter(pk=pk)
+ label, parent_id = q.values_list("label", "parent_id").all()[0]
+ labels.append(label)
+ self._get_label_hierarchy(labels, parent_id, parents)
+ return labels
+
+ def get_label_hierarchy(self, lower=False):
+ """
+ Get every upward labels of the hierarchy for full label or
+ cached hierarchical search.
+ Returned in reversed order.
+ """
+ parents = set((self.pk,)) # prevent loop
+ result = self._get_label_hierarchy([self.label], self.parent_id, parents)
+ if lower:
+ result = list(map(str.lower, result))
+ return result
@property
def first_parent(self):
diff --git a/ishtar_common/models_imports.py b/ishtar_common/models_imports.py
index 478bb5e1c..26516cb7f 100644
--- a/ishtar_common/models_imports.py
+++ b/ishtar_common/models_imports.py
@@ -1748,6 +1748,23 @@ class BaseImport(models.Model, OwnPerms, SheetItem):
def pre_import_form_is_valid(self) -> bool:
raise NotImplemented()
+ def start_import(self, request=None):
+ if settings.USE_BACKGROUND_TASK:
+ self.delayed_importation(request)
+ return
+ try:
+ self.importation()
+ except ImporterError as e:
+ self.state = "FE"
+ self.end_date = timezone.now()
+ self.save()
+ if request:
+ put_session_message(
+ request.session.session_key,
+ f"{self} - {e}",
+ "warning",
+ )
+
def _archive(self):
raise NotImplemented()
@@ -3077,24 +3094,6 @@ class Import(BaseImport):
continue
ImportLineError.objects.get_or_create(import_item=self, line=idx)
- def start_import(self, request=None):
- if settings.USE_BACKGROUND_TASK:
- self.delayed_importation(request)
- return
- try:
- self.importation()
- except ImporterError as e:
- self.state = "FE"
- self.end_date = timezone.now()
- self.save()
- if request:
- put_session_message(
- request.session.session_key,
- f"{self} - {e}",
- "warning",
- )
-
-
def save(self, *args, **kwargs):
maj_imported_file = False
if getattr(self, "_maj_imported_file", False):
diff --git a/ishtar_common/templates/ishtar/blocks/sheet_relations.html b/ishtar_common/templates/ishtar/blocks/sheet_relations.html
new file mode 100644
index 000000000..e18cb5532
--- /dev/null
+++ b/ishtar_common/templates/ishtar/blocks/sheet_relations.html
@@ -0,0 +1,22 @@
+{% load i18n l10n %}
+ {% if display_relations %}
+ <h3>{% trans "Relations"%}</h3>
+ {% for rel in item.right_relations.all %}
+ {% ifchanged rel.relation_type %}
+ {% if forloop.counter0 %}</div>{% endif %}
+ <h4>{{rel.relation_type}}</h4>
+ <div class="row">{% endifchanged %}
+ <div class="col-12">
+ <a href="#" onclick="load_window('{{relation_url}}{{rel.right_record.pk|unlocalize}}/');" class="display_details">
+ <i class="fa fa-info-circle" aria-hidden="true"></i>
+ </a> {{rel.right_record}}
+ </div>
+ {% if forloop.last %}
+ </div>{% endif %}
+ {% endfor %}
+ {% else %}
+ <div class="alert alert-info" role="alert">
+ <i class="fa fa-info-circle" aria-hidden="true"></i> &nbsp;
+ {% trans "No relations" %}
+ </div>
+ {% endif %}
diff --git a/ishtar_common/tests.py b/ishtar_common/tests.py
index 022783f64..b4f3cd930 100644
--- a/ishtar_common/tests.py
+++ b/ishtar_common/tests.py
@@ -3282,7 +3282,7 @@ class ImportTest(BaseImportTest):
def test_archive_group_import(self):
group_import = self.create_group_import()
- group_import.importation()
+ group_import.start_import()
profile = models.get_current_profile()
profile.delete_image_zip_on_archive = False
profile.save()
diff --git a/ishtar_common/version.py b/ishtar_common/version.py
index 5b4be93c8..1cc6bafef 100644
--- a/ishtar_common/version.py
+++ b/ishtar_common/version.py
@@ -1,5 +1,5 @@
-# 4.99.26
-VERSION = (4, 99, 26)
+# 4.99.29
+VERSION = (4, 99, 29)
def get_version():
diff --git a/ishtar_common/views.py b/ishtar_common/views.py
index 4f37a0938..1599c071f 100644
--- a/ishtar_common/views.py
+++ b/ishtar_common/views.py
@@ -526,6 +526,7 @@ def get_autocomplete_generic(model, extra=None):
nb = 0
objects = []
has_parent = hasattr(model, "parent")
+ query_exact = None
if not q:
q = ""
else:
@@ -547,8 +548,11 @@ def get_autocomplete_generic(model, extra=None):
sort = ["label"]
if has_parent:
sort = ["parent__label", "label"]
+ query = model.objects.filter(query)
+ if query_exact and objects:
+ query = query.exclude(pk__in=list(query_exact.values_list("pk", flat=True)))
objects += list(
- model.objects.filter(query).order_by(*sort).distinct()[:limit]
+ query.order_by(*sort).distinct()[:limit]
)
get_label = lambda x: x.full_label() if hasattr(x, "full_label") else str(x)
data = json.dumps([{"id": obj.pk, "value": get_label(obj)} for obj in objects])
diff --git a/ishtar_common/views_item.py b/ishtar_common/views_item.py
index 878d5361e..11d7a5345 100644
--- a/ishtar_common/views_item.py
+++ b/ishtar_common/views_item.py
@@ -41,6 +41,7 @@ from django.db.models import (
F,
Q,
Count,
+ Subquery,
Sum,
ImageField,
ExpressionWrapper,
@@ -2542,6 +2543,8 @@ def get_item(
copy(relation_types_prefix) if relation_types_prefix else {}
)
+ # n_start = datetime.datetime.now()
+
geo_import_key = dct.get("geo_import_key", None)
geo_type = dct.get("geo_type", None)
@@ -2885,11 +2888,11 @@ def get_item(
if split_type == "OR":
items |= sub_items
else:
- # in Django m2m queries use the same JOIN...
+ # in Django m2m queries use the same JOIN
# items &= sub_items do not work
- items &= model.objects.filter(Q(
- pk__in=list(sub_items.values_list("pk", flat=True))
- ))
+ items &= model.objects.filter(
+ id__in=Subquery(sub_items.values("id"))
+ )
if return_query:
return items
@@ -2916,7 +2919,8 @@ def get_item(
search_vector = request_items.get("search_vector", "").strip()
# cache only for GUI search
- cache_search = search_vector or "submited" in request_items
+ cache_search = search_vector or any(
+ 1 for k in request_items if k.startswith("columns["))
q_cached_count = None
if cache_search:
q_cached_count_attrs = {
@@ -2962,7 +2966,6 @@ def get_item(
stats_modality_2,
multiply=multiply,
)
-
table_cols = [col if col != [] else '' for col in table_cols]
query_table_cols = []
for idx, cols in enumerate(table_cols):
@@ -3282,6 +3285,7 @@ def get_item(
else:
new_rows[idx] = row
rows = [row for __, row in new_rows.items()]
+ # print("full", datetime.datetime.now() - n_start)
if full == "shortcut":
data = json.dumps(rows)
else: