Commits

Andrew Godwin committed e0fb36e

Console reporting, and a few other bits

Comments (0)

Files changed (6)

south/creator/actions.py

     def add_backwards(self, backwards):
         backwards.append(self.backwards_code())
     
+    def console_line(self):
+        "Returns the string to print on the console, e.g. ' + Added field foo'"
+        raise NotImplementedError
+    
     @classmethod
     def triples_to_defs(cls, fields):
         # Turn the (class, args, kwargs) format into a string
     def __init__(self, model, model_def):
         self.model = model
         self.model_def = model_def
+    
+    def console_line(self):
+        "Returns the string to print on the console, e.g. ' + Added field foo'"
+        return " + Added model %s.%s" % (
+            self.model._meta.app_label, 
+            self.model._meta.object_name,
+        )
 
     def forwards_code(self):
         
     """
     Deletion of a model. Takes the Model subclass that is being created.
     """
+    
+    def console_line(self):
+        "Returns the string to print on the console, e.g. ' + Added field foo'"
+        return " - Deleted model %s.%s" % (
+            self.model._meta.app_label, 
+            self.model._meta.object_name,
+        )
 
     def forwards_code(self):
         return AddModel.backwards_code(self)
         self.field_name = field
         self.field_def = field_def
     
+    def console_line(self):
+        "Returns the string to print on the console, e.g. ' + Added field foo'"
+        return " + Added field %s on %s.%s" % (
+            self.field_name,
+            self.model._meta.app_label, 
+            self.model._meta.object_name,
+        )
+    
     def forwards_code(self):
         
         return self.FORWARDS_TEMPLATE % {
     Removes a field from a model. Takes a Model class and the field name.
     """
     
+    def console_line(self):
+        "Returns the string to print on the console, e.g. ' + Added field foo'"
+        return " - Deleted field %s on %s.%s" % (
+            self.field_name,
+            self.model._meta.app_label, 
+            self.model._meta.object_name,
+        )
+    
     def forwards_code(self):
         return AddField.backwards_code(self)
 
         self.model = model
         self.fields = fields
     
+    def console_line(self):
+        "Returns the string to print on the console, e.g. ' + Added field foo'"
+        return " + Added unique constraint for %s on %s.%s" % (
+            self.fields,
+            self.model._meta.app_label, 
+            self.model._meta.object_name,
+        )
+    
     def forwards_code(self):
         
         return self.FORWARDS_TEMPLATE % {
     Removes a unique constraint from a model. Takes a Model class and the field names.
     """
     
+    def console_line(self):
+        "Returns the string to print on the console, e.g. ' + Added field foo'"
+        return " - Deleted unique constraint for %s on %s.%s" % (
+            self.fields,
+            self.model._meta.app_label, 
+            self.model._meta.object_name,
+        )
+    
     def forwards_code(self):
         return AddUnique.backwards_code(self)
 
         self.model = model
         self.field_name = field
     
+    def console_line(self):
+        "Returns the string to print on the console, e.g. ' + Added field foo'"
+        return " + Added M2M %s on %s.%s" % (
+            self.field_name,
+            self.model._meta.app_label, 
+            self.model._meta.object_name,
+        )
+    
     def forwards_code(self):
         
         field = self.model._meta.get_field_by_name(self.field_name)[0]
     Adds a unique constraint to a model. Takes a Model class and the field names.
     """
     
+    def console_line(self):
+        "Returns the string to print on the console, e.g. ' + Added field foo'"
+        return " - Deleted M2M %s on %s.%s" % (
+            self.field_name,
+            self.model._meta.app_label, 
+            self.model._meta.object_name,
+        )
+    
     def forwards_code(self):
         return AddM2M.backwards_code(self)
 

south/creator/changes.py

                 # Find fields that have vanished.
                 for fieldname in old_fields:
                     if fieldname not in new_fields:
-                        yield ("DeleteField", {"model": self.old_orm[key], "field": fieldname, "field_def": old_fields[fieldname]})
+                        if isinstance(self.old_orm[key+":"+fieldname], models.ManyToManyField):
+                            yield ("DeleteM2M", {"model": self.old_orm[key], "field": fieldname})
+                        else:
+                            yield ("DeleteField", {"model": self.old_orm[key], "field": fieldname, "field_def": old_fields[fieldname]})
                 
                 # And ones that have appeared
                 for fieldname in new_fields:
                     if fieldname not in old_fields:
-                        yield ("AddField", {"model": self.current_model_from_key(key), "field": fieldname, "field_def": new_fields[fieldname]})
+                        if isinstance(self.current_model_from_key(key)._meta.get_field_by_name(fieldname)[0], models.ManyToManyField):
+                            yield ("AddM2M", {"model": self.old_orm[key], "field": fieldname})
+                        else:
+                            yield ("AddField", {"model": self.current_model_from_key(key), "field": fieldname, "field_def": new_fields[fieldname]})
                 
                 # For the ones that exist in both models, see if they were changed
                 for fieldname in set(old_fields).intersection(set(new_fields)):

south/creator/freezer.py

     for name, field in fields.items():
         fields[name] = remove_useless_attributes(field)
     # See if there's a Meta
-    meta = modelsinspector.get_model_meta(model)
-    if meta:
-        fields['Meta'] = remove_useless_meta(meta)
+    fields['Meta'] = remove_useless_meta(modelsinspector.get_model_meta(model))
+    # Add in our own special item to track the object name
+    fields['Meta']['object_name'] = model._meta.object_name
     return fields
 
 ### Dependency resolvers

south/management/commands/datamigration.py

         """
         Prints the error, and exits with the given code.
         """
-        print >>sys.stderr(message)
+        print >>sys.stderr, message
         sys.exit(code)
 
 

south/management/commands/schemamigration.py

                 action = action_class(**params)
                 action.add_forwards(forwards_actions)
                 action.add_backwards(backwards_actions)
+                print >>sys.stderr, action.console_line()
+        
+        # Nowt happen? That's not good for --auto.
+        if auto and not forwards_actions:
+            self.error("Nothing seems to have changed.")
         
         # Work out which apps to freeze
         apps_to_freeze = self.calc_frozen_apps(migrations, freeze_list)
                 model_name = name
                 name = "%s.%s" % (app_label, model_name)
             
+            # If there's an object_name in the Meta, use it and remove it
+            if "object_name" in data['Meta']:
+                model_name = data['Meta']['object_name']
+                del data['Meta']['object_name']
+            
             name = name.lower()
             self.models[name] = name
             model_names.append((name, app_label, model_name, data))