Kaydet (Commit) 58411041 authored tarafından Loic Bistuer's avatar Loic Bistuer Kaydeden (comit) Tim Graham

Fixed #21283 -- Added support for migrations if models is a package.

Thanks Markus Holtermann for the report.
üst 96d1d4e2
......@@ -41,8 +41,8 @@ class MigrationLoader(object):
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)
return ".".join(app.__name__.split(".")[:-1] + ["migrations"])
else:
return '%s.migrations' % cache.get_app_package(app_label)
def load_disk(self):
"""
......
......@@ -61,20 +61,22 @@ class MigrationWriter(object):
@property
def path(self):
migrations_module_name = MigrationLoader.migrations_module(self.migration.app_label)
app_module = cache.get_app(self.migration.app_label)
migrations_package_name = MigrationLoader.migrations_module(self.migration.app_label)
# See if we can import the migrations module directly
try:
migrations_module = import_module(migrations_module_name)
migrations_module = import_module(migrations_package_name)
basedir = os.path.dirname(migrations_module.__file__)
except ImportError:
app = cache.get_app(self.migration.app_label)
app_path = cache._get_app_path(app)
app_package_name = cache._get_app_package(app)
migrations_package_basename = migrations_package_name.split(".")[-1]
# 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])
if '%s.%s' % (app_package_name, migrations_package_basename) == migrations_package_name:
basedir = os.path.join(app_path, migrations_package_basename)
else:
raise ImportError("Cannot open migrations module %s for app %s" % (migrations_module_name, self.migration.app_label))
raise ImportError("Cannot open migrations module %s for app %s" % (migrations_package_name, self.migration.app_label))
return os.path.join(basedir, self.filename)
@classmethod
......
......@@ -185,6 +185,12 @@ class BaseAppCache(object):
return [elt[0] for elt in apps]
def _get_app_package(self, app):
return '.'.join(app.__name__.split('.')[:-1])
def get_app_package(self, app_label):
return self._get_app_package(self.get_app(app_label))
def _get_app_path(self, app):
if hasattr(app, '__path__'): # models/__init__.py package
app_path = app.__path__[0]
......@@ -380,6 +386,7 @@ cache = AppCache()
# These methods were always module level, so are kept that way for backwards
# compatibility.
get_apps = cache.get_apps
get_app_package = cache.get_app_package
get_app_path = cache.get_app_path
get_app_paths = cache.get_app_paths
get_app = cache.get_app
......
......@@ -2,12 +2,15 @@
from __future__ import unicode_literals
import copy
import datetime
import os
from django.utils import six
from django.test import TestCase
from django.db.migrations.writer import MigrationWriter
from django.db import models, migrations
from django.db.migrations.writer import MigrationWriter
from django.db.models.loading import cache
from django.test import TestCase, override_settings
from django.utils import six
from django.utils.translation import ugettext_lazy as _
......@@ -95,3 +98,24 @@ class WriterTests(TestCase):
# Just make sure it runs for now, and that things look alright.
result = self.safe_exec(output)
self.assertIn("Migration", result)
def test_migration_path(self):
_old_app_store = copy.deepcopy(cache.app_store)
test_apps = [
'migrations.migrations_test_apps.normal',
'migrations.migrations_test_apps.with_package_model',
]
base_dir = os.path.dirname(os.path.dirname(__file__))
try:
with override_settings(INSTALLED_APPS=test_apps):
for app in test_apps:
cache.load_app(app)
migration = migrations.Migration('0001_initial', app.split('.')[-1])
expected_path = os.path.join(base_dir, *(app.split('.') + ['migrations', '0001_initial.py']))
writer = MigrationWriter(migration)
self.assertEqual(writer.path, expected_path)
finally:
cache.app_store = _old_app_store
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment