mirror of
https://github.com/django/django.git
synced 2025-03-11 18:02:35 +00:00
Makemigration command now works
This commit is contained in:
parent
ab5cbae9b7
commit
f25a385a5e
@ -1,4 +1,5 @@
|
|||||||
import sys
|
import sys
|
||||||
|
import os
|
||||||
from optparse import make_option
|
from optparse import make_option
|
||||||
|
|
||||||
from django.core.management.base import BaseCommand
|
from django.core.management.base import BaseCommand
|
||||||
@ -8,6 +9,7 @@ from django.db import connections
|
|||||||
from django.db.migrations.loader import MigrationLoader
|
from django.db.migrations.loader import MigrationLoader
|
||||||
from django.db.migrations.autodetector import MigrationAutodetector, InteractiveMigrationQuestioner
|
from django.db.migrations.autodetector import MigrationAutodetector, InteractiveMigrationQuestioner
|
||||||
from django.db.migrations.state import ProjectState
|
from django.db.migrations.state import ProjectState
|
||||||
|
from django.db.migrations.writer import MigrationWriter
|
||||||
from django.db.models.loading import cache
|
from django.db.models.loading import cache
|
||||||
|
|
||||||
|
|
||||||
@ -49,4 +51,30 @@ class Command(BaseCommand):
|
|||||||
if app_labels:
|
if app_labels:
|
||||||
changes = autodetector.trim_to_apps(changes, 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())
|
||||||
|
@ -41,10 +41,10 @@ class MigrationAutodetector(object):
|
|||||||
self.add_to_migration(
|
self.add_to_migration(
|
||||||
app_label,
|
app_label,
|
||||||
operations.CreateModel(
|
operations.CreateModel(
|
||||||
model_state.name,
|
name = model_state.name,
|
||||||
model_state.fields,
|
fields = model_state.fields,
|
||||||
model_state.options,
|
options = model_state.options,
|
||||||
model_state.bases,
|
bases = model_state.bases,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
# Removing models
|
# Removing models
|
||||||
|
@ -37,7 +37,8 @@ class MigrationLoader(object):
|
|||||||
self.disk_migrations = None
|
self.disk_migrations = None
|
||||||
self.applied_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:
|
if app_label in settings.MIGRATION_MODULES:
|
||||||
return settings.MIGRATION_MODULES[app_label]
|
return settings.MIGRATION_MODULES[app_label]
|
||||||
app = cache.get_app(app_label)
|
app = cache.get_app(app_label)
|
||||||
@ -52,7 +53,7 @@ class MigrationLoader(object):
|
|||||||
for app in cache.get_apps():
|
for app in cache.get_apps():
|
||||||
# Get the migrations module directory
|
# Get the migrations module directory
|
||||||
app_label = app.__name__.split(".")[-2]
|
app_label = app.__name__.split(".")[-2]
|
||||||
module_name = self.migration_module(app_label)
|
module_name = self.migrations_module(app_label)
|
||||||
try:
|
try:
|
||||||
module = import_module(module_name)
|
module = import_module(module_name)
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
|
@ -54,3 +54,9 @@ class Operation(object):
|
|||||||
drop the model's table.
|
drop the model's table.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def describe(self):
|
||||||
|
"""
|
||||||
|
Outputs a brief summary of what the action does.
|
||||||
|
"""
|
||||||
|
return "%s: %s" % (self.__class__.__name__, self._constructor_args)
|
||||||
|
@ -23,6 +23,9 @@ class AddField(Operation):
|
|||||||
from_model = from_state.render().get_model(app_label, self.model_name)
|
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])
|
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):
|
class RemoveField(Operation):
|
||||||
"""
|
"""
|
||||||
@ -48,3 +51,6 @@ class RemoveField(Operation):
|
|||||||
from_model = from_state.render().get_model(app_label, self.model_name)
|
from_model = from_state.render().get_model(app_label, self.model_name)
|
||||||
to_model = to_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])
|
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)
|
||||||
|
@ -25,6 +25,9 @@ class CreateModel(Operation):
|
|||||||
app_cache = from_state.render()
|
app_cache = from_state.render()
|
||||||
schema_editor.delete_model(app_cache.get_model(app, self.name))
|
schema_editor.delete_model(app_cache.get_model(app, self.name))
|
||||||
|
|
||||||
|
def describe(self):
|
||||||
|
return "Create model %s" % (self.name, )
|
||||||
|
|
||||||
|
|
||||||
class DeleteModel(Operation):
|
class DeleteModel(Operation):
|
||||||
"""
|
"""
|
||||||
@ -44,3 +47,6 @@ class DeleteModel(Operation):
|
|||||||
def database_backwards(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()
|
app_cache = to_state.render()
|
||||||
schema_editor.create_model(app_cache.get_model(app_label, self.name))
|
schema_editor.create_model(app_cache.get_model(app_label, self.name))
|
||||||
|
|
||||||
|
def describe(self):
|
||||||
|
return "Delete model %s" % (self.name, )
|
||||||
|
@ -1,8 +1,12 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
import datetime
|
import datetime
|
||||||
import types
|
import types
|
||||||
|
import os
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
|
from django.utils.importlib import import_module
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.db.models.loading import cache
|
||||||
|
from django.db.migrations.loader import MigrationLoader
|
||||||
|
|
||||||
|
|
||||||
class MigrationWriter(object):
|
class MigrationWriter(object):
|
||||||
@ -49,6 +53,24 @@ class MigrationWriter(object):
|
|||||||
def filename(self):
|
def filename(self):
|
||||||
return "%s.py" % self.migration.name
|
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
|
@classmethod
|
||||||
def serialize(cls, value):
|
def serialize(cls, value):
|
||||||
"""
|
"""
|
||||||
@ -130,6 +152,17 @@ class MigrationWriter(object):
|
|||||||
if module is None:
|
if module is None:
|
||||||
raise ValueError("Cannot serialize function %r: No module" % value)
|
raise ValueError("Cannot serialize function %r: No module" % value)
|
||||||
return "%s.%s" % (module, value.__name__), set(["import %s" % module])
|
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.
|
# Uh oh.
|
||||||
else:
|
else:
|
||||||
raise ValueError("Cannot serialize: %r" % value)
|
raise ValueError("Cannot serialize: %r" % value)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user