Author: arthurk Date: 2010-09-12 00:34:58 -0500 (Sun, 12 Sep 2010) New Revision: 13759
Modified: django/branches/soc2010/app-loading/django/conf/global_settings.py django/branches/soc2010/app-loading/django/core/apps.py django/branches/soc2010/app-loading/django/db/models/options.py django/branches/soc2010/app-loading/tests/appcachetests/runtests.py Log: [soc2010/app-loading] implement APP_CLASSES setting Modified: django/branches/soc2010/app-loading/django/conf/global_settings.py =================================================================== --- django/branches/soc2010/app-loading/django/conf/global_settings.py 2010-09-12 02:09:17 UTC (rev 13758) +++ django/branches/soc2010/app-loading/django/conf/global_settings.py 2010-09-12 05:34:58 UTC (rev 13759) @@ -170,6 +170,9 @@ EMAIL_HOST_PASSWORD = '' EMAIL_USE_TLS = False +# List of strings representing installed app classes. +APP_CLASSES = () + # List of strings representing installed apps. INSTALLED_APPS = () Modified: django/branches/soc2010/app-loading/django/core/apps.py =================================================================== --- django/branches/soc2010/app-loading/django/core/apps.py 2010-09-12 02:09:17 UTC (rev 13758) +++ django/branches/soc2010/app-loading/django/core/apps.py 2010-09-12 05:34:58 UTC (rev 13759) @@ -33,7 +33,7 @@ return self.name def __repr__(self): - return '<App: %s>' % self.name + return '<%s: %s>' % (self.__class__.__name__, self.name) class AppCache(object): """ @@ -78,10 +78,19 @@ try: if self.loaded: 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: if app_name in self.handled: continue self.load_app(app_name, True) + if not self.nesting_level: for app_name in self.postponed: self.load_app(app_name) @@ -111,7 +120,7 @@ finally: 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 model module. @@ -119,20 +128,7 @@ self.handled[app_name] = None self.nesting_level += 1 - try: - 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 + app_module = import_module(app_name) # check if an app instance with that name already exists app_instance = self.find_app(app_name) @@ -144,10 +140,11 @@ app_instance_name = app_name app_instance = app_class(app_instance_name) app_instance.module = app_module + app_instance.path = app_name self.app_instances.append(app_instance) 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 try: models_path = app_instance.models_path @@ -179,7 +176,7 @@ self.nesting_level -= 1 app_instance.models_module = models return models - + def find_app(self, name): "Returns the App instance that matches name" if '.' in name: @@ -211,9 +208,9 @@ self._populate() self.write_lock.acquire() try: - for app_name in self.installed_apps: - if app_label == app_name.split('.')[-1]: - mod = self.load_app(app_name, False) + for app in self.app_instances: + if app_label == app.name: + mod = self.load_app(app.path, False) if mod is None: if emptyOK: return None Modified: django/branches/soc2010/app-loading/django/db/models/options.py =================================================================== --- django/branches/soc2010/app-loading/django/db/models/options.py 2010-09-12 02:09:17 UTC (rev 13758) +++ django/branches/soc2010/app-loading/django/db/models/options.py 2010-09-12 05:34:58 UTC (rev 13759) @@ -99,7 +99,13 @@ # If the db_table wasn't provided, use the db_prefix + module_name. if not self.db_table: app_instance = cache.find_app(self.app_label) - self.db_table = "%s_%s" % (app_instance.db_prefix, self.module_name) + 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 = truncate_name(self.db_table, connection.ops.max_name_length()) def _prepare(self, model): Modified: django/branches/soc2010/app-loading/tests/appcachetests/runtests.py =================================================================== --- django/branches/soc2010/app-loading/tests/appcachetests/runtests.py 2010-09-12 02:09:17 UTC (rev 13758) +++ django/branches/soc2010/app-loading/tests/appcachetests/runtests.py 2010-09-12 05:34:58 UTC (rev 13759) @@ -18,10 +18,13 @@ def setUp(self): self.old_installed_apps = settings.INSTALLED_APPS + self.old_app_classes = settings.APP_CLASSES + settings.APP_CLASSES = () settings.INSTALLED_APPS = () def tearDown(self): settings.INSTALLED_APPS = self.old_installed_apps + settings.APP_CLASSES = self.old_app_classes # The appcache imports models modules. We need to delete the # imported module from sys.modules after the test has run. @@ -102,7 +105,7 @@ Test that an exception is raised if two app instances 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) class GetAppTests(AppCacheTestCase): @@ -264,10 +267,10 @@ def test_custom_app(self): """ 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 - rv = cache.load_app('nomodel_app.MyApp') + rv = cache.load_app('nomodel_app', False, MyApp) app = cache.app_instances[0] self.assertEqual(len(cache.app_instances), 1) self.assertEqual(app.name, 'nomodel_app') @@ -278,10 +281,11 @@ """ 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] - self.assertEqual(app.models_module.__name__, 'model_app.othermodels') - self.assertEqual(rv.__name__, 'model_app.othermodels') + self.assertEqual(app.models_module.__name__, 'model_app.models') + self.assertEqual(rv.__name__, 'model_app.models') def test_twice(self): """ @@ -304,10 +308,11 @@ """ 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 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): """Tests for the register_models function""" -- You received this message because you are subscribed to the Google Groups "Django updates" group. To post to this group, send email to django-upda...@googlegroups.com. To unsubscribe from this group, send email to django-updates+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/django-updates?hl=en.