Commits

Kevin Barnes committed b7c2ade

Adding support for index_together

Comments (0)

Files changed (2)

south/creator/changes.py

                                 "model": self.old_orm[key],
                                 "fields": [self.old_orm[key]._meta.get_field_by_name(x)[0] for x in fields],
                             })
+                    # And any other indexes it had
+                    index_together = eval(old_meta.get("index_together", "[]"))
+                    if index_together:
+                        # If it's only a single tuple, make it into the longer one
+                        if isinstance(index_together[0], basestring):
+                            index_together = [index_together]
+                        # For each combination, make an action for it
+                        for fields in index_together:
+                            yield ("DeleteIndex", {
+                                "model": self.old_orm[key],
+                                "fields": [self.old_orm[key]._meta.get_field_by_name(x)[0] for x in fields],
+                            })
                 # We always add it in here so we ignore it later
                 deleted_models.add(key)
         
                         field = self.current_field_from_key(key, fieldname)
                         if auto_through(field):
                             yield ("AddM2M", {"model": self.current_model_from_key(key), "field": field})
-                    # And any unique constraints it has 
+                    # And any unique constraints it has
                     unique_together = eval(new_meta.get("unique_together", "[]"))
                     if unique_together:
                         # If it's only a single tuple, make it into the longer one
                                 "model": self.current_model_from_key(key),
                                 "fields": [self.current_model_from_key(key)._meta.get_field_by_name(x)[0] for x in fields],
                             })
-        
+                    # And any other indexes it has
+                    index_together = eval(new_meta.get("index_together", "[]"))
+                    if index_together:
+                        # If it's only a single tuple, make it into the longer one
+                        if isinstance(index_together[0], basestring):
+                            index_together = [index_together]
+                        # For each combination, make an action for it
+                        for fields in index_together:
+                            yield ("AddIndex", {
+                                "model": self.current_model_from_key(key),
+                                "fields": [self.current_model_from_key(key)._meta.get_field_by_name(x)[0] for x in fields],
+                            })
+
         # Now, for every model that's stayed the same, check its fields.
         for key in self.old_defs:
             if key not in deleted_models:
                             "fields": [self.current_field_from_key(key, x) for x in item],
                         })
 
+                ## See if the index_togethers have changed
+                # First, normalise them into lists of sets.
+                old_index_together = eval(old_meta.get("index_together", "[]"))
+                new_index_together = eval(new_meta.get("index_together", "[]"))
+                if old_index_together and isinstance(old_index_together[0], basestring):
+                    old_index_together = [old_index_together]
+                if new_index_together and isinstance(new_index_together[0], basestring):
+                    new_index_together = [new_index_together]
+                old_index_together = map(set, old_index_together)
+                new_index_together = map(set, new_index_together)
+                # See if any appeared or disappeared
+                for item in old_index_together:
+                    if item not in new_index_together:
+                        yield ("DeleteIndex", {
+                            "model": self.old_orm[key],
+                            "fields": [self.old_orm[key + ":" + x] for x in item],
+                        })
+                for item in new_index_together:
+                    if item not in old_index_together:
+                        yield ("AddIndex", {
+                            "model": self.current_model_from_key(key),
+                            "fields": [self.current_field_from_key(key, x) for x in item],
+                        })
+
     @classmethod
     def is_triple(cls, triple):
         "Returns whether the argument is a triple."
                 "model_def": real_fields,
             })
             
-            # Then, add any uniqueness that's around
+            # Then, add any uniqueness and indexes that's around
             if meta:
                 unique_together = eval(meta.get("unique_together", "[]"))
                 if unique_together:
                             "model": model,
                             "fields": [model._meta.get_field_by_name(x)[0] for x in fields],
                         })
-            
+
+                index_together = eval(meta.get("index_together", "[]"))
+                if index_together:
+                    # If it's only a single tuple, make it into the longer one
+                    if isinstance(index_together[0], basestring):
+                        index_together = [index_together]
+                        # For each combination, make an action for it
+                    for fields in index_together:
+                        yield ("AddIndex", {
+                            "model": model,
+                            "fields": [model._meta.get_field_by_name(x)[0] for x in fields],
+                        })
+
             # Finally, see if there's some M2M action
             for name, triple in m2m_fields.items():
                 field = model._meta.get_field_by_name(name)[0]

south/modelsinspector.py

 meta_details = {
     "db_table": ["db_table", {"default_attr_concat": ["%s_%s", "app_label", "module_name"]}],
     "db_tablespace": ["db_tablespace", {"default": settings.DEFAULT_TABLESPACE}],
+    "index_together": ["index_together", {"default": []}],
     "unique_together": ["unique_together", {"default": []}],
     "ordering": ["ordering", {"default": []}],
     "proxy": ["proxy", {"default": False, "ignore_missing": True}],