diff options
Diffstat (limited to 'ishtar_common')
| -rw-r--r-- | ishtar_common/admin.py | 8 | ||||
| -rw-r--r-- | ishtar_common/models.py | 4 | ||||
| -rw-r--r-- | ishtar_common/models_common.py | 31 | ||||
| -rw-r--r-- | ishtar_common/models_imports.py | 35 | ||||
| -rw-r--r-- | ishtar_common/templates/ishtar/blocks/sheet_relations.html | 22 | ||||
| -rw-r--r-- | ishtar_common/tests.py | 2 | ||||
| -rw-r--r-- | ishtar_common/version.py | 4 | ||||
| -rw-r--r-- | ishtar_common/views.py | 6 | ||||
| -rw-r--r-- | ishtar_common/views_item.py | 16 |
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> + {% 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: |
