diff options
author | Étienne Loks <etienne.loks@proxience.com> | 2015-09-25 12:09:45 +0200 |
---|---|---|
committer | Étienne Loks <etienne.loks@proxience.com> | 2015-09-25 12:10:00 +0200 |
commit | 1f81bcd6625c7c411181c702a903781f3d3c7285 (patch) | |
tree | 469ab059c27a593b74224ad7a063a76ffce8d1b1 /ishtar_common/data_importer.py | |
parent | d23f19fe226ffe900c5f00c3deed65de2a5a47b1 (diff) | |
download | Ishtar-1f81bcd6625c7c411181c702a903781f3d3c7285.tar.bz2 Ishtar-1f81bcd6625c7c411181c702a903781f3d3c7285.zip |
Fix M2M imports - Import refactoring
Diffstat (limited to 'ishtar_common/data_importer.py')
-rw-r--r-- | ishtar_common/data_importer.py | 164 |
1 files changed, 85 insertions, 79 deletions
diff --git a/ishtar_common/data_importer.py b/ishtar_common/data_importer.py index 42dab251c..19746315a 100644 --- a/ishtar_common/data_importer.py +++ b/ishtar_common/data_importer.py @@ -868,91 +868,97 @@ class Importer(object): field_name, value, data, formater.force_value) c_row.append(u" ; ".join([v for v in c_values])) + def get_field(self, cls, attribute, data, m2ms, c_path): + field_object, model, direct, m2m = \ + cls._meta.get_field_by_name(attribute) + if m2m: + many_values = data.pop(attribute) + if hasattr(field_object, 'rel'): + model = field_object.rel.to + elif hasattr(field_object, 'to'): + model = field_object.to + elif hasattr(field_object, 'model'): + model = field_object.model + if type(many_values) not in (list, tuple): + many_values = [many_values] + for val in many_values: + if val.__class__ == model: + m2ms.append((attribute, val)) + elif val.__class__ != model and type(val) == dict: + vals = [] + + # contruct many dict for each values + default_dict = {} + # # init with simple values that will be duplicated + for key in val.keys(): + if type(val[key]) not in (list, tuple): + default_dict[key] = val[key] + vals.append(default_dict.copy()) + # # manage multiple values + for key in val.keys(): + if type(val[key]) in (list, tuple): + for idx, v in enumerate(val[key]): + if len(vals) <= idx: + vals.append(default_dict.copy()) + vals[idx][key] = v + + # check that m2m are not empty + notempty = False + for dct in vals: + for k in dct: + if dct[k] not in ("", None): + notempty = True + break + if not notempty: + continue + + field_names = model._meta.get_all_field_names() + for v in vals: + v['defaults'] = v.get('defaults', {}) + if 'history_modifier' in field_names: + v['defaults']['history_modifier'] = \ + self.history_modifier + m2m_m2ms = [] + c_c_path = c_path[:] + for k in v.keys(): + if k not in field_names: + continue + self.get_field(model, k, v, m2m_m2ms, c_c_path) + v, created = model.objects.get_or_create( + **v) + for att, objs in m2m_m2ms: + if type(objs) not in (list, tuple): + objs = [objs] + for obj in objs: + getattr(v, att).add(obj) + if self.import_instance \ + and hasattr(v, 'imports') and created: + v.imports.add(self.import_instance) + m2ms.append((attribute, v)) + elif hasattr(field_object, 'rel') and field_object.rel: + if type(data[attribute]) == dict: + c_path.append(attribute) + # put history_modifier for every created item + if 'history_modifier' in \ + field_object.rel.to._meta.get_all_field_names(): + data[attribute]['history_modifier'] = \ + self.history_modifier + data[attribute], created = self.get_object( + field_object.rel.to, data[attribute], c_path) + elif type(data[attribute]) == list: + data[attribute] = data[attribute][0] + def get_object(self, cls, data, path=[]): m2ms = [] if data and type(data) == dict: + c_path = path[:] for attribute in data.keys(): - c_path = path[:] + if not attribute: + data.pop(attribute) + continue if not data[attribute]: continue - field_object, model, direct, m2m = \ - cls._meta.get_field_by_name(attribute) - if m2m: - many_values = data.pop(attribute) - if hasattr(field_object, 'rel'): - model = field_object.rel.to - elif hasattr(field_object, 'to'): - model = field_object.to - elif hasattr(field_object, 'model'): - model = field_object.model - if type(many_values) not in (list, tuple): - many_values = [many_values] - for val in many_values: - if val.__class__ == model: - m2ms.append((attribute, val)) - elif val.__class__ != model and type(val) == dict: - vals = [] - - # contruct many dict for each values - default_dict = {} - # # init with simple values that will be duplicated - for key in val.keys(): - if type(val[key]) not in (list, tuple): - default_dict[key] = val[key] - vals.append(default_dict.copy()) - # # manage multiple values - for key in val.keys(): - if type(val[key]) in (list, tuple): - for idx, v in enumerate(val[key]): - if len(vals) <= idx: - vals.append(default_dict.copy()) - vals[idx][key] = v - - # check that m2m are not empty - notempty = False - for dct in vals: - for k in dct: - if dct[k] not in ("", None): - notempty = True - break - if not notempty: - continue - - field_names = model._meta.get_all_field_names() - for v in vals: - v['defaults'] = v.get('defaults', {}) - if 'history_modifier' in field_names: - v['defaults']['history_modifier'] = \ - self.history_modifier - m2m_m2ms = [] - for k in v.keys(): - if k not in field_names: - continue - field_object, m, direct, m2m = \ - model._meta.get_field_by_name(k) - if m2m: - m2m_m2ms.append((k, v.pop(k))) - v, created = model.objects.get_or_create( - **v) - for att, objs in m2m_m2ms: - if type(objs) not in (list, tuple): - objs = [objs] - for obj in objs: - getattr(v, att).add(obj) - if self.import_instance \ - and hasattr(v, 'imports') and created: - v.imports.add(self.import_instance) - m2ms.append((attribute, v)) - elif hasattr(field_object, 'rel') and field_object.rel and \ - type(data[attribute]) == dict: - c_path.append(attribute) - # put history_modifier for every created item - if 'history_modifier' in \ - field_object.rel.to._meta.get_all_field_names(): - data[attribute]['history_modifier'] = \ - self.history_modifier - data[attribute], created = self.get_object( - field_object.rel.to, data[attribute], c_path) + self.get_field(cls, attribute, data, m2ms, c_path) # default values path = tuple(path) if path in self._defaults: |