diff --git a/django/contrib/auth/checks.py b/django/contrib/auth/checks.py index 2d47377c9ad..75f95423468 100644 --- a/django/contrib/auth/checks.py +++ b/django/contrib/auth/checks.py @@ -6,10 +6,22 @@ from django.conf import settings from django.core import checks -def check_user_model(**kwargs): - errors = [] +def check_user_model(app_configs=None, **kwargs): + if app_configs is None: + cls = apps.get_model(settings.AUTH_USER_MODEL) + else: + app_label, model_name = settings.AUTH_USER_MODEL.split('.') + for app_config in app_configs: + if app_config.label == app_label: + cls = app_config.get_model(model_name) + break + else: + # Checks might be run against a set of app configs that don't + # include the specified user model. In this case we simply don't + # perform the checks defined below. + return [] - cls = apps.get_model(settings.AUTH_USER_MODEL) + errors = [] # Check that REQUIRED_FIELDS is a list if not isinstance(cls.REQUIRED_FIELDS, (list, tuple)): diff --git a/django/contrib/contenttypes/checks.py b/django/contrib/contenttypes/checks.py index 1b3df21353d..3db58cfdbe9 100644 --- a/django/contrib/contenttypes/checks.py +++ b/django/contrib/contenttypes/checks.py @@ -1,17 +1,23 @@ # -*- coding: utf-8 -*- from __future__ import unicode_literals +from itertools import chain + from django.apps import apps from django.utils import six -def check_generic_foreign_keys(**kwargs): +def check_generic_foreign_keys(app_configs=None, **kwargs): from .fields import GenericForeignKey + if app_configs is None: + models = apps.get_models() + else: + models = chain.from_iterable(app_config.get_models() for app_config in app_configs) errors = [] fields = (obj - for cls in apps.get_models() - for obj in six.itervalues(vars(cls)) + for model in models + for obj in six.itervalues(vars(model)) if isinstance(obj, GenericForeignKey)) for field in fields: errors.extend(field.check()) diff --git a/django/core/checks/model_checks.py b/django/core/checks/model_checks.py index 3d0d56af58a..b312602c6c1 100644 --- a/django/core/checks/model_checks.py +++ b/django/core/checks/model_checks.py @@ -3,6 +3,7 @@ from __future__ import unicode_literals import inspect import types +from itertools import chain from django.apps import apps from django.core.checks import Error, Tags, register @@ -11,21 +12,24 @@ from django.core.checks import Error, Tags, register @register(Tags.models) def check_all_models(app_configs=None, **kwargs): errors = [] - for model in apps.get_models(): - if app_configs is None or model._meta.app_config in app_configs: - if not inspect.ismethod(model.check): - errors.append( - Error( - "The '%s.check()' class method is " - "currently overridden by %r." % ( - model.__name__, model.check), - hint=None, - obj=model, - id='models.E020' - ) + if app_configs is None: + models = apps.get_models() + else: + models = chain.from_iterable(app_config.get_models() for app_config in app_configs) + for model in models: + if not inspect.ismethod(model.check): + errors.append( + Error( + "The '%s.check()' class method is " + "currently overridden by %r." % ( + model.__name__, model.check), + hint=None, + obj=model, + id='models.E020' ) - else: - errors.extend(model.check(**kwargs)) + ) + else: + errors.extend(model.check(**kwargs)) return errors diff --git a/tests/absolute_url_overrides/tests.py b/tests/absolute_url_overrides/tests.py index ab4ad0d0052..71874561126 100644 --- a/tests/absolute_url_overrides/tests.py +++ b/tests/absolute_url_overrides/tests.py @@ -1,7 +1,9 @@ from django.db import models from django.test import SimpleTestCase +from django.test.utils import isolate_apps +@isolate_apps('absolute_url_overrides') class AbsoluteUrlOverrideTests(SimpleTestCase): def test_get_absolute_url(self): diff --git a/tests/apps/tests.py b/tests/apps/tests.py index 9dad3cfb861..198b0a92c45 100644 --- a/tests/apps/tests.py +++ b/tests/apps/tests.py @@ -9,7 +9,7 @@ from django.contrib.admin.models import LogEntry from django.core.exceptions import AppRegistryNotReady, ImproperlyConfigured from django.db import models from django.test import SimpleTestCase, override_settings -from django.test.utils import extend_sys_path +from django.test.utils import extend_sys_path, isolate_apps from django.utils import six from django.utils._os import upath @@ -260,7 +260,8 @@ class AppsTests(SimpleTestCase): finally: apps.apps_ready = True - def test_lazy_model_operation(self): + @isolate_apps('apps', kwarg_name='apps') + def test_lazy_model_operation(self, apps): """ Tests apps.lazy_model_operation(). """ diff --git a/tests/auth_tests/models/__init__.py b/tests/auth_tests/models/__init__.py index ec6b6099db6..3f3bd897936 100644 --- a/tests/auth_tests/models/__init__.py +++ b/tests/auth_tests/models/__init__.py @@ -1,14 +1,10 @@ from .custom_permissions import CustomPermissionsUser -from .invalid_models import ( - CustomUserBadRequiredFields, CustomUserNonListRequiredFields, - CustomUserNonUniqueUsername, -) +from .invalid_models import CustomUserNonUniqueUsername from .is_active import IsActiveTestUser1 from .uuid_pk import UUIDUser from .with_foreign_key import CustomUserWithFK, Email __all__ = ( - 'CustomPermissionsUser', 'CustomUserNonUniqueUsername', - 'CustomUserNonListRequiredFields', 'CustomUserBadRequiredFields', - 'CustomUserWithFK', 'Email', 'IsActiveTestUser1', 'UUIDUser', + 'CustomPermissionsUser', 'CustomUserWithFK', 'Email', + 'IsActiveTestUser1', 'UUIDUser', 'CustomUserNonUniqueUsername', ) diff --git a/tests/auth_tests/models/invalid_models.py b/tests/auth_tests/models/invalid_models.py index 4e2307ea59c..123ed4d8655 100644 --- a/tests/auth_tests/models/invalid_models.py +++ b/tests/auth_tests/models/invalid_models.py @@ -18,21 +18,3 @@ class CustomUserNonUniqueUsername(AbstractBaseUser): REQUIRED_FIELDS = ['email'] objects = UserManager() - - -class CustomUserNonListRequiredFields(AbstractBaseUser): - "A user with a non-list REQUIRED_FIELDS" - username = models.CharField(max_length=30, unique=True) - date_of_birth = models.DateField() - - USERNAME_FIELD = 'username' - REQUIRED_FIELDS = 'date_of_birth' - - -class CustomUserBadRequiredFields(AbstractBaseUser): - "A user with a USERNAME_FIELD that appears in REQUIRED_FIELDS (invalid)" - username = models.CharField(max_length=30, unique=True) - date_of_birth = models.DateField() - - USERNAME_FIELD = 'username' - REQUIRED_FIELDS = ['username', 'date_of_birth'] diff --git a/tests/auth_tests/test_management.py b/tests/auth_tests/test_management.py index e933caa027c..a9418474744 100644 --- a/tests/auth_tests/test_management.py +++ b/tests/auth_tests/test_management.py @@ -11,23 +11,24 @@ from django.contrib.auth.management import create_permissions from django.contrib.auth.management.commands import ( changepassword, createsuperuser, ) -from django.contrib.auth.models import Group, Permission, User +from django.contrib.auth.models import ( + AbstractBaseUser, Group, Permission, User, +) from django.contrib.auth.tests.custom_user import CustomUser from django.contrib.contenttypes.models import ContentType from django.core import checks, exceptions from django.core.management import call_command from django.core.management.base import CommandError +from django.db import models from django.test import ( SimpleTestCase, TestCase, override_settings, override_system_checks, ) +from django.test.utils import isolate_apps from django.utils import six from django.utils.encoding import force_str from django.utils.translation import ugettext_lazy as _ -from .models import ( - CustomUserBadRequiredFields, CustomUserNonListRequiredFields, - CustomUserNonUniqueUsername, CustomUserWithFK, Email, -) +from .models import CustomUserNonUniqueUsername, CustomUserWithFK, Email def mock_inputs(inputs): @@ -568,9 +569,17 @@ class CreatesuperuserManagementCommandTestCase(TestCase): class CustomUserModelValidationTestCase(SimpleTestCase): @override_settings(AUTH_USER_MODEL='auth_tests.CustomUserNonListRequiredFields') @override_system_checks([check_user_model]) - def test_required_fields_is_list(self): - "REQUIRED_FIELDS should be a list." - errors = checks.run_checks() + @isolate_apps('auth_tests', kwarg_name='apps') + def test_required_fields_is_list(self, apps): + """REQUIRED_FIELDS should be a list.""" + class CustomUserNonListRequiredFields(AbstractBaseUser): + username = models.CharField(max_length=30, unique=True) + date_of_birth = models.DateField() + + USERNAME_FIELD = 'username' + REQUIRED_FIELDS = 'date_of_birth' + + errors = checks.run_checks(app_configs=apps.get_app_configs()) expected = [ checks.Error( "'REQUIRED_FIELDS' must be a list or tuple.", @@ -583,9 +592,17 @@ class CustomUserModelValidationTestCase(SimpleTestCase): @override_settings(AUTH_USER_MODEL='auth_tests.CustomUserBadRequiredFields') @override_system_checks([check_user_model]) - def test_username_not_in_required_fields(self): - "USERNAME_FIELD should not appear in REQUIRED_FIELDS." - errors = checks.run_checks() + @isolate_apps('auth_tests', kwarg_name='apps') + def test_username_not_in_required_fields(self, apps): + """USERNAME_FIELD should not appear in REQUIRED_FIELDS.""" + class CustomUserBadRequiredFields(AbstractBaseUser): + username = models.CharField(max_length=30, unique=True) + date_of_birth = models.DateField() + + USERNAME_FIELD = 'username' + REQUIRED_FIELDS = ['username', 'date_of_birth'] + + errors = checks.run_checks(apps.get_app_configs()) expected = [ checks.Error( ("The field named as the 'USERNAME_FIELD' for a custom user model " @@ -600,7 +617,10 @@ class CustomUserModelValidationTestCase(SimpleTestCase): @override_settings(AUTH_USER_MODEL='auth_tests.CustomUserNonUniqueUsername') @override_system_checks([check_user_model]) def test_username_non_unique(self): - "A non-unique USERNAME_FIELD should raise a model validation error." + """ + A non-unique USERNAME_FIELD should raise an error only if we use the + default authentication backend. Otherwise, an warning should be raised. + """ errors = checks.run_checks() expected = [ checks.Error( @@ -612,28 +632,19 @@ class CustomUserModelValidationTestCase(SimpleTestCase): ), ] self.assertEqual(errors, expected) - - @override_settings(AUTH_USER_MODEL='auth_tests.CustomUserNonUniqueUsername', - AUTHENTICATION_BACKENDS=[ - 'my.custom.backend', - ]) - @override_system_checks([check_user_model]) - def test_username_non_unique_with_custom_backend(self): - """ A non-unique USERNAME_FIELD should raise an error only if we use the - default authentication backend. Otherwise, an warning should be raised. - """ - errors = checks.run_checks() - expected = [ - checks.Warning( - ("'CustomUserNonUniqueUsername.username' is named as " - "the 'USERNAME_FIELD', but it is not unique."), - hint=('Ensure that your authentication backend(s) can handle ' - 'non-unique usernames.'), - obj=CustomUserNonUniqueUsername, - id='auth.W004', - ) - ] - self.assertEqual(errors, expected) + with self.settings(AUTHENTICATION_BACKENDS=['my.custom.backend']): + errors = checks.run_checks() + expected = [ + checks.Warning( + ("'CustomUserNonUniqueUsername.username' is named as " + "the 'USERNAME_FIELD', but it is not unique."), + hint=('Ensure that your authentication backend(s) can handle ' + 'non-unique usernames.'), + obj=CustomUserNonUniqueUsername, + id='auth.W004', + ) + ] + self.assertEqual(errors, expected) class PermissionTestCase(TestCase): diff --git a/tests/check_framework/test_model_field_deprecation.py b/tests/check_framework/test_model_field_deprecation.py index ce30803a616..21ece86bd40 100644 --- a/tests/check_framework/test_model_field_deprecation.py +++ b/tests/check_framework/test_model_field_deprecation.py @@ -1,11 +1,11 @@ from django.core import checks from django.db import models from django.test import SimpleTestCase - -from .tests import IsolateModelsMixin +from django.test.utils import isolate_apps -class TestDeprecatedField(IsolateModelsMixin, SimpleTestCase): +@isolate_apps('check_framework') +class TestDeprecatedField(SimpleTestCase): def test_default_details(self): class MyField(models.Field): system_check_deprecated_details = {} @@ -45,7 +45,8 @@ class TestDeprecatedField(IsolateModelsMixin, SimpleTestCase): ]) -class TestRemovedField(IsolateModelsMixin, SimpleTestCase): +@isolate_apps('check_framework') +class TestRemovedField(SimpleTestCase): def test_default_details(self): class MyField(models.Field): system_check_removed_details = {} diff --git a/tests/check_framework/test_multi_db.py b/tests/check_framework/test_multi_db.py index 168b2ea33f2..bfbeab0029d 100644 --- a/tests/check_framework/test_multi_db.py +++ b/tests/check_framework/test_multi_db.py @@ -1,8 +1,6 @@ from django.db import connections, models from django.test import TestCase, mock -from django.test.utils import override_settings - -from .tests import IsolateModelsMixin +from django.test.utils import isolate_apps, override_settings class TestRouter(object): @@ -14,7 +12,8 @@ class TestRouter(object): @override_settings(DATABASE_ROUTERS=[TestRouter()]) -class TestMultiDBChecks(IsolateModelsMixin, TestCase): +@isolate_apps('check_framework') +class TestMultiDBChecks(TestCase): multi_db = True def _patch_check_field_on(self, db): diff --git a/tests/check_framework/tests.py b/tests/check_framework/tests.py index 7ae7b633e07..90b8a944f07 100644 --- a/tests/check_framework/tests.py +++ b/tests/check_framework/tests.py @@ -11,7 +11,9 @@ from django.core.management import call_command from django.core.management.base import CommandError from django.db import models from django.test import SimpleTestCase -from django.test.utils import override_settings, override_system_checks +from django.test.utils import ( + isolate_apps, override_settings, override_system_checks, +) from django.utils.encoding import force_text from django.utils.six import StringIO @@ -254,23 +256,10 @@ class SilencingCheckTests(SimpleTestCase): self.assertEqual(err.getvalue(), '') -class IsolateModelsMixin(object): - def setUp(self): - self.current_models = apps.all_models[__package__] - self.saved_models = set(self.current_models) - - def tearDown(self): - for model in (set(self.current_models) - self.saved_models): - del self.current_models[model] - apps.clear_cache() - - -class CheckFrameworkReservedNamesTests(IsolateModelsMixin, SimpleTestCase): - @override_settings( - SILENCED_SYSTEM_CHECKS=['models.E20', 'fields.W342'], # ForeignKey(unique=True) - INSTALLED_APPS=['django.contrib.auth', 'django.contrib.contenttypes', 'check_framework'] - ) - def test_model_check_method_not_shadowed(self): +class CheckFrameworkReservedNamesTests(SimpleTestCase): + @isolate_apps('check_framework', kwarg_name='apps') + @override_system_checks([checks.model_checks.check_all_models]) + def test_model_check_method_not_shadowed(self, apps): class ModelWithAttributeCalledCheck(models.Model): check = 42 @@ -288,7 +277,7 @@ class CheckFrameworkReservedNamesTests(IsolateModelsMixin, SimpleTestCase): related_name='check', ) - errors = checks.run_checks() + errors = checks.run_checks(app_configs=apps.get_app_configs()) expected = [ Error( "The 'ModelWithAttributeCalledCheck.check()' class method is " diff --git a/tests/contenttypes_tests/tests.py b/tests/contenttypes_tests/tests.py index dd14eaad551..e5cf3d20109 100644 --- a/tests/contenttypes_tests/tests.py +++ b/tests/contenttypes_tests/tests.py @@ -12,8 +12,8 @@ from django.contrib.contenttypes.models import ContentType from django.contrib.sites.models import Site from django.core import checks from django.db import connections, models -from django.test import TestCase, override_settings -from django.test.utils import captured_stdout +from django.test import SimpleTestCase, TestCase, override_settings +from django.test.utils import captured_stdout, isolate_apps from django.utils.encoding import force_str, force_text from .models import Article, Author, SchemeIncludedURL @@ -114,20 +114,9 @@ class ContentTypesViewsTests(TestCase): self.assertEqual(force_text(ct), 'modelcreatedonthefly') -class IsolatedModelsTestCase(TestCase): - def setUp(self): - # The unmanaged models need to be removed after the test in order to - # prevent bad interactions with the flush operation in other tests. - self._old_models = apps.app_configs['contenttypes_tests'].models.copy() - - def tearDown(self): - apps.app_configs['contenttypes_tests'].models = self._old_models - apps.all_models['contenttypes_tests'] = self._old_models - apps.clear_cache() - - @override_settings(SILENCED_SYSTEM_CHECKS=['fields.W342']) # ForeignKey(unique=True) -class GenericForeignKeyTests(IsolatedModelsTestCase): +@isolate_apps('contenttypes_tests', attr_name='apps') +class GenericForeignKeyTests(SimpleTestCase): def test_str(self): class Model(models.Model): @@ -239,11 +228,12 @@ class GenericForeignKeyTests(IsolatedModelsTestCase): class Model(models.Model): content_object = MyGenericForeignKey() - errors = checks.run_checks() + errors = checks.run_checks(app_configs=self.apps.get_app_configs()) self.assertEqual(errors, ['performed!']) -class GenericRelationshipTests(IsolatedModelsTestCase): +@isolate_apps('contenttypes_tests') +class GenericRelationshipTests(SimpleTestCase): def test_valid_generic_relationship(self): class TaggedItem(models.Model): diff --git a/tests/defer_regress/tests.py b/tests/defer_regress/tests.py index cc1658ce585..ffb0b6e7759 100644 --- a/tests/defer_regress/tests.py +++ b/tests/defer_regress/tests.py @@ -3,7 +3,6 @@ from __future__ import unicode_literals from operator import attrgetter from django.apps import apps -from django.apps.registry import Apps from django.contrib.contenttypes.models import ContentType from django.contrib.sessions.backends.db import SessionStore from django.db import models @@ -12,6 +11,7 @@ from django.db.models.query_utils import ( DeferredAttribute, deferred_class_factory, ) from django.test import TestCase, override_settings +from django.test.utils import isolate_apps from .models import ( Base, Child, Derived, Feature, Item, ItemAndSimpleItem, Leaf, Location, @@ -265,22 +265,20 @@ class DeferRegressionTest(TestCase): deferred_cls = deferred_class_factory(Item, ()) self.assertFalse(deferred_cls._deferred) - def test_deferred_class_factory_apps_reuse(self): + @isolate_apps('defer_regress', kwarg_name='apps') + def test_deferred_class_factory_apps_reuse(self, apps): """ #25563 - model._meta.apps should be used for caching and retrieval of the created proxy class. """ - isolated_apps = Apps(['defer_regress']) - class BaseModel(models.Model): field = models.BooleanField() class Meta: - apps = isolated_apps app_label = 'defer_regress' deferred_model = deferred_class_factory(BaseModel, ['field']) - self.assertIs(deferred_model._meta.apps, isolated_apps) + self.assertIs(deferred_model._meta.apps, apps) self.assertIs(deferred_class_factory(BaseModel, ['field']), deferred_model) diff --git a/tests/foreign_object/tests.py b/tests/foreign_object/tests.py index bcdadc6d6d3..f83698175e6 100644 --- a/tests/foreign_object/tests.py +++ b/tests/foreign_object/tests.py @@ -1,11 +1,11 @@ import datetime from operator import attrgetter -from django.apps.registry import Apps from django.core.exceptions import FieldError from django.db import models from django.db.models.fields.related import ForeignObject from django.test import SimpleTestCase, TestCase, skipUnlessDBFeature +from django.test.utils import isolate_apps from django.utils import translation from .models import ( @@ -410,15 +410,13 @@ class MultiColumnFKTests(TestCase): class TestModelCheckTests(SimpleTestCase): + @isolate_apps('foreign_object') def test_check_composite_foreign_object(self): - test_apps = Apps(['foreign_object']) - class Parent(models.Model): a = models.PositiveIntegerField() b = models.PositiveIntegerField() class Meta: - apps = test_apps unique_together = (('a', 'b'),) class Child(models.Model): @@ -433,21 +431,16 @@ class TestModelCheckTests(SimpleTestCase): related_name='children', ) - class Meta: - apps = test_apps - self.assertEqual(Child._meta.get_field('parent').check(from_model=Child), []) + @isolate_apps('foreign_object') def test_check_subset_composite_foreign_object(self): - test_apps = Apps(['foreign_object']) - class Parent(models.Model): a = models.PositiveIntegerField() b = models.PositiveIntegerField() c = models.PositiveIntegerField() class Meta: - apps = test_apps unique_together = (('a', 'b'),) class Child(models.Model): @@ -463,7 +456,4 @@ class TestModelCheckTests(SimpleTestCase): related_name='children', ) - class Meta: - apps = test_apps - self.assertEqual(Child._meta.get_field('parent').check(from_model=Child), []) diff --git a/tests/invalid_models_tests/base.py b/tests/invalid_models_tests/base.py deleted file mode 100644 index 9459b313d6b..00000000000 --- a/tests/invalid_models_tests/base.py +++ /dev/null @@ -1,18 +0,0 @@ -# -*- encoding: utf-8 -*- -from __future__ import unicode_literals - -from django.apps import apps -from django.test import SimpleTestCase - - -class IsolatedModelsTestCase(SimpleTestCase): - - def setUp(self): - # The unmanaged models need to be removed after the test in order to - # prevent bad interactions with the flush operation in other tests. - self._old_models = apps.app_configs['invalid_models_tests'].models.copy() - - def tearDown(self): - apps.app_configs['invalid_models_tests'].models = self._old_models - apps.all_models['invalid_models_tests'] = self._old_models - apps.clear_cache() diff --git a/tests/invalid_models_tests/test_backend_specific.py b/tests/invalid_models_tests/test_backend_specific.py index 5be1d6f6917..fd73853a03b 100644 --- a/tests/invalid_models_tests/test_backend_specific.py +++ b/tests/invalid_models_tests/test_backend_specific.py @@ -3,9 +3,8 @@ from __future__ import unicode_literals from django.core.checks import Error from django.db import connections, models -from django.test import mock - -from .base import IsolatedModelsTestCase +from django.test import SimpleTestCase, mock +from django.test.utils import isolate_apps def dummy_allow_migrate(db, app_label, **hints): @@ -14,7 +13,8 @@ def dummy_allow_migrate(db, app_label, **hints): return db == 'default' -class BackendSpecificChecksTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class BackendSpecificChecksTests(SimpleTestCase): @mock.patch('django.db.models.fields.router.allow_migrate', new=dummy_allow_migrate) def test_check_field(self): diff --git a/tests/invalid_models_tests/test_custom_fields.py b/tests/invalid_models_tests/test_custom_fields.py index 03e65b599b3..4c379e70f57 100644 --- a/tests/invalid_models_tests/test_custom_fields.py +++ b/tests/invalid_models_tests/test_custom_fields.py @@ -1,9 +1,10 @@ from django.db import models - -from .base import IsolatedModelsTestCase +from django.test import SimpleTestCase +from django.test.utils import isolate_apps -class CustomFieldTest(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class CustomFieldTest(SimpleTestCase): def test_none_column(self): class NoColumnField(models.AutoField): diff --git a/tests/invalid_models_tests/test_deprecated_fields.py b/tests/invalid_models_tests/test_deprecated_fields.py index fa646515b3b..78265968958 100644 --- a/tests/invalid_models_tests/test_deprecated_fields.py +++ b/tests/invalid_models_tests/test_deprecated_fields.py @@ -1,10 +1,11 @@ from django.core import checks from django.db import models - -from .base import IsolatedModelsTestCase +from django.test import SimpleTestCase +from django.test.utils import isolate_apps -class DeprecatedFieldsTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class DeprecatedFieldsTests(SimpleTestCase): def test_IPAddressField_deprecated(self): class IPAddressModel(models.Model): ip = models.IPAddressField() diff --git a/tests/invalid_models_tests/test_models.py b/tests/invalid_models_tests/test_models.py index 8e1f515b13f..57647643415 100644 --- a/tests/invalid_models_tests/test_models.py +++ b/tests/invalid_models_tests/test_models.py @@ -6,9 +6,8 @@ import unittest from django.conf import settings from django.core.checks import Error from django.db import connections, models -from django.test.utils import override_settings - -from .base import IsolatedModelsTestCase +from django.test import SimpleTestCase +from django.test.utils import isolate_apps, override_settings def get_max_column_name_length(): @@ -31,7 +30,8 @@ def get_max_column_name_length(): return (allowed_len, db_alias) -class IndexTogetherTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class IndexTogetherTests(SimpleTestCase): def test_non_iterable(self): class Model(models.Model): @@ -146,7 +146,8 @@ class IndexTogetherTests(IsolatedModelsTestCase): # unique_together tests are very similar to index_together tests. -class UniqueTogetherTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class UniqueTogetherTests(SimpleTestCase): def test_non_iterable(self): class Model(models.Model): @@ -251,7 +252,8 @@ class UniqueTogetherTests(IsolatedModelsTestCase): self.assertEqual(errors, expected) -class FieldNamesTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class FieldNamesTests(SimpleTestCase): def test_ending_with_underscore(self): class Model(models.Model): @@ -434,7 +436,8 @@ class FieldNamesTests(IsolatedModelsTestCase): self.assertEqual(errors, expected) -class ShadowingFieldsTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class ShadowingFieldsTests(SimpleTestCase): def test_field_name_clash_with_child_accessor(self): class Parent(models.Model): @@ -558,7 +561,8 @@ class ShadowingFieldsTests(IsolatedModelsTestCase): self.assertEqual(errors, expected) -class OtherModelTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class OtherModelTests(SimpleTestCase): def test_unique_primary_key(self): invalid_id = models.IntegerField(primary_key=False) diff --git a/tests/invalid_models_tests/test_ordinary_fields.py b/tests/invalid_models_tests/test_ordinary_fields.py index 033970aae4b..2a7e912f8ce 100644 --- a/tests/invalid_models_tests/test_ordinary_fields.py +++ b/tests/invalid_models_tests/test_ordinary_fields.py @@ -5,14 +5,13 @@ import unittest from django.core.checks import Error, Warning as DjangoWarning from django.db import connection, models -from django.test import TestCase -from django.test.utils import override_settings +from django.test import SimpleTestCase, TestCase +from django.test.utils import isolate_apps, override_settings from django.utils.timezone import now -from .base import IsolatedModelsTestCase - -class AutoFieldTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class AutoFieldTests(SimpleTestCase): def test_valid_case(self): class Model(models.Model): @@ -46,7 +45,8 @@ class AutoFieldTests(IsolatedModelsTestCase): self.assertEqual(errors, expected) -class BooleanFieldTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class BooleanFieldTests(SimpleTestCase): def test_nullable_boolean_field(self): class Model(models.Model): @@ -65,7 +65,8 @@ class BooleanFieldTests(IsolatedModelsTestCase): self.assertEqual(errors, expected) -class CharFieldTests(IsolatedModelsTestCase, TestCase): +@isolate_apps('invalid_models_tests') +class CharFieldTests(TestCase): def test_valid_field(self): class Model(models.Model): @@ -216,7 +217,8 @@ class CharFieldTests(IsolatedModelsTestCase, TestCase): self.assertEqual(errors, expected) -class DateFieldTests(IsolatedModelsTestCase, TestCase): +@isolate_apps('invalid_models_tests') +class DateFieldTests(TestCase): def test_auto_now_and_auto_now_add_raise_error(self): class Model(models.Model): @@ -282,7 +284,8 @@ class DateFieldTests(IsolatedModelsTestCase, TestCase): self.test_fix_default_value() -class DateTimeFieldTests(IsolatedModelsTestCase, TestCase): +@isolate_apps('invalid_models_tests') +class DateTimeFieldTests(TestCase): def test_fix_default_value(self): class Model(models.Model): @@ -326,7 +329,8 @@ class DateTimeFieldTests(IsolatedModelsTestCase, TestCase): self.test_fix_default_value() -class DecimalFieldTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class DecimalFieldTests(SimpleTestCase): def test_required_attributes(self): class Model(models.Model): @@ -420,7 +424,8 @@ class DecimalFieldTests(IsolatedModelsTestCase): self.assertEqual(errors, expected) -class FileFieldTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class FileFieldTests(SimpleTestCase): def test_valid_case(self): class Model(models.Model): @@ -464,7 +469,8 @@ class FileFieldTests(IsolatedModelsTestCase): self.assertEqual(errors, expected) -class FilePathFieldTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class FilePathFieldTests(SimpleTestCase): def test_forbidden_files_and_folders(self): class Model(models.Model): @@ -483,7 +489,8 @@ class FilePathFieldTests(IsolatedModelsTestCase): self.assertEqual(errors, expected) -class GenericIPAddressFieldTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class GenericIPAddressFieldTests(SimpleTestCase): def test_non_nullable_blank(self): class Model(models.Model): @@ -503,7 +510,8 @@ class GenericIPAddressFieldTests(IsolatedModelsTestCase): self.assertEqual(errors, expected) -class ImageFieldTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class ImageFieldTests(SimpleTestCase): def test_pillow_installed(self): try: @@ -530,7 +538,8 @@ class ImageFieldTests(IsolatedModelsTestCase): self.assertEqual(errors, expected) -class IntegerFieldTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class IntegerFieldTests(SimpleTestCase): def test_max_length_warning(self): class Model(models.Model): @@ -549,7 +558,8 @@ class IntegerFieldTests(IsolatedModelsTestCase): self.assertEqual(errors, expected) -class TimeFieldTests(IsolatedModelsTestCase, TestCase): +@isolate_apps('invalid_models_tests') +class TimeFieldTests(TestCase): def test_fix_default_value(self): class Model(models.Model): diff --git a/tests/invalid_models_tests/test_relative_fields.py b/tests/invalid_models_tests/test_relative_fields.py index f157f2beb88..c2895f681f7 100644 --- a/tests/invalid_models_tests/test_relative_fields.py +++ b/tests/invalid_models_tests/test_relative_fields.py @@ -3,21 +3,19 @@ from __future__ import unicode_literals import warnings -from django.apps.registry import Apps from django.core.checks import Error, Warning as DjangoWarning from django.db import models from django.db.models.fields.related import ForeignObject from django.test import ignore_warnings -from django.test.testcases import skipIfDBFeature -from django.test.utils import override_settings +from django.test.testcases import SimpleTestCase, skipIfDBFeature +from django.test.utils import isolate_apps, override_settings from django.utils import six from django.utils.deprecation import RemovedInDjango20Warning from django.utils.version import get_docs_version -from .base import IsolatedModelsTestCase - -class RelativeFieldTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class RelativeFieldTests(SimpleTestCase): def test_valid_foreign_key_without_accessor(self): class Target(models.Model): @@ -133,23 +131,18 @@ class RelativeFieldTests(IsolatedModelsTestCase): ] self.assertEqual(errors, expected) - def test_foreign_key_to_isolated_apps_model(self): + @isolate_apps('invalid_models_tests') + def test_foreign_key_to_isolate_apps_model(self): """ #25723 - Referenced model registration lookup should be run against the field's model registry. """ - test_apps = Apps(['invalid_models_tests']) - class OtherModel(models.Model): - class Meta: - apps = test_apps + pass class Model(models.Model): foreign_key = models.ForeignKey('OtherModel', models.CASCADE) - class Meta: - apps = test_apps - field = Model._meta.get_field('foreign_key') self.assertEqual(field.check(from_model=Model), []) @@ -170,23 +163,18 @@ class RelativeFieldTests(IsolatedModelsTestCase): ] self.assertEqual(errors, expected) - def test_many_to_many_to_isolated_apps_model(self): + @isolate_apps('invalid_models_tests') + def test_many_to_many_to_isolate_apps_model(self): """ #25723 - Referenced model registration lookup should be run against the field's model registry. """ - test_apps = Apps(['invalid_models_tests']) - class OtherModel(models.Model): - class Meta: - apps = test_apps + pass class Model(models.Model): m2m = models.ManyToManyField('OtherModel') - class Meta: - apps = test_apps - field = Model._meta.get_field('m2m') self.assertEqual(field.check(from_model=Model), []) @@ -329,30 +317,22 @@ class RelativeFieldTests(IsolatedModelsTestCase): ] self.assertEqual(errors, expected) - def test_many_to_many_through_isolated_apps_model(self): + @isolate_apps('invalid_models_tests') + def test_many_to_many_through_isolate_apps_model(self): """ #25723 - Through model registration lookup should be run against the field's model registry. """ - test_apps = Apps(['invalid_models_tests']) - class GroupMember(models.Model): person = models.ForeignKey('Person', models.CASCADE) group = models.ForeignKey('Group', models.CASCADE) - class Meta: - apps = test_apps - class Person(models.Model): - class Meta: - apps = test_apps + pass class Group(models.Model): members = models.ManyToManyField('Person', through='GroupMember') - class Meta: - apps = test_apps - field = Group._meta.get_field('members') self.assertEqual(field.check(from_model=Group), []) @@ -790,7 +770,8 @@ class RelativeFieldTests(IsolatedModelsTestCase): self.assertFalse(errors) -class AccessorClashTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class AccessorClashTests(SimpleTestCase): def test_fk_to_integer(self): self._test_accessor_clash( @@ -902,7 +883,8 @@ class AccessorClashTests(IsolatedModelsTestCase): self.assertEqual(errors, expected) -class ReverseQueryNameClashTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class ReverseQueryNameClashTests(SimpleTestCase): def test_fk_to_integer(self): self._test_reverse_query_name_clash( @@ -958,7 +940,8 @@ class ReverseQueryNameClashTests(IsolatedModelsTestCase): self.assertEqual(errors, expected) -class ExplicitRelatedNameClashTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class ExplicitRelatedNameClashTests(SimpleTestCase): def test_fk_to_integer(self): self._test_explicit_related_name_clash( @@ -1022,7 +1005,8 @@ class ExplicitRelatedNameClashTests(IsolatedModelsTestCase): self.assertEqual(errors, expected) -class ExplicitRelatedQueryNameClashTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class ExplicitRelatedQueryNameClashTests(SimpleTestCase): def test_fk_to_integer(self): self._test_explicit_related_query_name_clash( @@ -1086,7 +1070,8 @@ class ExplicitRelatedQueryNameClashTests(IsolatedModelsTestCase): self.assertEqual(errors, expected) -class SelfReferentialM2MClashTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class SelfReferentialM2MClashTests(SimpleTestCase): def test_clash_between_accessors(self): class Model(models.Model): @@ -1181,7 +1166,8 @@ class SelfReferentialM2MClashTests(IsolatedModelsTestCase): self.assertEqual(errors, []) -class SelfReferentialFKClashTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class SelfReferentialFKClashTests(SimpleTestCase): def test_accessor_clash(self): class Model(models.Model): @@ -1244,7 +1230,8 @@ class SelfReferentialFKClashTests(IsolatedModelsTestCase): self.assertEqual(errors, expected) -class ComplexClashTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class ComplexClashTests(SimpleTestCase): # New tests should not be included here, because this is a single, # self-contained sanity check, not a test of everything. @@ -1358,7 +1345,8 @@ class ComplexClashTests(IsolatedModelsTestCase): self.assertEqual(errors, expected) -class M2mThroughFieldsTests(IsolatedModelsTestCase): +@isolate_apps('invalid_models_tests') +class M2mThroughFieldsTests(SimpleTestCase): def test_m2m_field_argument_validation(self): """ Tests that ManyToManyField accepts the ``through_fields`` kwarg diff --git a/tests/managers_regress/tests.py b/tests/managers_regress/tests.py index cd9898ae637..e05602c50da 100644 --- a/tests/managers_regress/tests.py +++ b/tests/managers_regress/tests.py @@ -1,9 +1,9 @@ from __future__ import unicode_literals -from django.apps import apps from django.db import models from django.template import Context, Template from django.test import TestCase, override_settings +from django.test.utils import isolate_apps from django.utils.encoding import force_text from .models import ( @@ -91,82 +91,58 @@ class ManagersRegressionTests(TestCase): AbstractBase1.objects.all() @override_settings(TEST_SWAPPABLE_MODEL='managers_regress.Parent') + @isolate_apps('managers_regress') def test_swappable_manager(self): - # The models need to be removed after the test in order to prevent bad - # interactions with the flush operation in other tests. - _old_models = apps.app_configs['managers_regress'].models.copy() + class SwappableModel(models.Model): + class Meta: + swappable = 'TEST_SWAPPABLE_MODEL' - try: - class SwappableModel(models.Model): - class Meta: - swappable = 'TEST_SWAPPABLE_MODEL' - - # Accessing the manager on a swappable model should - # raise an attribute error with a helpful message - msg = ( - "Manager isn't available; 'managers_regress.SwappableModel' " - "has been swapped for 'managers_regress.Parent'" - ) - with self.assertRaisesMessage(AttributeError, msg): - SwappableModel.objects.all() - finally: - apps.app_configs['managers_regress'].models = _old_models - apps.all_models['managers_regress'] = _old_models - apps.clear_cache() + # Accessing the manager on a swappable model should + # raise an attribute error with a helpful message + msg = ( + "Manager isn't available; 'managers_regress.SwappableModel' " + "has been swapped for 'managers_regress.Parent'" + ) + with self.assertRaisesMessage(AttributeError, msg): + SwappableModel.objects.all() @override_settings(TEST_SWAPPABLE_MODEL='managers_regress.Parent') + @isolate_apps('managers_regress') def test_custom_swappable_manager(self): - # The models need to be removed after the test in order to prevent bad - # interactions with the flush operation in other tests. - _old_models = apps.app_configs['managers_regress'].models.copy() + class SwappableModel(models.Model): + stuff = models.Manager() - try: - class SwappableModel(models.Model): - stuff = models.Manager() + class Meta: + swappable = 'TEST_SWAPPABLE_MODEL' - class Meta: - swappable = 'TEST_SWAPPABLE_MODEL' - - # Accessing the manager on a swappable model with an - # explicit manager should raise an attribute error with a - # helpful message - msg = ( - "Manager isn't available; 'managers_regress.SwappableModel' " - "has been swapped for 'managers_regress.Parent'" - ) - with self.assertRaisesMessage(AttributeError, msg): - SwappableModel.stuff.all() - finally: - apps.app_configs['managers_regress'].models = _old_models - apps.all_models['managers_regress'] = _old_models - apps.clear_cache() + # Accessing the manager on a swappable model with an + # explicit manager should raise an attribute error with a + # helpful message + msg = ( + "Manager isn't available; 'managers_regress.SwappableModel' " + "has been swapped for 'managers_regress.Parent'" + ) + with self.assertRaisesMessage(AttributeError, msg): + SwappableModel.stuff.all() @override_settings(TEST_SWAPPABLE_MODEL='managers_regress.Parent') + @isolate_apps('managers_regress') def test_explicit_swappable_manager(self): - # The models need to be removed after the test in order to prevent bad - # interactions with the flush operation in other tests. - _old_models = apps.app_configs['managers_regress'].models.copy() + class SwappableModel(models.Model): + objects = models.Manager() - try: - class SwappableModel(models.Model): - objects = models.Manager() + class Meta: + swappable = 'TEST_SWAPPABLE_MODEL' - class Meta: - swappable = 'TEST_SWAPPABLE_MODEL' - - # Accessing the manager on a swappable model with an - # explicit manager should raise an attribute error with a - # helpful message - msg = ( - "Manager isn't available; 'managers_regress.SwappableModel' " - "has been swapped for 'managers_regress.Parent'" - ) - with self.assertRaisesMessage(AttributeError, msg): - SwappableModel.objects.all() - finally: - apps.app_configs['managers_regress'].models = _old_models - apps.all_models['managers_regress'] = _old_models - apps.clear_cache() + # Accessing the manager on a swappable model with an + # explicit manager should raise an attribute error with a + # helpful message + msg = ( + "Manager isn't available; 'managers_regress.SwappableModel' " + "has been swapped for 'managers_regress.Parent'" + ) + with self.assertRaisesMessage(AttributeError, msg): + SwappableModel.objects.all() def test_regress_3871(self): related = RelatedModel.objects.create() diff --git a/tests/model_fields/tests.py b/tests/model_fields/tests.py index 77361fae79f..14b56139dee 100644 --- a/tests/model_fields/tests.py +++ b/tests/model_fields/tests.py @@ -19,7 +19,7 @@ from django.db.models.fields import ( TimeField, URLField, ) from django.db.models.fields.files import FileField, ImageField -from django.test.utils import requires_tz_support +from django.test.utils import isolate_apps, requires_tz_support from django.utils import six, timezone from django.utils.encoding import force_str from django.utils.functional import lazy @@ -207,7 +207,11 @@ class ForeignKeyTests(test.TestCase): fk_model_empty = FkToChar.objects.select_related('out').get(id=fk_model_empty.pk) self.assertEqual(fk_model_empty.out, char_model_empty) + @isolate_apps('model_fields') def test_warning_when_unique_true_on_fk(self): + class Foo(models.Model): + pass + class FKUniqueTrue(models.Model): fk_field = models.ForeignKey(Foo, models.CASCADE, unique=True) diff --git a/tests/order_with_respect_to/tests.py b/tests/order_with_respect_to/tests.py index c22f9b4ea4e..7788fe3368c 100644 --- a/tests/order_with_respect_to/tests.py +++ b/tests/order_with_respect_to/tests.py @@ -2,9 +2,9 @@ from __future__ import unicode_literals from operator import attrgetter -from django.apps.registry import Apps from django.db import models from django.test import TestCase +from django.test.utils import isolate_apps from .base_tests import BaseOrderWithRespectToTests from .models import Answer, Dimension, Entity, Post, Question @@ -18,12 +18,10 @@ class OrderWithRespectToBaseTests(BaseOrderWithRespectToTests, TestCase): class OrderWithRespectToTests(TestCase): + @isolate_apps('order_with_respect_to') def test_duplicate_order_field(self): - test_apps = Apps(['order_with_respect_to']) - class Bar(models.Model): class Meta: - apps = test_apps app_label = 'order_with_respect_to' class Foo(models.Model): @@ -32,7 +30,6 @@ class OrderWithRespectToTests(TestCase): class Meta: order_with_respect_to = 'bar' - apps = test_apps app_label = 'order_with_respect_to' count = 0 diff --git a/tests/postgres_tests/test_array.py b/tests/postgres_tests/test_array.py index e9cec6b5b50..24a47db1d79 100644 --- a/tests/postgres_tests/test_array.py +++ b/tests/postgres_tests/test_array.py @@ -4,11 +4,11 @@ import unittest import uuid from django import forms -from django.apps.registry import Apps from django.core import exceptions, serializers, validators from django.core.management import call_command from django.db import IntegrityError, connection, models from django.test import TransactionTestCase, override_settings +from django.test.utils import isolate_apps from django.utils import timezone from . import PostgreSQLTestCase @@ -333,17 +333,13 @@ class TestOtherTypesExactQuerying(PostgreSQLTestCase): ) +@isolate_apps('postgres_tests') class TestChecks(PostgreSQLTestCase): def test_field_checks(self): - test_apps = Apps(['postgres_tests']) - class MyModel(PostgreSQLModel): field = ArrayField(models.CharField()) - class Meta: - apps = test_apps - model = MyModel() errors = model.check() self.assertEqual(len(errors), 1) @@ -352,14 +348,9 @@ class TestChecks(PostgreSQLTestCase): self.assertIn('max_length', errors[0].msg) def test_invalid_base_fields(self): - test_apps = Apps(['postgres_tests']) - class MyModel(PostgreSQLModel): field = ArrayField(models.ManyToManyField('postgres_tests.IntegerArrayModel')) - class Meta: - apps = test_apps - model = MyModel() errors = model.check() self.assertEqual(len(errors), 1) @@ -369,14 +360,9 @@ class TestChecks(PostgreSQLTestCase): """ Nested ArrayFields are permitted. """ - test_apps = Apps(['postgres_tests']) - class MyModel(PostgreSQLModel): field = ArrayField(ArrayField(models.CharField())) - class Meta: - apps = test_apps - model = MyModel() errors = model.check() self.assertEqual(len(errors), 1) diff --git a/tests/proxy_models/tests.py b/tests/proxy_models/tests.py index 625925fcb5a..874a2596f0a 100644 --- a/tests/proxy_models/tests.py +++ b/tests/proxy_models/tests.py @@ -2,7 +2,6 @@ from __future__ import unicode_literals import datetime -from django.apps import apps from django.contrib import admin from django.contrib.auth.models import User as AuthUser from django.contrib.contenttypes.models import ContentType @@ -10,6 +9,7 @@ from django.core import checks, management from django.db import DEFAULT_DB_ALIAS, models from django.db.models import signals from django.test import TestCase, override_settings +from django.test.utils import isolate_apps from django.urls import reverse from .admin import admin as force_admin_model_registration # NOQA @@ -129,6 +129,7 @@ class ProxyModelTests(TestCase): proxy = True self.assertRaises(TypeError, build_abc) + @isolate_apps('proxy_models') def test_no_cbc(self): """ The proxy must actually have one concrete base class @@ -139,6 +140,7 @@ class ProxyModelTests(TestCase): proxy = True self.assertRaises(TypeError, build_no_cbc) + @isolate_apps('proxy_models') def test_no_base_classes(self): def build_no_base_classes(): class NoBaseClasses(models.Model): @@ -146,15 +148,13 @@ class ProxyModelTests(TestCase): proxy = True self.assertRaises(TypeError, build_no_base_classes) + @isolate_apps('proxy_models') def test_new_fields(self): class NoNewFields(Person): newfield = models.BooleanField() class Meta: proxy = True - # don't register this model in the app_cache for the current app, - # otherwise the check fails when other tests are being run. - app_label = 'no_such_app' errors = NoNewFields.check() expected = [ @@ -168,30 +168,22 @@ class ProxyModelTests(TestCase): self.assertEqual(errors, expected) @override_settings(TEST_SWAPPABLE_MODEL='proxy_models.AlternateModel') + @isolate_apps('proxy_models') def test_swappable(self): - # The models need to be removed after the test in order to prevent bad - # interactions with the flush operation in other tests. - _old_models = apps.app_configs['proxy_models'].models.copy() + class SwappableModel(models.Model): - try: - class SwappableModel(models.Model): + class Meta: + swappable = 'TEST_SWAPPABLE_MODEL' + + class AlternateModel(models.Model): + pass + + # You can't proxy a swapped model + with self.assertRaises(TypeError): + class ProxyModel(SwappableModel): class Meta: - swappable = 'TEST_SWAPPABLE_MODEL' - - class AlternateModel(models.Model): - pass - - # You can't proxy a swapped model - with self.assertRaises(TypeError): - class ProxyModel(SwappableModel): - - class Meta: - proxy = True - finally: - apps.app_configs['proxy_models'].models = _old_models - apps.all_models['proxy_models'] = _old_models - apps.clear_cache() + proxy = True def test_myperson_manager(self): Person.objects.create(name="fred") diff --git a/tests/signals/tests.py b/tests/signals/tests.py index ba99316bfbb..f3bbc05f659 100644 --- a/tests/signals/tests.py +++ b/tests/signals/tests.py @@ -4,6 +4,7 @@ from django.db import models from django.db.models import signals from django.dispatch import receiver from django.test import TestCase +from django.test.utils import isolate_apps from django.utils import six from .models import Author, Book, Car, Person @@ -285,6 +286,7 @@ class LazyModelRefTest(BaseSignalTest): finally: signals.post_init.disconnect(self.receiver, sender=Book) + @isolate_apps('signals') def test_not_loaded_model(self): signals.post_init.connect( self.receiver, sender='signals.Created', weak=False diff --git a/tests/sites_framework/tests.py b/tests/sites_framework/tests.py index ca516388cff..576dbfc7eb4 100644 --- a/tests/sites_framework/tests.py +++ b/tests/sites_framework/tests.py @@ -1,14 +1,12 @@ -from django.apps import apps from django.conf import settings from django.contrib.sites.managers import CurrentSiteManager from django.contrib.sites.models import Site from django.core import checks from django.db import models -from django.test import TestCase +from django.test import SimpleTestCase, TestCase +from django.test.utils import isolate_apps -from .models import ( - AbstractArticle, CustomArticle, ExclusiveArticle, SyndicatedArticle, -) +from .models import CustomArticle, ExclusiveArticle, SyndicatedArticle class SitesFrameworkTestCase(TestCase): @@ -16,13 +14,6 @@ class SitesFrameworkTestCase(TestCase): Site.objects.get_or_create(id=settings.SITE_ID, domain="example.com", name="example.com") Site.objects.create(id=settings.SITE_ID + 1, domain="example2.com", name="example2.com") - self._old_models = apps.app_configs['sites_framework'].models.copy() - - def tearDown(self): - apps.app_configs['sites_framework'].models = self._old_models - apps.all_models['sites_framework'] = self._old_models - apps.clear_cache() - def test_site_fk(self): article = ExclusiveArticle.objects.create(title="Breaking News!", site_id=settings.SITE_ID) self.assertEqual(ExclusiveArticle.on_site.all().get(), article) @@ -42,12 +33,12 @@ class SitesFrameworkTestCase(TestCase): ) self.assertEqual(CustomArticle.on_site.all().get(), article) + +@isolate_apps('sites_framework') +class CurrentSiteManagerChecksTests(SimpleTestCase): + def test_invalid_name(self): - - class InvalidArticle(AbstractArticle): - site = models.ForeignKey(Site, models.CASCADE) - - objects = models.Manager() + class InvalidArticle(models.Model): on_site = CurrentSiteManager("places_this_article_should_appear") errors = InvalidArticle.check() @@ -64,8 +55,9 @@ class SitesFrameworkTestCase(TestCase): def test_invalid_field_type(self): - class ConfusedArticle(AbstractArticle): + class ConfusedArticle(models.Model): site = models.IntegerField() + on_site = CurrentSiteManager() errors = ConfusedArticle.check() expected = [ diff --git a/tests/str/tests.py b/tests/str/tests.py index 6467875a5c9..08fd554e5ec 100644 --- a/tests/str/tests.py +++ b/tests/str/tests.py @@ -4,9 +4,9 @@ from __future__ import unicode_literals import datetime from unittest import skipIf -from django.apps.registry import Apps from django.db import models from django.test import TestCase +from django.test.utils import isolate_apps from django.utils import six from .models import Article, InternationalArticle @@ -36,16 +36,14 @@ class SimpleTests(TestCase): # python_2_unicode_compatible decorator is used. self.assertEqual(str(a), b'Girl wins \xe2\x82\xac12.500 in lottery') + @isolate_apps('str') def test_defaults(self): """ The default implementation of __str__ and __repr__ should return instances of str. """ - test_apps = Apps(['str']) - class Default(models.Model): - class Meta: - apps = test_apps + pass obj = Default() # Explicit call to __str__/__repr__ to make sure str()/repr() don't