Loading django/db/migrations/autodetector.py +8 −8 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ from django.db.migrations import operations from django.db.migrations.migration import Migration class AutoDetector(object): class MigrationAutodetector(object): """ Takes a pair of ProjectStates, and compares them to see what the first would need doing to make it match the second (the second Loading @@ -27,9 +27,9 @@ class AutoDetector(object): # We'll store migrations as lists by app names for now self.migrations = {} # Stage one: Adding models. added_models = set(self.to_state.keys()) - set(self.from_state.keys()) added_models = set(self.to_state.models.keys()) - set(self.from_state.models.keys()) for app_label, model_name in added_models: model_state = self.to_state[app_label, model_name] model_state = self.to_state.models[app_label, model_name] self.add_to_migration( app_label, operations.CreateModel( Loading @@ -40,9 +40,9 @@ class AutoDetector(object): ) ) # Removing models removed_models = set(self.from_state.keys()) - set(self.to_state.keys()) removed_models = set(self.from_state.models.keys()) - set(self.to_state.models.keys()) for app_label, model_name in removed_models: model_state = self.from_state[app_label, model_name] model_state = self.from_state.models[app_label, model_name] self.add_to_migration( app_label, operations.DeleteModel( Loading @@ -59,11 +59,11 @@ class AutoDetector(object): for migration in migrations: subclass = type("Migration", (Migration,), migration) instance = subclass(migration['name'], app_label) result.append(instance) result.add(instance) return result def add_to_migration(self, app_label, operation): migrations = self.migrations.setdefault(app_label, []) if not migrations: migrations.append({"name": "temp-%i" % len(migrations) + 1, "operations": [], "dependencies": []}) migrations[-1].operations.append(operation) migrations.append({"name": "auto_%i" % (len(migrations) + 1), "operations": [], "dependencies": []}) migrations[-1]['operations'].append(operation) django/db/migrations/migration.py +3 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,9 @@ class Migration(object): def __repr__(self): return "<Migration %s.%s>" % (self.app_label, self.name) def __hash__(self): return hash("%s.%s" % (self.app_label, self.name)) def mutate_state(self, project_state): """ Takes a ProjectState and returns a new one with the migration's Loading tests/migrations/test_autodetector.py 0 → 100644 +54 −0 Original line number Diff line number Diff line # encoding: utf8 from django.test import TransactionTestCase from django.db.migrations.autodetector import MigrationAutodetector from django.db.migrations.state import ProjectState, ModelState from django.db import models class AutodetectorTests(TransactionTestCase): """ Tests the migration autodetector. """ author_empty = ModelState("testapp", "Author", [("id", models.AutoField(primary_key=True))]) def make_project_state(self, model_states): "Shortcut to make ProjectStates from lists of predefined models" project_state = ProjectState() for model_state in model_states: project_state.add_model_state(model_state) return project_state def test_new_model(self): "Tests autodetection of new models" # Make state before = self.make_project_state([]) after = self.make_project_state([self.author_empty]) autodetector = MigrationAutodetector(before, after) changes = autodetector.changes() # Right number of migrations? self.assertEqual(len(changes), 1) # Right number of actions? migration = changes.pop() self.assertEqual(len(migration.operations), 1) # Right action? action = migration.operations[0] self.assertEqual(action.__class__.__name__, "CreateModel") self.assertEqual(action.name, "Author") def test_old_model(self): "Tests deletion of old models" # Make state before = self.make_project_state([self.author_empty]) after = self.make_project_state([]) autodetector = MigrationAutodetector(before, after) changes = autodetector.changes() # Right number of migrations? self.assertEqual(len(changes), 1) # Right number of actions? migration = changes.pop() self.assertEqual(len(migration.operations), 1) # Right action? action = migration.operations[0] self.assertEqual(action.__class__.__name__, "DeleteModel") self.assertEqual(action.name, "Author") Loading
django/db/migrations/autodetector.py +8 −8 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ from django.db.migrations import operations from django.db.migrations.migration import Migration class AutoDetector(object): class MigrationAutodetector(object): """ Takes a pair of ProjectStates, and compares them to see what the first would need doing to make it match the second (the second Loading @@ -27,9 +27,9 @@ class AutoDetector(object): # We'll store migrations as lists by app names for now self.migrations = {} # Stage one: Adding models. added_models = set(self.to_state.keys()) - set(self.from_state.keys()) added_models = set(self.to_state.models.keys()) - set(self.from_state.models.keys()) for app_label, model_name in added_models: model_state = self.to_state[app_label, model_name] model_state = self.to_state.models[app_label, model_name] self.add_to_migration( app_label, operations.CreateModel( Loading @@ -40,9 +40,9 @@ class AutoDetector(object): ) ) # Removing models removed_models = set(self.from_state.keys()) - set(self.to_state.keys()) removed_models = set(self.from_state.models.keys()) - set(self.to_state.models.keys()) for app_label, model_name in removed_models: model_state = self.from_state[app_label, model_name] model_state = self.from_state.models[app_label, model_name] self.add_to_migration( app_label, operations.DeleteModel( Loading @@ -59,11 +59,11 @@ class AutoDetector(object): for migration in migrations: subclass = type("Migration", (Migration,), migration) instance = subclass(migration['name'], app_label) result.append(instance) result.add(instance) return result def add_to_migration(self, app_label, operation): migrations = self.migrations.setdefault(app_label, []) if not migrations: migrations.append({"name": "temp-%i" % len(migrations) + 1, "operations": [], "dependencies": []}) migrations[-1].operations.append(operation) migrations.append({"name": "auto_%i" % (len(migrations) + 1), "operations": [], "dependencies": []}) migrations[-1]['operations'].append(operation)
django/db/migrations/migration.py +3 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,9 @@ class Migration(object): def __repr__(self): return "<Migration %s.%s>" % (self.app_label, self.name) def __hash__(self): return hash("%s.%s" % (self.app_label, self.name)) def mutate_state(self, project_state): """ Takes a ProjectState and returns a new one with the migration's Loading
tests/migrations/test_autodetector.py 0 → 100644 +54 −0 Original line number Diff line number Diff line # encoding: utf8 from django.test import TransactionTestCase from django.db.migrations.autodetector import MigrationAutodetector from django.db.migrations.state import ProjectState, ModelState from django.db import models class AutodetectorTests(TransactionTestCase): """ Tests the migration autodetector. """ author_empty = ModelState("testapp", "Author", [("id", models.AutoField(primary_key=True))]) def make_project_state(self, model_states): "Shortcut to make ProjectStates from lists of predefined models" project_state = ProjectState() for model_state in model_states: project_state.add_model_state(model_state) return project_state def test_new_model(self): "Tests autodetection of new models" # Make state before = self.make_project_state([]) after = self.make_project_state([self.author_empty]) autodetector = MigrationAutodetector(before, after) changes = autodetector.changes() # Right number of migrations? self.assertEqual(len(changes), 1) # Right number of actions? migration = changes.pop() self.assertEqual(len(migration.operations), 1) # Right action? action = migration.operations[0] self.assertEqual(action.__class__.__name__, "CreateModel") self.assertEqual(action.name, "Author") def test_old_model(self): "Tests deletion of old models" # Make state before = self.make_project_state([self.author_empty]) after = self.make_project_state([]) autodetector = MigrationAutodetector(before, after) changes = autodetector.changes() # Right number of migrations? self.assertEqual(len(changes), 1) # Right number of actions? migration = changes.pop() self.assertEqual(len(migration.operations), 1) # Right action? action = migration.operations[0] self.assertEqual(action.__class__.__name__, "DeleteModel") self.assertEqual(action.name, "Author")