Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Improved validation of swappable model settings.

  • Loading branch information...
commit 6494bf91f2ddaaabec3ec017f2e3131937c35517 1 parent 5a04cde
Russell Keith-Magee authored September 17, 2012
5  django/contrib/auth/__init__.py
@@ -97,7 +97,10 @@ def get_user_model():
97 97
     from django.conf import settings
98 98
     from django.db.models import get_model
99 99
 
100  
-    app_label, model_name = settings.AUTH_USER_MODEL.split('.')
  100
+    try:
  101
+        app_label, model_name = settings.AUTH_USER_MODEL.split('.')
  102
+    except ValueError:
  103
+        raise ImproperlyConfigured("AUTH_USER_MODEL must be of the form 'app_label.model_name'")
101 104
     return get_model(app_label, model_name)
102 105
 
103 106
 
10  django/core/management/validation.py
@@ -285,6 +285,16 @@ def get_validation_errors(outfile, app=None):
285 285
                     if r.get_accessor_name() == rel_query_name:
286 286
                         e.add(opts, "Reverse query name for m2m field '%s' clashes with related field '%s.%s'. Add a related_name argument to the definition for '%s'." % (f.name, rel_opts.object_name, r.get_accessor_name(), f.name))
287 287
 
  288
+        # Check swappable attribute.
  289
+        if opts.swapped:
  290
+            try:
  291
+                app_label, model_name = opts.swapped.split('.')
  292
+            except ValueError:
  293
+                e.add(opts, "%s is not of the form 'app_label.app_name'." % opts.swappable)
  294
+                continue
  295
+            if not models.get_model(app_label, model_name):
  296
+                e.add(opts, "Model has been swapped out for '%s' which has not been installed or is abstract." % opts.swapped)
  297
+
288 298
         # Check ordering attribute.
289 299
         if opts.ordering:
290 300
             for field_name in opts.ordering:
22  tests/modeltests/invalid_models/invalid_models/models.py
@@ -310,6 +310,26 @@ class Meta:
310 310
         swappable = 'TEST_SWAPPED_MODEL'
311 311
 
312 312
 
  313
+class BadSwappableValue(models.Model):
  314
+    """A model that can be swapped out; during testing, the swappable
  315
+    value is not of the format app.model
  316
+    """
  317
+    name = models.CharField(max_length=100)
  318
+
  319
+    class Meta:
  320
+        swappable = 'TEST_SWAPPED_MODEL_BAD_VALUE'
  321
+
  322
+
  323
+class BadSwappableModel(models.Model):
  324
+    """A model that can be swapped out; during testing, the swappable
  325
+    value references an unknown model.
  326
+    """
  327
+    name = models.CharField(max_length=100)
  328
+
  329
+    class Meta:
  330
+        swappable = 'TEST_SWAPPED_MODEL_BAD_MODEL'
  331
+
  332
+
313 333
 class HardReferenceModel(models.Model):
314 334
     fk_1 = models.ForeignKey(SwappableModel, related_name='fk_hardref1')
315 335
     fk_2 = models.ForeignKey('invalid_models.SwappableModel', related_name='fk_hardref2')
@@ -433,6 +453,8 @@ class HardReferenceModel(models.Model):
433 453
 invalid_models.hardreferencemodel: 'fk_4' defines a relation with the model 'invalid_models.SwappedModel', which has been swapped out. Update the relation to point at settings.TEST_SWAPPED_MODEL.
434 454
 invalid_models.hardreferencemodel: 'm2m_3' defines a relation with the model 'invalid_models.SwappedModel', which has been swapped out. Update the relation to point at settings.TEST_SWAPPED_MODEL.
435 455
 invalid_models.hardreferencemodel: 'm2m_4' defines a relation with the model 'invalid_models.SwappedModel', which has been swapped out. Update the relation to point at settings.TEST_SWAPPED_MODEL.
  456
+invalid_models.badswappablevalue: TEST_SWAPPED_MODEL_BAD_VALUE is not of the form 'app_label.app_name'.
  457
+invalid_models.badswappablemodel: Model has been swapped out for 'not_an_app.Target' which has not been installed or is abstract.
436 458
 """
437 459
 
438 460
 if not connection.features.interprets_empty_strings_as_nulls:
6  tests/modeltests/invalid_models/tests.py
@@ -36,7 +36,11 @@ def tearDown(self):
36 36
     # set to *something* in order for the test to work. However, it's
37 37
     # easier to set this up as an override than to require every developer
38 38
     # to specify a value in their test settings.
39  
-    @override_settings(TEST_SWAPPED_MODEL='invalid_models.Target')
  39
+    @override_settings(
  40
+        TEST_SWAPPED_MODEL='invalid_models.Target',
  41
+        TEST_SWAPPED_MODEL_BAD_VALUE='not-a-model',
  42
+        TEST_SWAPPED_MODEL_BAD_MODEL='not_an_app.Target',
  43
+    )
40 44
     def test_invalid_models(self):
41 45
         try:
42 46
             module = load_app("modeltests.invalid_models.invalid_models")

0 notes on commit 6494bf9

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