mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	[1.8.x] Fixed #24287 -- Added friendly error if a model is in a models.py outside an installed app.
This commit is contained in:
		| @@ -2,34 +2,41 @@ from __future__ import unicode_literals | ||||
|  | ||||
| import copy | ||||
| import inspect | ||||
| from itertools import chain | ||||
| import sys | ||||
| import warnings | ||||
| from itertools import chain | ||||
|  | ||||
| from django.apps import apps | ||||
| from django.apps.config import MODELS_MODULE_NAME | ||||
| from django.conf import settings | ||||
| from django.core import checks | ||||
| from django.core.exceptions import (FieldDoesNotExist, ObjectDoesNotExist, | ||||
|     MultipleObjectsReturned, FieldError, ValidationError, NON_FIELD_ERRORS) | ||||
| from django.db import (router, connections, transaction, DatabaseError, | ||||
|     DEFAULT_DB_ALIAS, DJANGO_VERSION_PICKLE_KEY) | ||||
| from django.core.exceptions import ( | ||||
|     NON_FIELD_ERRORS, FieldDoesNotExist, FieldError, ImproperlyConfigured, | ||||
|     MultipleObjectsReturned, ObjectDoesNotExist, ValidationError, | ||||
| ) | ||||
| from django.db import ( | ||||
|     DEFAULT_DB_ALIAS, DJANGO_VERSION_PICKLE_KEY, DatabaseError, connections, | ||||
|     router, transaction, | ||||
| ) | ||||
| from django.db.models import signals | ||||
| from django.db.models.constants import LOOKUP_SEP | ||||
| from django.db.models.deletion import Collector | ||||
| from django.db.models.fields import AutoField | ||||
| from django.db.models.fields.related import (ForeignObjectRel, ManyToOneRel, | ||||
|     OneToOneField, add_lazy_relation) | ||||
| from django.db.models.fields.related import ( | ||||
|     ForeignObjectRel, ManyToOneRel, OneToOneField, add_lazy_relation, | ||||
| ) | ||||
| from django.db.models.manager import ensure_default_manager | ||||
| from django.db.models.options import Options | ||||
| from django.db.models.query import Q | ||||
| from django.db.models.query_utils import DeferredAttribute, deferred_class_factory | ||||
| from django.db.models.query_utils import ( | ||||
|     DeferredAttribute, deferred_class_factory, | ||||
| ) | ||||
| from django.utils import six | ||||
| from django.utils.deprecation import RemovedInDjango19Warning | ||||
| from django.utils.encoding import force_str, force_text | ||||
| from django.utils.functional import curry | ||||
| from django.utils.six.moves import zip | ||||
| from django.utils.text import get_text_list, capfirst | ||||
| from django.utils.text import capfirst, get_text_list | ||||
| from django.utils.translation import ugettext_lazy as _ | ||||
| from django.utils.version import get_version | ||||
|  | ||||
| @@ -115,8 +122,14 @@ class ModelBase(type): | ||||
|                     app_label_index = package_components.index(MODELS_MODULE_NAME) + 1 | ||||
|                 except ValueError: | ||||
|                     app_label_index = 1 | ||||
|                 kwargs = {"app_label": package_components[app_label_index]} | ||||
|  | ||||
|                 try: | ||||
|                     kwargs = {"app_label": package_components[app_label_index]} | ||||
|                 except IndexError: | ||||
|                     raise ImproperlyConfigured( | ||||
|                         'Unable to detect the app label for model "%s." ' | ||||
|                         'Ensure that its module, "%s", is located inside an installed ' | ||||
|                         'app.' % (new_class.__name__, model_module.__name__) | ||||
|                     ) | ||||
|             else: | ||||
|                 kwargs = {"app_label": app_config.label} | ||||
|  | ||||
|   | ||||
| @@ -1,8 +1,11 @@ | ||||
| from __future__ import unicode_literals | ||||
|  | ||||
| import os | ||||
| import sys | ||||
|  | ||||
| from django.apps import apps | ||||
| from django.core.exceptions import ImproperlyConfigured | ||||
| from django.db import models | ||||
| from django.test import TestCase | ||||
| from django.test.utils import extend_sys_path | ||||
| from django.utils._os import upath | ||||
| @@ -75,3 +78,26 @@ class GetModelsTest(TestCase): | ||||
|         self.assertNotIn( | ||||
|             "NotInstalledModel", | ||||
|             [m.__name__ for m in apps.get_models()]) | ||||
|  | ||||
|     def test_exception_raised_if_model_declared_outside_app(self): | ||||
|  | ||||
|         class FakeModule(models.Model): | ||||
|             __name__ = str("models_that_do_not_live_in_an_app") | ||||
|  | ||||
|         sys.modules['models_not_in_app'] = FakeModule | ||||
|  | ||||
|         def declare_model_outside_app(): | ||||
|             models.base.ModelBase.__new__( | ||||
|                 models.base.ModelBase, | ||||
|                 str('Outsider'), | ||||
|                 (models.Model,), | ||||
|                 {'__module__': 'models_not_in_app'}) | ||||
|  | ||||
|         msg = ( | ||||
|             'Unable to detect the app label for model "Outsider." ' | ||||
|             'Ensure that its module, "models_that_do_not_live_in_an_app", ' | ||||
|             'is located inside an installed app.' | ||||
|         ) | ||||
|  | ||||
|         with self.assertRaisesMessage(ImproperlyConfigured, msg): | ||||
|             declare_model_outside_app() | ||||
|   | ||||
		Reference in New Issue
	
	Block a user