Ticket #21719: 21719-postponing-wip.patch
File 21719-postponing-wip.patch, 8.4 KB (added by , 11 years ago) |
---|
-
django/apps/registry.py
diff --git a/django/apps/registry.py b/django/apps/registry.py index 41095bd..913cc4b 100644
a b from django.utils import lru_cache 9 9 from django.utils.deprecation import RemovedInDjango19Warning 10 10 from django.utils._os import upath 11 11 12 from .config import AppConfig 12 from .config import AppConfig, MODELS_MODULE_NAME 13 13 14 14 15 15 class Apps(object): … … class Apps(object): 48 48 # Lock for thread-safe population. 49 49 self._lock = threading.Lock() 50 50 51 # Models imported before their apps. 52 self._orphan_models = [] 53 51 54 # Pending lookups for lazy relations. 52 55 self._pending_lookups = {} 53 56 … … class Apps(object): 100 103 "Application names aren't unique, " 101 104 "duplicates: %s" % ", ".join(duplicates)) 102 105 106 # Handle models loaded prematurely. 107 orphan_models, self._orphan_models = self._orphan_models, None 108 for orphan_model in orphan_models: 109 self.register_model(orphan_model) 110 103 111 # Load models. 104 112 for app_config in self.app_configs.values(): 105 113 all_models = self.all_models[app_config.label] … … class Apps(object): 189 197 app_label, model_name = app_label.split('.') 190 198 return self.get_app_config(app_label).get_model(model_name.lower()) 191 199 192 def register_model(self, app_label,model):200 def register_model(self, model): 193 201 # Since this method is called when models are imported, it cannot 194 202 # perform imports because of the risk of import loops. It mustn't 195 203 # call get_app_config(). 204 if model._meta.app_label is None: 205 app_config = self.get_containing_app_config(model.__module__) 206 else: 207 app_config = self.app_configs.get(model._meta.app_label) 208 209 if app_config is None: 210 if self._orphan_models is not None: 211 # Applications are still loading. Orphaning is allowed. 212 self._orphan_models.append(model) 213 return 214 else: 215 # If the model isn't in an installed application (#21680), use 216 # the legacy logic to figure out the app_label by looking one 217 # level up from the package or module named 'models'. If no 218 # such package or module exists, fall back to looking one 219 # level up from the module this model is defined in. 220 221 # For 'django.contrib.sites.models', this would be 'sites'. 222 # For 'geo.models.places' this would be 'geo'. 223 224 msg = ( 225 "Model class %s.%s doesn't declare an explicit app_label " 226 "and either isn't in an application in INSTALLED_APPS. " % 227 (model.__module__, model.__name__)) 228 if model._meta.abstract: 229 msg += "Its app_label will be set to None in Django 1.9." 230 else: 231 msg += "This will no longer be supported in Django 1.9." 232 warnings.warn(msg, RemovedInDjango19Warning, stacklevel=2) 233 234 package_components = model.__module__.split('.') 235 package_components.reverse() # find the last occurrence of 'models' 236 try: 237 app_label_index = package_components.index(MODELS_MODULE_NAME) + 1 238 except ValueError: 239 app_label_index = 1 240 model._meta.app_label = package_components[app_label_index] 241 else: 242 model._meta.app_label = app_config.label 243 196 244 model_name = model._meta.model_name 197 app_models = self.all_models[ app_label]245 app_models = self.all_models[model._meta.app_label] 198 246 if model_name in app_models: 199 247 raise RuntimeError( 200 248 "Conflicting '%s' models in application '%s': %s and %s." % … … class Apps(object): 416 464 "register_models(app_label, *models) is deprecated.", 417 465 RemovedInDjango19Warning, stacklevel=2) 418 466 for model in models: 419 self.register_model( app_label,model)467 self.register_model(model) 420 468 421 469 422 470 apps = Apps(installed_apps=None) -
django/db/models/base.py
diff --git a/django/db/models/base.py b/django/db/models/base.py index ba89e6e..1e5f57a 100644
a b class ModelBase(type): 89 89 meta = attr_meta 90 90 base_meta = getattr(new_class, '_meta', None) 91 91 92 # Look for an application configuration to attach the model to. 93 app_config = apps.get_containing_app_config(module) 94 95 if getattr(meta, 'app_label', None) is None: 96 97 if app_config is None: 98 # If the model is imported before the configuration for its 99 # application is created (#21719), or isn't in an installed 100 # application (#21680), use the legacy logic to figure out the 101 # app_label by looking one level up from the package or module 102 # named 'models'. If no such package or module exists, fall 103 # back to looking one level up from the module this model is 104 # defined in. 105 106 # For 'django.contrib.sites.models', this would be 'sites'. 107 # For 'geo.models.places' this would be 'geo'. 108 109 msg = ( 110 "Model class %s.%s doesn't declare an explicit app_label " 111 "and either isn't in an application in INSTALLED_APPS or " 112 "else was imported before its application was loaded. " % 113 (module, name)) 114 if abstract: 115 msg += "Its app_label will be set to None in Django 1.9." 116 else: 117 msg += "This will no longer be supported in Django 1.9." 118 warnings.warn(msg, RemovedInDjango19Warning, stacklevel=2) 119 120 model_module = sys.modules[new_class.__module__] 121 package_components = model_module.__name__.split('.') 122 package_components.reverse() # find the last occurrence of 'models' 123 try: 124 app_label_index = package_components.index(MODELS_MODULE_NAME) + 1 125 except ValueError: 126 app_label_index = 1 127 kwargs = {"app_label": package_components[app_label_index]} 128 129 else: 130 kwargs = {"app_label": app_config.label} 131 132 else: 133 kwargs = {} 92 new_class.add_to_class('_meta', Options(meta)) 93 new_class._meta.apps.register_model(new_class) 134 94 135 new_class.add_to_class('_meta', Options(meta, **kwargs))136 95 if not abstract: 137 96 new_class.add_to_class( 138 97 'DoesNotExist', … … class ModelBase(type): 293 252 # little differently from normal models. 294 253 attr_meta.abstract = False 295 254 new_class.Meta = attr_meta 296 return new_class 255 else: 256 new_class._prepare() 297 257 298 new_class._prepare()299 new_class._meta.apps.register_model(new_class._meta.app_label, new_class)300 258 return new_class 301 259 302 260 def copy_managers(cls, base_managers): -
django/db/models/options.py
diff --git a/django/db/models/options.py b/django/db/models/options.py index d204bcf..cfbbb8b 100644
a b from django.db.models.fields.related import ManyToManyRel 10 10 from django.db.models.fields import AutoField, FieldDoesNotExist 11 11 from django.db.models.fields.proxy import OrderWrt 12 12 from django.utils import six 13 from django.utils.deprecation import RemovedInDjango18Warning 13 from django.utils.deprecation import RemovedInDjango18Warning, RemovedInDjango19Warning 14 14 from django.utils.encoding import force_text, smart_text, python_2_unicode_compatible 15 15 from django.utils.functional import cached_property 16 16 from django.utils.text import camel_case_to_spaces … … def normalize_together(option_together): 49 49 50 50 @python_2_unicode_compatible 51 51 class Options(object): 52 52 53 def __init__(self, meta, app_label=None): 54 if app_label is not None: 55 warnings.warn( 56 "The app_label argument of Options is deprecated.", 57 RemovedInDjango19Warning, stacklevel=2) 53 58 self.local_fields = [] 54 59 self.local_many_to_many = [] 55 60 self.virtual_fields = []