diff options
| author | Étienne Loks <etienne.loks@iggdrasil.net> | 2026-02-04 15:13:56 +0100 |
|---|---|---|
| committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2026-02-04 16:54:00 +0100 |
| commit | 48f9e3d7b4d325e454ea8b0cb51a074dd6ba6fe0 (patch) | |
| tree | 1032be5dca7239c2decede5397dd8cebf2867096 /ishtar_common | |
| parent | ceb2af2f33d6d8c120bbd8e140821b0a1c671113 (diff) | |
| download | Ishtar-48f9e3d7b4d325e454ea8b0cb51a074dd6ba6fe0.tar.bz2 Ishtar-48f9e3d7b4d325e454ea8b0cb51a074dd6ba6fe0.zip | |
🐛 JSON fields - base finds: manage base finds JSON fields in edit forms
Diffstat (limited to 'ishtar_common')
| -rw-r--r-- | ishtar_common/forms.py | 7 | ||||
| -rw-r--r-- | ishtar_common/models.py | 43 | ||||
| -rw-r--r-- | ishtar_common/wizards.py | 155 |
3 files changed, 119 insertions, 86 deletions
diff --git a/ishtar_common/forms.py b/ishtar_common/forms.py index 899cdc6d1..9558186bb 100644 --- a/ishtar_common/forms.py +++ b/ishtar_common/forms.py @@ -368,9 +368,14 @@ class CustomForm(BSForm): "json_field__key", "json_field__value_type", "json_field__name", + "json_field__content_type__model", ).order_by("order") for field in q.all(): - key = "data__" + field["json_field__key"] + key = "data__" + # base find used in find form -> clearly identify them + if field["json_field__content_type__model"] == "basefind": + key = "get_first_base_find__" + key + key += field["json_field__key"] field_cls, widget = forms.CharField, None if field["json_field__value_type"] in JSON_VALUE_TYPES_FIELDS: field_cls, widget = JSON_VALUE_TYPES_FIELDS[ diff --git a/ishtar_common/models.py b/ishtar_common/models.py index 2a8e9fdad..5e8107d17 100644 --- a/ishtar_common/models.py +++ b/ishtar_common/models.py @@ -1781,23 +1781,24 @@ class CustomForm(models.Model): ADMIN_SECTION = _("Custom data / custom forms") MODELS = { - "contextrecord": ("archaeological_context_records", "contextrecord"), - "file": ("archaeological_files", "contextrecord"), - "adminact": ("archaeological_operations", "administrativeact"), - "operation": ("archaeological_operations", "operation"), - "archaeological_site": ("archaeological_operations", "archaeologicalsite"), - "find": ("archaeological_finds", "find"), - "findbasket": ("archaeological_finds", "findbasket"), - "treatment": ("archaeological_finds", "treatment"), - "treatmentfile": ("archaeological_finds", "treatmentfile"), - "exhibition": ("archaeological_finds", "exhibition"), - "warehouse": ("archaeological_warehouse", "warehouse"), - "container": ("archaeological_warehouse", "container"), - "person": ("ishtar_common", "person"), - "organization": ("ishtar_common", "organization"), - "biographicalnote": ("ishtar_common", "biographicalnote"), - "document": ("ishtar_common", "document"), - "geoitem": ("ishtar_common", "geovectordata"), + "contextrecord": (("archaeological_context_records", "contextrecord"),), + "file": (("archaeological_files", "contextrecord"),), + "adminact": (("archaeological_operations", "administrativeact"),), + "operation": (("archaeological_operations", "operation"),), + "archaeological_site": (("archaeological_operations", "archaeologicalsite"),), + "find": (("archaeological_finds", "find"), + ("archaeological_finds", "basefind")), + "findbasket": (("archaeological_finds", "findbasket"),), + "treatment": (("archaeological_finds", "treatment"),), + "treatmentfile": (("archaeological_finds", "treatmentfile"),), + "exhibition": (("archaeological_finds", "exhibition"),), + "warehouse": (("archaeological_warehouse", "warehouse"),), + "container": (("archaeological_warehouse", "container"),), + "person": (("ishtar_common", "person"),), + "organization": (("ishtar_common", "organization"),), + "biographicalnote": (("ishtar_common", "biographicalnote"),), + "document": (("ishtar_common", "document"),), + "geoitem": (("ishtar_common", "geovectordata"),), } def natural_key(self): @@ -1870,10 +1871,10 @@ class CustomForm(models.Model): model_name = self.form.split("-")[0] content_types = [] if model_name in self.MODELS: - app_name, model_name = self.MODELS[model_name] - q = ContentType.objects.filter(app_label=app_name, model=model_name) - if q.count(): - content_types.append(q.all()[0]) + for app_name, model_name in self.MODELS[model_name]: + q = ContentType.objects.filter(app_label=app_name, model=model_name) + if q.count(): + content_types.append(q.all()[0]) if not content_types: register, register_fields = self.register() if self.form not in self._register: diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py index 4fb1222c3..5e23d469a 100644 --- a/ishtar_common/wizards.py +++ b/ishtar_common/wizards.py @@ -687,19 +687,29 @@ class Wizard(IshtarWizard): dct = self.get_extra_model(dct, m2m, form_list) obj = self.get_current_saved_object() data = {} + base_find_data = {} if obj and hasattr(obj, "data"): data = obj.data - + if obj and hasattr(obj, "get_first_base_find"): + bf = obj.get_first_base_find() + if bf: + base_find_data = bf.data # manage dependant items and json fields other_objs = {} for k in list(dct.keys()): if "__" not in k: continue + vals = k.split("__") # manage json field - if k.startswith("data__"): - data_keys = k[len("data__") :].split("__") + if "data" in vals: + data_keys = vals[vals.index("data") + 1:] # tree - current_data = data + if vals[0] == "get_first_base_find": + if "get_first_base_find" not in other_objs: + other_objs["get_first_base_find"] = {} + current_data = base_find_data + else: + current_data = data for data_key in data_keys[:-1]: if data_key not in current_data: current_data[data_key] = {} @@ -714,13 +724,14 @@ class Wizard(IshtarWizard): current_data[data_keys[-1]] = value continue - vals = k.split("__") if len(vals) != 2: raise NotImplementedError("Only one level of dependant item is managed") dependant_item, key = vals if dependant_item not in other_objs: other_objs[dependant_item] = {} other_objs[dependant_item][key] = dct.pop(k) + if "get_first_base_find" in other_objs and base_find_data: + other_objs["get_first_base_find"]["data"] = base_find_data if obj: for k in list(dct.keys()): if k.startswith("pk"): @@ -1517,6 +1528,78 @@ class Wizard(IshtarWizard): obj_name = prefixes[-2] return obj_name + def __instanced_json_data(self, initial, c_form, obj): + """ + Get initial data for JSON fields + """ + for key in self.json_fields[c_form.form_slug]: + data_key = "data__" + current_obj = obj + if not key.startswith("data__"): + if not key.startswith("get_first_base_find__data__") \ + or not hasattr(obj, "get_first_base_find"): + continue + data_key = "get_first_base_find__data__" + current_obj = obj.get_first_base_find() + if not current_obj: + continue + json_keys = key[len(data_key):].split("__") + value = current_obj.data + for json_key in json_keys: + if json_key not in value: + value = None + break + value = value[json_key] + if value: + initial[key] = value + elif value is False: + initial[key] = "False" + + def __instanced_data(self, initial, c_form, obj, base_field): + """ + Get initial data for standard fields + """ + value = obj + base_model = None + if (hasattr(c_form, "base_model") and base_field == c_form.base_model) or ( + hasattr(c_form, "base_models") and base_field in c_form.base_models): + base_model = base_field + try: + getattr(obj, base_model + "s") + key = base_model + "s" + except AttributeError: + getattr(obj, base_model) + key = base_model + initial.setlist( + base_field, [str(val.pk) for val in getattr(value, key).all()] + ) + else: + fields = base_field.split("__") + for field in fields: + if callable(value): + value = value() + if not hasattr(value, field) or getattr(value, field) is None: + value = obj + break + value = getattr(value, field) + if hasattr(value, "all") and callable(value.all): + if not value.count(): + return + initial.setlist(base_field, [str(v.pk) for v in value.all()]) + return + if value == obj: + return + if hasattr(value, "pk"): + value = value.pk + if ( + value in (True, False) + or isinstance(value, ImageFieldFile) + or isinstance(value, FileField) + ): + initial[base_field] = value + elif value is not None: + initial[base_field] = str(value) + def _get_instanced_init_for_form(self, obj, c_form): """ Get initial data from an object: simple form @@ -1525,71 +1608,15 @@ class Wizard(IshtarWizard): # manage json field if ( - hasattr(obj, "data") - and obj.data + getattr(obj, "data", None) and hasattr(self, "json_fields") and getattr(c_form, "form_slug", None) and c_form.form_slug in self.json_fields - and obj.data ): - for key in self.json_fields[c_form.form_slug]: - if not key.startswith("data__"): - continue - json_keys = key[len("data__") :].split("__") - value = obj.data - for json_key in json_keys: - if json_key not in value: - value = None - break - value = value[json_key] - if value: - initial[key] = value - elif value is False: - initial[key] = "False" + self.__instanced_json_data(initial, c_form, obj) for base_field in c_form.base_fields.keys(): - value = obj - base_model = None - if hasattr(c_form, "base_model") and base_field == c_form.base_model: - base_model = base_field - if hasattr(c_form, "base_models") and base_field in c_form.base_models: - base_model = base_field - if base_model: - try: - __ = getattr(obj, base_model + "s") - key = base_model + "s" - except AttributeError: - __ = getattr(obj, base_model) - key = base_model - initial.setlist( - base_field, [str(val.pk) for val in getattr(value, key).all()] - ) - else: - fields = base_field.split("__") - for field in fields: - if callable(value): - value = value() - if not hasattr(value, field) or getattr(value, field) is None: - value = obj - break - value = getattr(value, field) - if hasattr(value, "all") and callable(value.all): - if not value.count(): - continue - initial.setlist(base_field, [str(v.pk) for v in value.all()]) - continue - if value == obj: - continue - if hasattr(value, "pk"): - value = value.pk - if ( - value in (True, False) - or isinstance(value, ImageFieldFile) - or isinstance(value, FileField) - ): - initial[base_field] = value - elif value is not None: - initial[base_field] = str(value) + self.__instanced_data(initial, c_form, obj, base_field) return initial @staticmethod |
