[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:
parent
64a9540829
commit
ac576e9f45
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue