mirror of
https://github.com/django/django.git
synced 2025-10-26 07:06:08 +00:00
Made it possible to change an application's label in its configuration.
Fixed #21683.
This commit is contained in:
@@ -201,6 +201,27 @@ class Apps(object):
|
||||
app_config = self.app_configs.get(app_name.rpartition(".")[2])
|
||||
return app_config is not None and app_config.name == app_name
|
||||
|
||||
def get_containing_app_config(self, object_name):
|
||||
"""
|
||||
Look for an app config containing a given object.
|
||||
|
||||
object_name is the dotted Python path to the object.
|
||||
|
||||
Returns the app config for the inner application in case of nesting.
|
||||
Returns None if the object isn't in any registered app config.
|
||||
|
||||
It's safe to call this method at import time, even while the registry
|
||||
is being populated.
|
||||
"""
|
||||
candidates = []
|
||||
for app_config in self.app_configs.values():
|
||||
if object_name.startswith(app_config.name):
|
||||
subpath = object_name[len(app_config.name):]
|
||||
if subpath == '' or subpath[0] == '.':
|
||||
candidates.append(app_config)
|
||||
if candidates:
|
||||
return sorted(candidates, key=lambda ac: -len(ac.name))[0]
|
||||
|
||||
def get_registered_model(self, app_label, model_name):
|
||||
"""
|
||||
Similar to get_model(), but doesn't require that an app exists with
|
||||
|
||||
@@ -76,9 +76,7 @@ class AppConfigStub(AppConfig):
|
||||
Stubs a Django AppConfig. Only provides a label and a dict of models.
|
||||
"""
|
||||
def __init__(self, label):
|
||||
self.label = label
|
||||
self.path = None
|
||||
super(AppConfigStub, self).__init__(None, None)
|
||||
super(AppConfigStub, self).__init__(label, None)
|
||||
|
||||
def import_models(self, all_models):
|
||||
self.models = all_models
|
||||
|
||||
@@ -86,23 +86,35 @@ class ModelBase(type):
|
||||
meta = attr_meta
|
||||
base_meta = getattr(new_class, '_meta', None)
|
||||
|
||||
# Look for an application configuration to attach the model to.
|
||||
app_config = apps.get_containing_app_config(module)
|
||||
|
||||
if getattr(meta, 'app_label', None) is None:
|
||||
# Figure out the app_label by looking one level up from the package
|
||||
# or module named 'models'. If no such package or module exists,
|
||||
# fall back to looking one level up from the module this model is
|
||||
# defined in.
|
||||
|
||||
# For 'django.contrib.sites.models', this would be 'sites'.
|
||||
# For 'geo.models.places' this would be 'geo'.
|
||||
if app_config is None:
|
||||
# If the model is imported before the configuration for its
|
||||
# application is created (#21719), or isn't in an installed
|
||||
# application (#21680), use the legacy logic to figure out the
|
||||
# app_label by looking one level up from the package or module
|
||||
# named 'models'. If no such package or module exists, fall
|
||||
# back to looking one level up from the module this model is
|
||||
# defined in.
|
||||
|
||||
# For 'django.contrib.sites.models', this would be 'sites'.
|
||||
# For 'geo.models.places' this would be 'geo'.
|
||||
|
||||
model_module = sys.modules[new_class.__module__]
|
||||
package_components = model_module.__name__.split('.')
|
||||
package_components.reverse() # find the last occurrence of 'models'
|
||||
try:
|
||||
app_label_index = package_components.index(MODELS_MODULE_NAME) + 1
|
||||
except ValueError:
|
||||
app_label_index = 1
|
||||
kwargs = {"app_label": package_components[app_label_index]}
|
||||
|
||||
else:
|
||||
kwargs = {"app_label": app_config.label}
|
||||
|
||||
model_module = sys.modules[new_class.__module__]
|
||||
package_components = model_module.__name__.split('.')
|
||||
package_components.reverse() # find the last occurrence of 'models'
|
||||
try:
|
||||
app_label_index = package_components.index(MODELS_MODULE_NAME) + 1
|
||||
except ValueError:
|
||||
app_label_index = 1
|
||||
kwargs = {"app_label": package_components[app_label_index]}
|
||||
else:
|
||||
kwargs = {}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user