Andrew Godwin avatar Andrew Godwin committed 4bea62b

Fix #521: Create unique_togethers with new models (added for delete as well)

Comments (0)

Files changed (1)

south/creator/changes.py

         for key in self.old_defs:
             if key not in self.new_defs:
                 # We shouldn't delete it if it was managed=False
-                if self.old_defs[key].get("Meta", {}).get("managed", "True") != "False":
-                    old_fields, old_meta, old_m2ms = self.split_model_def(self.old_orm[key], self.old_defs[key])
-                    # Alright, delete it.
-                    yield ("DeleteModel", {
-                        "model": self.old_orm[key], 
-                        "model_def": old_fields,
-                    })
-                    # Also make sure we delete any M2Ms it had.
+                old_fields, old_meta, old_m2ms = self.split_model_def(self.old_orm[key], self.old_defs[key])
+                if old_meta.get("managed", "True") != "False":
+                    # Make sure we delete any M2Ms it had.
                     for fieldname in old_m2ms:
                         # Only delete its stuff if it wasn't a through=.
                         field = self.old_orm[key + ":" + fieldname]
                         if auto_through(field):
                             yield ("DeleteM2M", {"model": self.old_orm[key], "field": field})
+                    # And any unique constraints it had 
+                    unique_together = eval(old_meta.get("unique_together", "[]"))
+                    if unique_together:
+                        # If it's only a single tuple, make it into the longer one
+                        if isinstance(unique_together[0], basestring):
+                            unique_together = [unique_together]
+                        # For each combination, make an action for it
+                        for fields in unique_together:
+                            yield ("DeleteUnique", {
+                                "model": self.old_orm[key],
+                                "fields": [self.old_orm[key]._meta.get_field_by_name(x)[0] for x in fields],
+                            })
+                    # Finally, delete it.
+                    yield ("DeleteModel", {
+                        "model": self.old_orm[key], 
+                        "model_def": old_fields,
+                    })
                 # We always add it in here so we ignore it later
                 deleted_models.add(key)
         
         for key in self.new_defs:
             if key not in self.old_defs:
                 # We shouldn't add it if it's managed=False
-                if self.new_defs[key].get("Meta", {}).get("managed", "True") != "False":
-                    new_fields, new_meta, new_m2ms = self.split_model_def(self.current_model_from_key(key), self.new_defs[key])
+                new_fields, new_meta, new_m2ms = self.split_model_def(self.current_model_from_key(key), self.new_defs[key])
+                if new_meta.get("managed", "True") != "False":
                     yield ("AddModel", {
                         "model": self.current_model_from_key(key), 
                         "model_def": new_fields,
                         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 
+                    unique_together = eval(new_meta.get("unique_together", "[]"))
+                    if unique_together:
+                        # If it's only a single tuple, make it into the longer one
+                        if isinstance(unique_together[0], basestring):
+                            unique_together = [unique_together]
+                        # For each combination, make an action for it
+                        for fields in unique_together:
+                            yield ("AddUnique", {
+                                "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:
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.