Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Makemigration command now works

  • Loading branch information...
commit f25a385a5eb81ee660a82e6dd41e80938672f69c 1 parent ab5cbae
@andrewgodwin andrewgodwin authored
View
30 django/core/management/commands/makemigration.py
@@ -1,4 +1,5 @@
import sys
+import os
from optparse import make_option
from django.core.management.base import BaseCommand
@@ -8,6 +9,7 @@
from django.db.migrations.loader import MigrationLoader
from django.db.migrations.autodetector import MigrationAutodetector, InteractiveMigrationQuestioner
from django.db.migrations.state import ProjectState
+from django.db.migrations.writer import MigrationWriter
from django.db.models.loading import cache
@@ -49,4 +51,30 @@ def handle(self, *app_labels, **options):
if app_labels:
changes = autodetector.trim_to_apps(changes, app_labels)
- print changes
+ # No changes? Tell them.
+ if not changes:
+ if len(app_labels) == 1:
+ self.stdout.write("No changes detected in app '%s'" % app_labels.pop())
+ elif len(app_labels) > 1:
+ self.stdout.write("No changes detected in apps '%s'" % ("', '".join(app_labels)))
+ else:
+ self.stdout.write("No changes detected")
+ return
+
+ for app_label, migrations in changes.items():
+ self.stdout.write(self.style.MIGRATE_HEADING("Migrations for '%s':" % app_label) + "\n")
+ for migration in migrations:
+ # Describe the migration
+ writer = MigrationWriter(migration)
+ self.stdout.write(" %s:\n" % (self.style.MIGRATE_LABEL(writer.filename),))
+ for operation in migration.operations:
+ self.stdout.write(" - %s\n" % operation.describe())
+ # Write it
+ migrations_directory = os.path.dirname(writer.path)
+ if not os.path.isdir(migrations_directory):
+ os.mkdir(migrations_directory)
+ init_path = os.path.join(migrations_directory, "__init__.py")
+ if not os.path.isfile(init_path):
+ open(init_path, "w").close()
+ with open(writer.path, "w") as fh:
+ fh.write(writer.as_string())
View
8 django/db/migrations/autodetector.py
@@ -41,10 +41,10 @@ def changes(self):
self.add_to_migration(
app_label,
operations.CreateModel(
- model_state.name,
- model_state.fields,
- model_state.options,
- model_state.bases,
+ name = model_state.name,
+ fields = model_state.fields,
+ options = model_state.options,
+ bases = model_state.bases,
)
)
# Removing models
View
5 django/db/migrations/loader.py
@@ -37,7 +37,8 @@ def __init__(self, connection):
self.disk_migrations = None
self.applied_migrations = None
- def migration_module(self, app_label):
+ @classmethod
+ def migrations_module(cls, app_label):
if app_label in settings.MIGRATION_MODULES:
return settings.MIGRATION_MODULES[app_label]
app = cache.get_app(app_label)
@@ -52,7 +53,7 @@ def load_disk(self):
for app in cache.get_apps():
# Get the migrations module directory
app_label = app.__name__.split(".")[-2]
- module_name = self.migration_module(app_label)
+ module_name = self.migrations_module(app_label)
try:
module = import_module(module_name)
except ImportError as e:
View
6 django/db/migrations/operations/base.py
@@ -54,3 +54,9 @@ def database_backwards(self, app_label, schema_editor, from_state, to_state):
drop the model's table.
"""
raise NotImplementedError()
+
+ def describe(self):
+ """
+ Outputs a brief summary of what the action does.
+ """
+ return "%s: %s" % (self.__class__.__name__, self._constructor_args)
View
6 django/db/migrations/operations/fields.py
@@ -23,6 +23,9 @@ def database_backwards(self, app_label, schema_editor, from_state, to_state):
from_model = from_state.render().get_model(app_label, self.model_name)
schema_editor.remove_field(from_model, from_model._meta.get_field_by_name(self.name)[0])
+ def describe(self):
+ return "Add field %s to %s" % (self.name, self.model_name)
+
class RemoveField(Operation):
"""
@@ -48,3 +51,6 @@ 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.add_field(from_model, to_model._meta.get_field_by_name(self.name)[0])
+
+ def describe(self):
+ return "Remove field %s from %s" % (self.name, self.model_name)
View
6 django/db/migrations/operations/models.py
@@ -25,6 +25,9 @@ def database_backwards(self, app, schema_editor, from_state, to_state):
app_cache = from_state.render()
schema_editor.delete_model(app_cache.get_model(app, self.name))
+ def describe(self):
+ return "Create model %s" % (self.name, )
+
class DeleteModel(Operation):
"""
@@ -44,3 +47,6 @@ def database_forwards(self, app_label, schema_editor, from_state, to_state):
def database_backwards(self, app_label, schema_editor, from_state, to_state):
app_cache = to_state.render()
schema_editor.create_model(app_cache.get_model(app_label, self.name))
+
+ def describe(self):
+ return "Delete model %s" % (self.name, )
View
33 django/db/migrations/writer.py
@@ -1,8 +1,12 @@
from __future__ import unicode_literals
import datetime
import types
+import os
from django.utils import six
+from django.utils.importlib import import_module
from django.db import models
+from django.db.models.loading import cache
+from django.db.migrations.loader import MigrationLoader
class MigrationWriter(object):
@@ -49,6 +53,24 @@ def as_string(self):
def filename(self):
return "%s.py" % self.migration.name
+ @property
+ def path(self):
+ migrations_module_name = MigrationLoader.migrations_module(self.migration.app_label)
+ app_module = cache.get_app(self.migration.app_label)
+ # See if we can import the migrations module directly
+ try:
+ migrations_module = import_module(migrations_module_name)
+ basedir = os.path.dirname(migrations_module.__file__)
+ except ImportError:
+ # Alright, see if it's a direct submodule of the app
+ oneup = ".".join(migrations_module_name.split(".")[:-1])
+ app_oneup = ".".join(app_module.__name__.split(".")[:-1])
+ if oneup == app_oneup:
+ basedir = os.path.join(os.path.dirname(app_module.__file__), migrations_module_name.split(".")[-1])
+ else:
+ raise ImportError("Cannot open migrations module %s for app %s" % (migrations_module_name, self.migration.app_label))
+ return os.path.join(basedir, self.filename)
+
@classmethod
def serialize(cls, value):
"""
@@ -130,6 +152,17 @@ def serialize(cls, value):
if module is None:
raise ValueError("Cannot serialize function %r: No module" % value)
return "%s.%s" % (module, value.__name__), set(["import %s" % module])
+ # Classes
+ elif isinstance(value, type):
+ special_cases = [
+ (models.Model, "models.Model", []),
+ ]
+ for case, string, imports in special_cases:
+ if case is value:
+ return string, set(imports)
+ if hasattr(value, "__module__"):
+ module = value.__module__
+ return "%s.%s" % (module, value.__name__), set(["import %s" % module])
# Uh oh.
else:
raise ValueError("Cannot serialize: %r" % value)
Please sign in to comment.
Something went wrong with that request. Please try again.