diff options
| author | Étienne Loks <etienne.loks@iggdrasil.net> | 2018-04-24 12:44:18 +0200 | 
|---|---|---|
| committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2018-06-12 08:43:58 +0200 | 
| commit | d083ce1b75dc70f1c69b5207e2606d33b1b0e9a3 (patch) | |
| tree | 17c2e17a835bde449b988b8725170e65f1ff235e /ishtar_common/wizards.py | |
| parent | 458174b3dc14a3a1bc8cc4f3bb10fccdd8dc824a (diff) | |
| download | Ishtar-d083ce1b75dc70f1c69b5207e2606d33b1b0e9a3.tar.bz2 Ishtar-d083ce1b75dc70f1c69b5207e2606d33b1b0e9a3.zip | |
Wizards: manage intermediary model for M2M relations
Diffstat (limited to 'ishtar_common/wizards.py')
| -rw-r--r-- | ishtar_common/wizards.py | 50 | 
1 files changed, 43 insertions, 7 deletions
| diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py index e47d5b48b..70f3caa19 100644 --- a/ishtar_common/wizards.py +++ b/ishtar_common/wizards.py @@ -525,7 +525,7 @@ class Wizard(NamedUrlWizardView):                          frm.cleaned_data.pop('DELETE')                      for key in frm.cleaned_data:                          value = frm.cleaned_data[key] -                        if value is None or value == '': +                        if value is None or value in ['', []]:                              continue                          if key in associated_models:                              value = associated_models[key].objects.get( @@ -736,6 +736,18 @@ class Wizard(NamedUrlWizardView):                      r.delete()          for key, value in m2m:              related_model = getattr(obj, key + 's') +            related_data = {}  # used for intermediary models + +            # an intermediary model is used +            if not related_model.through._meta.auto_created: +                for field in related_model.through._meta.get_fields(): +                    # is used for the obj or target +                    if getattr(field, 'related_model', None) and \ +                            (field.related_model == related_model.model or +                             isinstance(obj, field.related_model)): +                        continue +                    related_data[field.name] = None +              if key not in m2m_items:                  if type(key) == dict:                      vals = [] @@ -747,6 +759,7 @@ class Wizard(NamedUrlWizardView):                      m2m_items[key] = vals                  else:                      m2m_items[key] = related_model.all() +              if value not in m2m_items[key]:                  if type(value) == dict:                      model = related_model.model @@ -794,8 +807,7 @@ class Wizard(NamedUrlWizardView):                          # should be managed normally in forms but...                          fields = model._meta.get_fields() - -                        has_problemetic_null = False +                        has_problematic_null = False                          for field in fields:                              if (field.name not in value                                  or not value[field.name]) \ @@ -806,14 +818,19 @@ class Wizard(NamedUrlWizardView):                                  and (hasattr(field, 'default')                                       and (not field.default                                            or field.default == NOT_PROVIDED)): -                                    has_problemetic_null = True +                                    has_problematic_null = True                                      break -                        if has_problemetic_null: +                        if has_problematic_null:                              continue                          if hasattr(model, 'data') and 'data' not in value:                              value['data'] = {} +                        # remove intermediary model keys +                        for k in related_data.keys(): +                            if k in value: +                                related_data[k] = value.pop(k) +                          if get_or_create:                              value, created = model.objects.get_or_create(                                  **value) @@ -821,11 +838,30 @@ class Wizard(NamedUrlWizardView):                              value = model.objects.create(**value)                          value.save()  # force post_save                  # check that an item is not add multiple times (forged forms) -                if value not in related_model.all() and\ +                if value not in related_model.all() and \                          (not hasattr(related_model, 'through') or                           not isinstance(value, related_model.through)):                      # many to many and the value have been already managed -                    related_model.add(value) + +                    # an intermediary model is used +                    if not related_model.through._meta.auto_created: +                        for field in related_model.through._meta.get_fields(): +                            if hasattr(field, 'related_model') \ +                                    and field.related_model: +                                # assume that one foreign key is used for obj +                                # table and value table - more complex schema +                                # are not managed +                                if isinstance(value, +                                              field.related_model): +                                    related_data[field.name] = value +                                elif isinstance(obj, +                                                field.related_model): +                                    related_data[field.name] = obj +                        related_model.through.objects.create( +                            **related_data +                        ) +                    else: +                        related_model.add(value)                      # necessary to manage interaction between models like                      # material_index management for baseitems                      obj._cached_label_checked = False | 
