summaryrefslogtreecommitdiff
path: root/ishtar_common/models_imports.py
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@iggdrasil.net>2023-09-15 18:46:41 +0200
committerÉtienne Loks <etienne.loks@iggdrasil.net>2024-04-16 16:38:32 +0200
commit5ec78fa85dbb6b7ec7d286827b6e32f82c489b3e (patch)
treef4f98c3ef9923df42ff579fbc9b71c807f26716e /ishtar_common/models_imports.py
parentb1c4e814bdb7ded9314b8d5337fa5841c737d32d (diff)
downloadIshtar-5ec78fa85dbb6b7ec7d286827b6e32f82c489b3e.tar.bz2
Ishtar-5ec78fa85dbb6b7ec7d286827b6e32f82c489b3e.zip
♻️ refactoring and optimisation: manage defaults like pre_importer_values - add an explicit field for required value to apply defaults
Diffstat (limited to 'ishtar_common/models_imports.py')
-rw-r--r--ishtar_common/models_imports.py77
1 files changed, 63 insertions, 14 deletions
diff --git a/ishtar_common/models_imports.py b/ishtar_common/models_imports.py
index c03dd208b..85b859a5d 100644
--- a/ishtar_common/models_imports.py
+++ b/ishtar_common/models_imports.py
@@ -288,14 +288,23 @@ class ImporterType(models.Model):
uno.save_calc(calc, dest_filename)
return dest_filename
+ def get_default_values(self) -> list:
+ """
+ Get list of 2-tuple to manage default values.
+ The first item is a tuple of mandatory fields for the values to be relevant. Empty if the
+ default values always applies.
+ The second item is the dict of default values.
+ """
+ return [(default.mandatory_keys, default.values) for default in self.defaults.all()]
+
def get_importer_class(self, import_instance=None):
- OBJECT_CLS = import_class(self.associated_models.klass)
- DEFAULTS = dict(
- [(default.keys, default.values) for default in self.defaults.all()]
- )
- PRE_IMPORT_VALUES = {}
+ object_cls = import_class(self.associated_models.klass)
+ pre_import_values = {}
if import_instance:
- PRE_IMPORT_VALUES = import_instance.pre_import_values
+ pre_import_values = import_instance.pre_import_values
+ defaults = import_instance.default_values
+ else:
+ defaults = self.get_default_values()
LINE_FORMAT = []
LINE_EXPORT_FORMAT = []
idx = 0
@@ -356,10 +365,10 @@ class ImporterType(models.Model):
for modls in self.created_models.all():
MODEL_CREATION_LIMIT.append(import_class(modls.klass))
args = {
- "OBJECT_CLS": OBJECT_CLS,
+ "OBJECT_CLS": object_cls,
"DESC": self.description,
- "DEFAULTS": DEFAULTS,
- "PRE_IMPORT_VALUES": PRE_IMPORT_VALUES,
+ "DEFAULTS": defaults,
+ "PRE_IMPORT_VALUES": pre_import_values,
"LINE_FORMAT": LINE_FORMAT,
"UNICITY_KEYS": UNICITY_KEYS,
"LINE_EXPORT_FORMAT": LINE_EXPORT_FORMAT,
@@ -502,7 +511,19 @@ class ImporterDefault(models.Model):
importer_type = models.ForeignKey(
ImporterType, related_name="defaults", on_delete=models.CASCADE
)
- target = models.CharField("Target", max_length=500)
+ target = models.CharField(
+ _("Target"), max_length=500,
+ help_text=_('The target of the default values. Can be set to empty with "-". '
+ 'Use the "__" notation to pass between models.')
+ )
+ required_fields = models.CharField(
+ _("Required fields"), max_length=500, blank=True, default="",
+ help_text=_(
+ "Theses defaults values only apply if the designated fields are not empty. "
+ 'Use the "__" notation to pass between models.'
+ "Leave empty to always apply."
+ )
+ )
class Meta:
verbose_name = _("Importer - Default")
@@ -531,13 +552,23 @@ class ImporterDefault(models.Model):
)
@property
+ def mandatory_keys(self):
+ return tuple(k for k in self.required_fields.split("__") if k)
+
+ @property
def values(self):
values = {}
for default_value in self.default_values.all():
+ targets = list(self.keys)
target = default_value.target
- if target == "-":
- target = ""
- values[target.split("__")[0]] = default_value.get_value()
+ if target != "-":
+ targets += target.split("__")
+ value = default_value.value
+ # explicit key or id is not set - try to get the value
+ if targets[-1] not in ("srid", "txt_idx", "slug", "id", "pk"):
+ value = default_value.get_value()
+ dct = generate_dict_from_list(targets, value)
+ values = update_data(values, dct)
return values
@@ -602,7 +633,7 @@ class ImporterDefaultValues(models.Model):
if target not in fields:
return
field = fields[target]
- if target in ("srid", "txt_idx"):
+ if target in ("srid", "txt_idx", "slug"):
try:
return parent_model.objects.get(**{target: self.value})
except (ValueError, parent_model.DoesNotExist):
@@ -1639,6 +1670,17 @@ class Import(BaseImport):
return errors
@property
+ def default_values(self) -> dict:
+ """
+ Get DB default values for this importer. Cached in memory.
+ :return: defaults values as a dict
+ """
+ if hasattr(self, "_default_values"):
+ return self._default_values
+ self._default_values = self.importer_type.get_default_values()
+ return self._default_values
+
+ @property
def has_pre_import_form(self) -> bool:
"""
Check if a pre-import form is available
@@ -1655,6 +1697,12 @@ class Import(BaseImport):
@property
def pre_import_values(self) -> dict:
+ """
+ Get DB pre import values for this importer. Cached in memory.
+ :return: pre import as a dict
+ """
+ if hasattr(self, "_pre_import_values"):
+ return self._pre_import_values
values = {}
for column in self.importer_type.columns.filter(col_number__lte=0):
q = ImportColumnValue.objects.filter(column=column, import_item=self)
@@ -1697,6 +1745,7 @@ class Import(BaseImport):
keys = dup.field_name.split("__")
dct = generate_dict_from_list(keys, value)
values = update_data(values, dct)
+ self._pre_import_values = values
return values
def get_number_of_lines(self):