Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Autodetect fields, have migrate actually work

  • Loading branch information...
commit 41214eaf18c083012c57836befa4b833cf8a3698 1 parent f25a385
@andrewgodwin andrewgodwin authored
View
2  django/core/management/commands/migrate.py
@@ -72,7 +72,7 @@ def handle_noargs(self, **options):
plan = executor.migration_plan(targets)
if self.verbosity >= 1:
- self.stdout.write(self.style.MIGRATE_LABEL(" Apps with migrations: ") + (", ".join(executor.loader.disk_migrations) or "(none)"))
+ self.stdout.write(self.style.MIGRATE_LABEL(" Apps with migrations: ") + (", ".join(executor.loader.migrated_apps) or "(none)"))
# Run the syncdb phase.
# If you ever manage to get rid of this, I owe you many, many drinks.
View
28 django/db/migrations/autodetector.py
@@ -34,7 +34,7 @@ def changes(self):
"""
# We'll store migrations as lists by app names for now
self.migrations = {}
- # Stage one: Adding models.
+ # Adding models.
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.models[app_label, model_name]
@@ -57,6 +57,32 @@ def changes(self):
model_state.name,
)
)
+ # Changes within models
+ kept_models = set(self.from_state.models.keys()).intersection(self.to_state.models.keys())
+ for app_label, model_name in kept_models:
+ old_model_state = self.from_state.models[app_label, model_name]
+ new_model_state = self.to_state.models[app_label, model_name]
+ # New fields
+ old_field_names = set([x for x, y in old_model_state.fields])
+ new_field_names = set([x for x, y in new_model_state.fields])
+ for field_name in new_field_names - old_field_names:
+ self.add_to_migration(
+ app_label,
+ operations.AddField(
+ model_name = model_name,
+ name = field_name,
+ field = [y for x, y in new_model_state.fields if x == field_name][0],
+ )
+ )
+ # Old fields
+ for field_name in old_field_names - new_field_names:
+ self.add_to_migration(
+ app_label,
+ operations.RemoveField(
+ model_name = model_name,
+ name = field_name,
+ )
+ )
# Alright, now add internal dependencies
for app_label, migrations in self.migrations.items():
for m1, m2 in zip(migrations, migrations[1:]):
View
2  django/db/migrations/loader.py
@@ -50,6 +50,7 @@ def load_disk(self):
"""
self.disk_migrations = {}
self.unmigrated_apps = set()
+ self.migrated_apps = set()
for app in cache.get_apps():
# Get the migrations module directory
app_label = app.__name__.split(".")[-2]
@@ -62,6 +63,7 @@ def load_disk(self):
if "No module named" in str(e) and "migrations" in str(e):
self.unmigrated_apps.add(app_label)
continue
+ self.migrated_apps.add(app_label)
directory = os.path.dirname(module.__file__)
# Scan for .py[c|o] files
migration_names = set()
View
6 django/db/migrations/operations/fields.py
@@ -6,13 +6,13 @@ class AddField(Operation):
Adds a field to a model.
"""
- def __init__(self, model_name, name, instance):
+ def __init__(self, model_name, name, field):
self.model_name = model_name
self.name = name
- self.instance = instance
+ self.field = field
def state_forwards(self, app_label, state):
- state.models[app_label, self.model_name.lower()].fields.append((self.name, self.instance))
+ state.models[app_label, self.model_name.lower()].fields.append((self.name, self.field))
def database_forwards(self, app_label, schema_editor, from_state, to_state):
from_model = from_state.render().get_model(app_label, self.model_name)
Please sign in to comment.
Something went wrong with that request. Please try again.