Loading django/db/models/base.py +24 −11 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -115,8 +122,14 @@ class ModelBase(type): app_label_index = package_components.index(MODELS_MODULE_NAME) + 1 except ValueError: app_label_index = 1 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} Loading tests/app_loading/tests.py +26 −0 Original line number Diff line number Diff line 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 Loading Loading @@ -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() Loading
django/db/models/base.py +24 −11 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -115,8 +122,14 @@ class ModelBase(type): app_label_index = package_components.index(MODELS_MODULE_NAME) + 1 except ValueError: app_label_index = 1 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} Loading
tests/app_loading/tests.py +26 −0 Original line number Diff line number Diff line 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 Loading Loading @@ -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()