Commits

Andrew Godwin committed 5573258

Changing initial so it works with the new actions. Almost there.

  • Participants
  • Parent commits 4215f1e
  • Branches 0.7

Comments (0)

Files changed (2)

south/creator/actions.py

     def add_backwards(self, backwards):
         backwards.append(self.backwards_code())
     
-    def triples_to_defs(self, fields):
+    @classmethod
+    def triples_to_defs(cls, fields):
         # Turn the (class, args, kwargs) format into a string
         for field, triple in fields.items():
-            triple = remove_useless_attributes(triple, db=True)
-            if triple is None:
-                print "WARNING: Cannot get definition for '%s' on '%s'. Please edit the migration manually." % (
-                    field,
-                    model_key(model),
-                )
-                fields[field] = "<<??>>"
-            else:
-                fields[field] = "self.gf(%r)(%s)" % (
-                    triple[0], # Field full path
-                    ", ".join(triple[1] + ["%s=%s" % (kwd, val) for kwd, val in triple[2].items()]), # args and kwds
-                )
+            fields[field] = cls.triple_to_def(triple)
         return fields
     
+    @classmethod
+    def triple_to_def(cls, triple):
+        "Turns a single triple into a definition."
+        triple = remove_useless_attributes(triple, db=True)
+        if triple is None:
+            print "WARNING: Cannot get definition for '%s' on '%s'. Please edit the migration manually." % (
+                field,
+                model_key(model),
+            )
+            return "<<??>>"
+        else:
+            return "self.gf(%r)(%s)" % (
+                triple[0], # Field full path
+                ", ".join(triple[1] + ["%s=%s" % (kwd, val) for kwd, val in triple[2].items()]), # args and kwds
+            )
+    
     
 class AddModel(Action):
     """
             "model_name": self.model._meta.object_name,
             "table_name": self.model._meta.db_table,
             "field_name": self.field_name,
-            "field_def": self.field_def,
+            "field_def": self.triple_to_def(self.field_def),
         }
 
     def backwards_code(self):
     def backwards_code(self):
         return AddField.forwards_code(self)
 
+
+class AddUnique(Action):
+    """
+    Adds a unique constraint to a model. Takes a Model class and the field names.
+    """
+    
+    FORWARDS_TEMPLATE = '''
+        # Adding unique constraint on '%(model_name)s', fields %(fields)s
+        db.add_unique(%(table_name)r, %(fields)r)'''
+    
+    BACKWARDS_TEMPLATE = '''
+        # Removing unique constraint on '%(model_name)s', fields %(fields)s
+        db.delete_unique(%(table_name)r, %(fields)r)'''
+    
+    def __init__(self, model, fields):
+        self.model = model
+        self.fields = fields
+    
+    def forwards_code(self):
+        
+        return self.FORWARDS_TEMPLATE % {
+            "model_name": self.model._meta.object_name,
+            "table_name": self.model._meta.db_table,
+            "fields": self.fields,
+        }
+
+    def backwards_code(self):
+        return self.BACKWARDS_TEMPLATE % {
+            "model_name": self.model._meta.object_name,
+            "table_name": self.model._meta.db_table,
+            "fields": self.fields,
+        }
+
+
+class DeleteUnique(AddUnique):
+    """
+    Removes a unique constraint from a model. Takes a Model class and the field names.
+    """
+    
+    def forwards_code(self):
+        return AddUnique.backwards_code(self)
+
+    def backwards_code(self):
+        return AddUnique.forwards_code(self)

south/creator/changes.py

 
 from django.db import models
 
-from south.creator.freezer import remove_useless_attributes
+from south.creator.freezer import remove_useless_attributes, freeze_apps
 
 class AutoChanges(object):
     """
         self.migrations = migrations
     
     def get_changes(self):
-        # Get the app's models
+        # Get the frozen models for this app
+        model_defs = freeze_apps(self.migrations.app_label())
+        
         for model in models.get_models(models.get_app(self.migrations.app_label())):
-            yield ("AddModel", {"model": model})
+            
+            model_def = model_defs[model._meta.app_label + "." + model._meta.object_name]
+            
+            yield ("AddModel", {
+                "model": model,
+                "model_def": dict((k, v) for k, v in model_defs.items() if k != "Meta"),
+            })