diff --git a/django/db/models/base.py b/django/db/models/base.py index 79a1233df7..b3a4ab361f 100644 --- a/django/db/models/base.py +++ b/django/db/models/base.py @@ -34,12 +34,11 @@ class ModelBase(type): model_module = sys.modules[new_class.__module__] - # Figure out the app_label by looking one level up. - # For 'django.contrib.sites.models', this would be 'sites'. - app_label = model_module.__name__.split('.')[-2] - - # Cache the app label. - new_class._meta.app_label = app_label + if not hasattr(new_class._meta, 'app_label') or \ + new_class._meta.app_label is None: + # Figure out the app_label by looking one level up. + # For 'django.contrib.sites.models', this would be 'sites'. + new_class._meta.app_label = model_module.__name__.split('.')[-2] # Add all attributes to the class. for obj_name, obj in attrs.items(): diff --git a/django/db/models/loading.py b/django/db/models/loading.py index ba33024a31..2464a632a6 100644 --- a/django/db/models/loading.py +++ b/django/db/models/loading.py @@ -3,7 +3,7 @@ from django.conf import settings from django.core.exceptions import ImproperlyConfigured -__all__ = ('get_apps', 'get_app', 'get_models', 'get_model') +__all__ = ('get_apps', 'get_app', 'get_models', 'get_model', 'register_models') _app_list = None # Cache of installed apps. @@ -50,3 +50,14 @@ def get_model(app_label, model_name): if model._meta.object_name.lower() == model_name and \ model._meta.app_label == app_label: return model + +def register_models(app_mod, *models): + """ + Use this from an app's models.py module to register imported Model classes + as belonging to the app. e.g.: + + register_models(sys.modules[__name__], Article, Reporter) + """ + if not hasattr(app_mod, '_MODELS'): + app_mod._MODELS = [] + app_mod._MODELS.extend(models) diff --git a/django/db/models/options.py b/django/db/models/options.py index 1c0779ec81..c9ccd293f7 100644 --- a/django/db/models/options.py +++ b/django/db/models/options.py @@ -10,7 +10,8 @@ import re get_verbose_name = lambda class_name: re.sub('([A-Z])', ' \\1', class_name).lower().strip() DEFAULT_NAMES = ('verbose_name', 'verbose_name_plural', 'db_table', 'ordering', - 'unique_together', 'permissions', 'get_latest_by', 'order_with_respect_to') + 'unique_together', 'permissions', 'get_latest_by', + 'order_with_respect_to', 'app_label') class Options: def __init__(self, meta):