Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Browse files

Fixed #19401 -- Ensure that swappable model references are case insen…


This is necessary because get_model() checks are case insensitive, and if the swapable check isn't, the
swappable logic gets tied up in knots with models that are partially swapped out.

Thanks to for the report and extensive analysis, and Preston for his work on the draft patch.
  • Loading branch information...
1 parent 3989ce5 commit c04c03daa3620dc5106740a976738ada35203ab5 @freakboy3742 freakboy3742 committed
19 django/db/models/
@@ -213,12 +213,25 @@ def _swapped(self):
Has this model been swapped out for another? If so, return the model
name of the replacement; otherwise, return None.
+ For historical reasons, model name lookups using get_model() are
+ case insensitive, so we make sure we are case insensitive here.
if self.swappable:
- model_label = '%s.%s' % (self.app_label, self.object_name)
+ model_label = '%s.%s' % (self.app_label, self.object_name.lower())
swapped_for = getattr(settings, self.swappable, None)
- if swapped_for not in (None, model_label):
- return swapped_for
+ if swapped_for:
+ try:
+ swapped_label, swapped_object = swapped_for.split('.')
+ except ValueError:
+ # setting not in the format app_label.model_name
+ # raising ImproperlyConfigured here causes problems with
+ # test cleanup code - instead it is raised in get_user_model
+ # or as part of validation.
+ return swapped_for
+ if '%s.%s' % (swapped_label, swapped_object.lower()) not in (None, model_label):
+ return swapped_for
return None
swapped = property(_swapped)
12 tests/regressiontests/swappable_models/
@@ -9,6 +9,8 @@
from django.test import TestCase
from django.test.utils import override_settings
+from regressiontests.swappable_models.models import Article
class SwappableModelTests(TestCase):
def setUp(self):
@@ -44,3 +46,13 @@ def test_generated_data(self):
for ct in ContentType.objects.all()]
self.assertIn(('swappable_models', 'alternatearticle'), apps_models)
self.assertNotIn(('swappable_models', 'article'), apps_models)
+ @override_settings(TEST_ARTICLE_MODEL='swappable_models.article')
+ def test_case_insensitive(self):
+ "Model names are case insensitive. Check that model swapping honors this."
+ try:
+ Article.objects.all()
+ except AttributeError:
+'Swappable model names should be case insensitive.')
+ self.assertIsNone(Article._meta.swapped)

0 comments on commit c04c03d

Please sign in to comment.
Something went wrong with that request. Please try again.