diff options
| -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: | 
