diff options
| author | Andrew Godwin <andrew@aeracode.org> | 2013-06-20 15:12:59 +0100 |
|---|---|---|
| committer | Andrew Godwin <andrew@aeracode.org> | 2013-06-20 15:12:59 +0100 |
| commit | 80bdf68d6b5fd44056479ccc74cd24281b787a64 (patch) | |
| tree | 8ce30bba063a2a8a8cb9395e2a403fc0d228fbe6 /django | |
| parent | 6f667999e1186b8eaa9c86e4cbd80d5c0ba20576 (diff) | |
Add AlterField and RenameField operations
Diffstat (limited to 'django')
| -rw-r--r-- | django/db/migrations/operations/__init__.py | 2 | ||||
| -rw-r--r-- | django/db/migrations/operations/fields.py | 68 | ||||
| -rw-r--r-- | django/db/migrations/state.py | 9 |
3 files changed, 77 insertions, 2 deletions
diff --git a/django/db/migrations/operations/__init__.py b/django/db/migrations/operations/__init__.py index 6c2c784635..925b05fff3 100644 --- a/django/db/migrations/operations/__init__.py +++ b/django/db/migrations/operations/__init__.py @@ -1,2 +1,2 @@ from .models import CreateModel, DeleteModel, AlterModelTable -from .fields import AddField, RemoveField +from .fields import AddField, RemoveField, AlterField, RenameField diff --git a/django/db/migrations/operations/fields.py b/django/db/migrations/operations/fields.py index 660cba6b72..cc4f4a43df 100644 --- a/django/db/migrations/operations/fields.py +++ b/django/db/migrations/operations/fields.py @@ -54,3 +54,71 @@ class RemoveField(Operation): def describe(self): return "Remove field %s from %s" % (self.name, self.model_name) + + +class AlterField(Operation): + """ + Alters a field's database column (e.g. null, max_length) to the provided new field + """ + + def __init__(self, model_name, name, field): + self.model_name = model_name + self.name = name + self.field = field + + def state_forwards(self, app_label, state): + state.models[app_label, self.model_name.lower()].fields = [ + (n, self.field if n == self.name else f) for n, f in state.models[app_label, self.model_name.lower()].fields + ] + + def database_forwards(self, app_label, schema_editor, from_state, to_state): + from_model = from_state.render().get_model(app_label, self.model_name) + to_model = to_state.render().get_model(app_label, self.model_name) + schema_editor.alter_field( + from_model, + from_model._meta.get_field_by_name(self.name)[0], + to_model._meta.get_field_by_name(self.name)[0], + ) + + def database_backwards(self, app_label, schema_editor, from_state, to_state): + self.database_forwards(app_label, schema_editor, from_state, to_state) + + def describe(self): + return "Alter field %s on %s" % (self.name, self.model_name) + + +class RenameField(Operation): + """ + Renames a field on the model. Might affect db_column too. + """ + + def __init__(self, model_name, old_name, new_name): + self.model_name = model_name + self.old_name = old_name + self.new_name = new_name + + def state_forwards(self, app_label, state): + state.models[app_label, self.model_name.lower()].fields = [ + (self.new_name if n == self.old_name else n, f) for n, f in state.models[app_label, self.model_name.lower()].fields + ] + + def database_forwards(self, app_label, schema_editor, from_state, to_state): + from_model = from_state.render().get_model(app_label, self.model_name) + to_model = to_state.render().get_model(app_label, self.model_name) + schema_editor.alter_field( + from_model, + from_model._meta.get_field_by_name(self.old_name)[0], + to_model._meta.get_field_by_name(self.new_name)[0], + ) + + def database_backwards(self, app_label, schema_editor, from_state, to_state): + from_model = from_state.render().get_model(app_label, self.model_name) + to_model = to_state.render().get_model(app_label, self.model_name) + schema_editor.alter_field( + from_model, + from_model._meta.get_field_by_name(self.new_name)[0], + to_model._meta.get_field_by_name(self.old_name)[0], + ) + + def describe(self): + return "Rename field %s on %s to %s" % (self.old_name, self.model_name, self.new_name) diff --git a/django/db/migrations/state.py b/django/db/migrations/state.py index b6618041f2..65b749c80c 100644 --- a/django/db/migrations/state.py +++ b/django/db/migrations/state.py @@ -93,10 +93,17 @@ class ModelState(object): def clone(self): "Returns an exact copy of this ModelState" + # We deep-clone the fields using deconstruction + fields = [] + for name, field in self.fields: + _, path, args, kwargs = field.deconstruct() + field_class = import_by_path(path) + fields.append((name, field_class(*args, **kwargs))) + # Now make a copy return self.__class__( app_label = self.app_label, name = self.name, - fields = list(self.fields), + fields = fields, options = dict(self.options), bases = self.bases, ) |
