mirror of https://github.com/django/django.git
[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 copy
|
||||||
import inspect
|
import inspect
|
||||||
from itertools import chain
|
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
|
from itertools import chain
|
||||||
|
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
from django.apps.config import MODELS_MODULE_NAME
|
from django.apps.config import MODELS_MODULE_NAME
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core import checks
|
from django.core import checks
|
||||||
from django.core.exceptions import (FieldDoesNotExist, ObjectDoesNotExist,
|
from django.core.exceptions import (
|
||||||
MultipleObjectsReturned, FieldError, ValidationError, NON_FIELD_ERRORS)
|
NON_FIELD_ERRORS, FieldDoesNotExist, FieldError, ImproperlyConfigured,
|
||||||
from django.db import (router, connections, transaction, DatabaseError,
|
MultipleObjectsReturned, ObjectDoesNotExist, ValidationError,
|
||||||
DEFAULT_DB_ALIAS, DJANGO_VERSION_PICKLE_KEY)
|
)
|
||||||
|
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 import signals
|
||||||
from django.db.models.constants import LOOKUP_SEP
|
from django.db.models.constants import LOOKUP_SEP
|
||||||
from django.db.models.deletion import Collector
|
from django.db.models.deletion import Collector
|
||||||
from django.db.models.fields import AutoField
|
from django.db.models.fields import AutoField
|
||||||
from django.db.models.fields.related import (ForeignObjectRel, ManyToOneRel,
|
from django.db.models.fields.related import (
|
||||||
OneToOneField, add_lazy_relation)
|
ForeignObjectRel, ManyToOneRel, OneToOneField, add_lazy_relation,
|
||||||
|
)
|
||||||
from django.db.models.manager import ensure_default_manager
|
from django.db.models.manager import ensure_default_manager
|
||||||
from django.db.models.options import Options
|
from django.db.models.options import Options
|
||||||
from django.db.models.query import Q
|
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 import six
|
||||||
from django.utils.deprecation import RemovedInDjango19Warning
|
from django.utils.deprecation import RemovedInDjango19Warning
|
||||||
from django.utils.encoding import force_str, force_text
|
from django.utils.encoding import force_str, force_text
|
||||||
from django.utils.functional import curry
|
from django.utils.functional import curry
|
||||||
from django.utils.six.moves import zip
|
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.translation import ugettext_lazy as _
|
||||||
from django.utils.version import get_version
|
from django.utils.version import get_version
|
||||||
|
|
||||||
|
@ -115,8 +122,14 @@ class ModelBase(type):
|
||||||
app_label_index = package_components.index(MODELS_MODULE_NAME) + 1
|
app_label_index = package_components.index(MODELS_MODULE_NAME) + 1
|
||||||
except ValueError:
|
except ValueError:
|
||||||
app_label_index = 1
|
app_label_index = 1
|
||||||
|
try:
|
||||||
kwargs = {"app_label": package_components[app_label_index]}
|
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:
|
else:
|
||||||
kwargs = {"app_label": app_config.label}
|
kwargs = {"app_label": app_config.label}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
from django.apps import apps
|
from django.apps import apps
|
||||||
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
|
from django.db import models
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
from django.test.utils import extend_sys_path
|
from django.test.utils import extend_sys_path
|
||||||
from django.utils._os import upath
|
from django.utils._os import upath
|
||||||
|
@ -75,3 +78,26 @@ class GetModelsTest(TestCase):
|
||||||
self.assertNotIn(
|
self.assertNotIn(
|
||||||
"NotInstalledModel",
|
"NotInstalledModel",
|
||||||
[m.__name__ for m in apps.get_models()])
|
[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