Loading django/contrib/auth/tests/test_management.py +1 −0 Original line number Diff line number Diff line Loading @@ -153,6 +153,7 @@ class ChangepasswordManagementCommandTestCase(TestCase): @skipIfCustomUser @override_settings(SILENCED_SYSTEM_CHECKS=['fields.W342']) # ForeignKey(unique=True) class CreatesuperuserManagementCommandTestCase(TestCase): def test_basic_usage(self): Loading django/db/models/fields/related.py +15 −0 Original line number Diff line number Diff line Loading @@ -1710,6 +1710,7 @@ class ForeignKey(ForeignObject): def check(self, **kwargs): errors = super(ForeignKey, self).check(**kwargs) errors.extend(self._check_on_delete()) errors.extend(self._check_unique()) return errors def _check_on_delete(self): Loading @@ -1735,6 +1736,16 @@ class ForeignKey(ForeignObject): else: return [] def _check_unique(self, **kwargs): return [ checks.Warning( 'Setting unique=True on a ForeignKey has the same effect as using a OneToOneField.', hint='ForeignKey(unique=True) is usually better served by a OneToOneField.', obj=self, id='fields.W342', ) ] if self.unique else [] def deconstruct(self): name, path, args, kwargs = super(ForeignKey, self).deconstruct() del kwargs['to_fields'] Loading Loading @@ -1891,6 +1902,10 @@ class OneToOneField(ForeignKey): else: setattr(instance, self.attname, data) def _check_unique(self, **kwargs): # override ForeignKey since check isn't applicable here return [] def create_many_to_many_intermediary_model(field, klass): from django.db import models Loading docs/ref/checks.txt +2 −0 Original line number Diff line number Diff line Loading @@ -154,6 +154,8 @@ Related Fields * **fields.E339**: ``<model>.<field name>`` is not a foreign key to ``<model>``. * **fields.W340**: ``null`` has no effect on ``ManyToManyField``. * **fields.W341**: ``ManyToManyField`` does not support ``validators``. * **fields.W342**: Setting ``unique=True`` on a ``ForeignKey`` has the same effect as using a ``OneToOneField``. Signals ~~~~~~~ Loading tests/admin_checks/tests.py +5 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ from django.contrib.contenttypes.admin import GenericStackedInline from django.core import checks from django.core.exceptions import ImproperlyConfigured from django.test import TestCase from django.test.utils import override_settings from .models import Song, Book, Album, TwoAlbumFKAndAnE, City, State, Influence Loading @@ -34,6 +35,10 @@ class ValidFormFieldsets(admin.ModelAdmin): ) @override_settings( SILENCED_SYSTEM_CHECKS=['fields.W342'], # ForeignKey(unique=True) INSTALLED_APPS=['django.contrib.auth', 'django.contrib.contenttypes', 'admin_checks'] ) class SystemChecksTestCase(TestCase): def test_checks_are_performed(self): Loading tests/check_framework/tests.py +6 −4 Original line number Diff line number Diff line Loading @@ -8,7 +8,6 @@ from django.apps import apps from django.conf import settings from django.core import checks from django.core.checks import Error, Warning from django.core.checks.model_checks import check_all_models from django.core.checks.registry import CheckRegistry from django.core.checks.compatibility.django_1_7_0 import check_1_7_compatibility from django.core.management.base import CommandError Loading Loading @@ -303,7 +302,10 @@ class CheckFrameworkReservedNamesTests(TestCase): del self.current_models[model] apps.clear_cache() @override_settings(SILENCED_SYSTEM_CHECKS=['models.E020']) @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 ModelWithAttributeCalledCheck(models.Model): check = 42 Loading @@ -318,6 +320,7 @@ class CheckFrameworkReservedNamesTests(TestCase): check = models.ForeignKey(ModelWithRelatedManagerCalledCheck) article = models.ForeignKey(ModelWithRelatedManagerCalledCheck, related_name='check') errors = checks.run_checks() expected = [ Error( "The 'ModelWithAttributeCalledCheck.check()' class method is " Loading @@ -341,5 +344,4 @@ class CheckFrameworkReservedNamesTests(TestCase): id='models.E020' ), ] self.assertEqual(check_all_models(), expected) self.assertEqual(errors, expected) Loading
django/contrib/auth/tests/test_management.py +1 −0 Original line number Diff line number Diff line Loading @@ -153,6 +153,7 @@ class ChangepasswordManagementCommandTestCase(TestCase): @skipIfCustomUser @override_settings(SILENCED_SYSTEM_CHECKS=['fields.W342']) # ForeignKey(unique=True) class CreatesuperuserManagementCommandTestCase(TestCase): def test_basic_usage(self): Loading
django/db/models/fields/related.py +15 −0 Original line number Diff line number Diff line Loading @@ -1710,6 +1710,7 @@ class ForeignKey(ForeignObject): def check(self, **kwargs): errors = super(ForeignKey, self).check(**kwargs) errors.extend(self._check_on_delete()) errors.extend(self._check_unique()) return errors def _check_on_delete(self): Loading @@ -1735,6 +1736,16 @@ class ForeignKey(ForeignObject): else: return [] def _check_unique(self, **kwargs): return [ checks.Warning( 'Setting unique=True on a ForeignKey has the same effect as using a OneToOneField.', hint='ForeignKey(unique=True) is usually better served by a OneToOneField.', obj=self, id='fields.W342', ) ] if self.unique else [] def deconstruct(self): name, path, args, kwargs = super(ForeignKey, self).deconstruct() del kwargs['to_fields'] Loading Loading @@ -1891,6 +1902,10 @@ class OneToOneField(ForeignKey): else: setattr(instance, self.attname, data) def _check_unique(self, **kwargs): # override ForeignKey since check isn't applicable here return [] def create_many_to_many_intermediary_model(field, klass): from django.db import models Loading
docs/ref/checks.txt +2 −0 Original line number Diff line number Diff line Loading @@ -154,6 +154,8 @@ Related Fields * **fields.E339**: ``<model>.<field name>`` is not a foreign key to ``<model>``. * **fields.W340**: ``null`` has no effect on ``ManyToManyField``. * **fields.W341**: ``ManyToManyField`` does not support ``validators``. * **fields.W342**: Setting ``unique=True`` on a ``ForeignKey`` has the same effect as using a ``OneToOneField``. Signals ~~~~~~~ Loading
tests/admin_checks/tests.py +5 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ from django.contrib.contenttypes.admin import GenericStackedInline from django.core import checks from django.core.exceptions import ImproperlyConfigured from django.test import TestCase from django.test.utils import override_settings from .models import Song, Book, Album, TwoAlbumFKAndAnE, City, State, Influence Loading @@ -34,6 +35,10 @@ class ValidFormFieldsets(admin.ModelAdmin): ) @override_settings( SILENCED_SYSTEM_CHECKS=['fields.W342'], # ForeignKey(unique=True) INSTALLED_APPS=['django.contrib.auth', 'django.contrib.contenttypes', 'admin_checks'] ) class SystemChecksTestCase(TestCase): def test_checks_are_performed(self): Loading
tests/check_framework/tests.py +6 −4 Original line number Diff line number Diff line Loading @@ -8,7 +8,6 @@ from django.apps import apps from django.conf import settings from django.core import checks from django.core.checks import Error, Warning from django.core.checks.model_checks import check_all_models from django.core.checks.registry import CheckRegistry from django.core.checks.compatibility.django_1_7_0 import check_1_7_compatibility from django.core.management.base import CommandError Loading Loading @@ -303,7 +302,10 @@ class CheckFrameworkReservedNamesTests(TestCase): del self.current_models[model] apps.clear_cache() @override_settings(SILENCED_SYSTEM_CHECKS=['models.E020']) @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 ModelWithAttributeCalledCheck(models.Model): check = 42 Loading @@ -318,6 +320,7 @@ class CheckFrameworkReservedNamesTests(TestCase): check = models.ForeignKey(ModelWithRelatedManagerCalledCheck) article = models.ForeignKey(ModelWithRelatedManagerCalledCheck, related_name='check') errors = checks.run_checks() expected = [ Error( "The 'ModelWithAttributeCalledCheck.check()' class method is " Loading @@ -341,5 +344,4 @@ class CheckFrameworkReservedNamesTests(TestCase): id='models.E020' ), ] self.assertEqual(check_all_models(), expected) self.assertEqual(errors, expected)