mirror of
https://github.com/django/django.git
synced 2025-07-04 17:59:13 +00:00
[soc2010/app-loading] implement APP_CLASSES setting
git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2010/app-loading@13759 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
574424f40d
commit
11a32d6011
@ -170,6 +170,9 @@ EMAIL_HOST_USER = ''
|
|||||||
EMAIL_HOST_PASSWORD = ''
|
EMAIL_HOST_PASSWORD = ''
|
||||||
EMAIL_USE_TLS = False
|
EMAIL_USE_TLS = False
|
||||||
|
|
||||||
|
# List of strings representing installed app classes.
|
||||||
|
APP_CLASSES = ()
|
||||||
|
|
||||||
# List of strings representing installed apps.
|
# List of strings representing installed apps.
|
||||||
INSTALLED_APPS = ()
|
INSTALLED_APPS = ()
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ class App(object):
|
|||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return '<App: %s>' % self.name
|
return '<%s: %s>' % (self.__class__.__name__, self.name)
|
||||||
|
|
||||||
class AppCache(object):
|
class AppCache(object):
|
||||||
"""
|
"""
|
||||||
@ -78,10 +78,19 @@ class AppCache(object):
|
|||||||
try:
|
try:
|
||||||
if self.loaded:
|
if self.loaded:
|
||||||
return
|
return
|
||||||
|
for app_name in settings.APP_CLASSES:
|
||||||
|
if app_name in self.handled:
|
||||||
|
continue
|
||||||
|
app_module, app_classname = app_name.rsplit('.', 1)
|
||||||
|
app_module = import_module(app_module)
|
||||||
|
app_class = getattr(app_module, app_classname)
|
||||||
|
app_name = app_name.rsplit('.', 2)[0]
|
||||||
|
self.load_app(app_name, True, app_class)
|
||||||
for app_name in settings.INSTALLED_APPS:
|
for app_name in settings.INSTALLED_APPS:
|
||||||
if app_name in self.handled:
|
if app_name in self.handled:
|
||||||
continue
|
continue
|
||||||
self.load_app(app_name, True)
|
self.load_app(app_name, True)
|
||||||
|
|
||||||
if not self.nesting_level:
|
if not self.nesting_level:
|
||||||
for app_name in self.postponed:
|
for app_name in self.postponed:
|
||||||
self.load_app(app_name)
|
self.load_app(app_name)
|
||||||
@ -111,7 +120,7 @@ class AppCache(object):
|
|||||||
finally:
|
finally:
|
||||||
self.write_lock.release()
|
self.write_lock.release()
|
||||||
|
|
||||||
def load_app(self, app_name, can_postpone=False):
|
def load_app(self, app_name, can_postpone=False, app_class=App):
|
||||||
"""
|
"""
|
||||||
Loads the app with the provided fully qualified name, and returns the
|
Loads the app with the provided fully qualified name, and returns the
|
||||||
model module.
|
model module.
|
||||||
@ -119,20 +128,7 @@ class AppCache(object):
|
|||||||
self.handled[app_name] = None
|
self.handled[app_name] = None
|
||||||
self.nesting_level += 1
|
self.nesting_level += 1
|
||||||
|
|
||||||
try:
|
|
||||||
app_module = import_module(app_name)
|
app_module = import_module(app_name)
|
||||||
except ImportError:
|
|
||||||
# If the import fails, we assume it was because an path to a
|
|
||||||
# class was passed (e.g. "foo.bar.MyApp")
|
|
||||||
# We split the app_name by the rightmost dot to get the path
|
|
||||||
# and classname, and then try importing it again
|
|
||||||
if not '.' in app_name:
|
|
||||||
raise
|
|
||||||
app_name, app_classname = app_name.rsplit('.', 1)
|
|
||||||
app_module = import_module(app_name)
|
|
||||||
app_class = getattr(app_module, app_classname)
|
|
||||||
else:
|
|
||||||
app_class = App
|
|
||||||
|
|
||||||
# check if an app instance with that name already exists
|
# check if an app instance with that name already exists
|
||||||
app_instance = self.find_app(app_name)
|
app_instance = self.find_app(app_name)
|
||||||
@ -144,10 +140,11 @@ class AppCache(object):
|
|||||||
app_instance_name = app_name
|
app_instance_name = app_name
|
||||||
app_instance = app_class(app_instance_name)
|
app_instance = app_class(app_instance_name)
|
||||||
app_instance.module = app_module
|
app_instance.module = app_module
|
||||||
|
app_instance.path = app_name
|
||||||
self.app_instances.append(app_instance)
|
self.app_instances.append(app_instance)
|
||||||
self.installed_apps.append(app_name)
|
self.installed_apps.append(app_name)
|
||||||
|
|
||||||
# check if the app instance specifies a path to models
|
# Check if the app instance specifies a path to models
|
||||||
# if not, we use the models.py file from the package dir
|
# if not, we use the models.py file from the package dir
|
||||||
try:
|
try:
|
||||||
models_path = app_instance.models_path
|
models_path = app_instance.models_path
|
||||||
@ -211,9 +208,9 @@ class AppCache(object):
|
|||||||
self._populate()
|
self._populate()
|
||||||
self.write_lock.acquire()
|
self.write_lock.acquire()
|
||||||
try:
|
try:
|
||||||
for app_name in self.installed_apps:
|
for app in self.app_instances:
|
||||||
if app_label == app_name.split('.')[-1]:
|
if app_label == app.name:
|
||||||
mod = self.load_app(app_name, False)
|
mod = self.load_app(app.path, False)
|
||||||
if mod is None:
|
if mod is None:
|
||||||
if emptyOK:
|
if emptyOK:
|
||||||
return None
|
return None
|
||||||
|
@ -99,6 +99,12 @@ class Options(object):
|
|||||||
# If the db_table wasn't provided, use the db_prefix + module_name.
|
# If the db_table wasn't provided, use the db_prefix + module_name.
|
||||||
if not self.db_table:
|
if not self.db_table:
|
||||||
app_instance = cache.find_app(self.app_label)
|
app_instance = cache.find_app(self.app_label)
|
||||||
|
if not app_instance:
|
||||||
|
# use the app label when no app instance was found, this
|
||||||
|
# can happen when the app cache is not initialized but the
|
||||||
|
# model is imported
|
||||||
|
self.db_table = "%s_%s" % (self.app_label, self.module_name)
|
||||||
|
else:
|
||||||
self.db_table = "%s_%s" % (app_instance.db_prefix, self.module_name)
|
self.db_table = "%s_%s" % (app_instance.db_prefix, self.module_name)
|
||||||
self.db_table = truncate_name(self.db_table, connection.ops.max_name_length())
|
self.db_table = truncate_name(self.db_table, connection.ops.max_name_length())
|
||||||
|
|
||||||
|
@ -18,10 +18,13 @@ class AppCacheTestCase(unittest.TestCase):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.old_installed_apps = settings.INSTALLED_APPS
|
self.old_installed_apps = settings.INSTALLED_APPS
|
||||||
|
self.old_app_classes = settings.APP_CLASSES
|
||||||
|
settings.APP_CLASSES = ()
|
||||||
settings.INSTALLED_APPS = ()
|
settings.INSTALLED_APPS = ()
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
settings.INSTALLED_APPS = self.old_installed_apps
|
settings.INSTALLED_APPS = self.old_installed_apps
|
||||||
|
settings.APP_CLASSES = self.old_app_classes
|
||||||
|
|
||||||
# The appcache imports models modules. We need to delete the
|
# The appcache imports models modules. We need to delete the
|
||||||
# imported module from sys.modules after the test has run.
|
# imported module from sys.modules after the test has run.
|
||||||
@ -102,7 +105,7 @@ class GetAppsTests(AppCacheTestCase):
|
|||||||
Test that an exception is raised if two app instances
|
Test that an exception is raised if two app instances
|
||||||
have the same db_prefix attribute
|
have the same db_prefix attribute
|
||||||
"""
|
"""
|
||||||
settings.INSTALLED_APPS = ('nomodel_app.MyApp', 'model_app.MyOtherApp',)
|
settings.APP_CLASSES = ('nomodel_app.MyApp', 'model_app.MyOtherApp',)
|
||||||
self.assertRaises(ImproperlyConfigured, cache.get_apps)
|
self.assertRaises(ImproperlyConfigured, cache.get_apps)
|
||||||
|
|
||||||
class GetAppTests(AppCacheTestCase):
|
class GetAppTests(AppCacheTestCase):
|
||||||
@ -264,10 +267,10 @@ class LoadAppTests(AppCacheTestCase):
|
|||||||
def test_custom_app(self):
|
def test_custom_app(self):
|
||||||
"""
|
"""
|
||||||
Test that a custom app instance is created if the function
|
Test that a custom app instance is created if the function
|
||||||
gets passed a classname
|
gets passed a custom app class
|
||||||
"""
|
"""
|
||||||
from nomodel_app import MyApp
|
from nomodel_app import MyApp
|
||||||
rv = cache.load_app('nomodel_app.MyApp')
|
rv = cache.load_app('nomodel_app', False, MyApp)
|
||||||
app = cache.app_instances[0]
|
app = cache.app_instances[0]
|
||||||
self.assertEqual(len(cache.app_instances), 1)
|
self.assertEqual(len(cache.app_instances), 1)
|
||||||
self.assertEqual(app.name, 'nomodel_app')
|
self.assertEqual(app.name, 'nomodel_app')
|
||||||
@ -278,10 +281,11 @@ class LoadAppTests(AppCacheTestCase):
|
|||||||
"""
|
"""
|
||||||
Test that custom models are imported correctly
|
Test that custom models are imported correctly
|
||||||
"""
|
"""
|
||||||
rv = cache.load_app('model_app.MyApp')
|
from nomodel_app import MyApp
|
||||||
|
rv = cache.load_app('model_app', False, MyApp)
|
||||||
app = cache.app_instances[0]
|
app = cache.app_instances[0]
|
||||||
self.assertEqual(app.models_module.__name__, 'model_app.othermodels')
|
self.assertEqual(app.models_module.__name__, 'model_app.models')
|
||||||
self.assertEqual(rv.__name__, 'model_app.othermodels')
|
self.assertEqual(rv.__name__, 'model_app.models')
|
||||||
|
|
||||||
def test_twice(self):
|
def test_twice(self):
|
||||||
"""
|
"""
|
||||||
@ -304,10 +308,11 @@ class LoadAppTests(AppCacheTestCase):
|
|||||||
"""
|
"""
|
||||||
Test that the installed_apps attribute is populated correctly
|
Test that the installed_apps attribute is populated correctly
|
||||||
"""
|
"""
|
||||||
settings.INSTALLED_APPS = ('model_app', 'nomodel_app.MyApp',)
|
settings.APP_CLASSES = ('nomodel_app.MyApp',)
|
||||||
|
settings.INSTALLED_APPS = ('model_app',)
|
||||||
# populate cache
|
# populate cache
|
||||||
cache.get_app_errors()
|
cache.get_app_errors()
|
||||||
self.assertEqual(cache.installed_apps, ['model_app', 'nomodel_app',])
|
self.assertEqual(cache.installed_apps, ['nomodel_app', 'model_app',])
|
||||||
|
|
||||||
class RegisterModelsTests(AppCacheTestCase):
|
class RegisterModelsTests(AppCacheTestCase):
|
||||||
"""Tests for the register_models function"""
|
"""Tests for the register_models function"""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user