Code

Ticket #3011: t3011_swappable_validation.diff

File t3011_swappable_validation.diff, 2.4 KB (added by mindsocket, 20 months ago)

Make model validation more robust (checks that swappable referred to in setting exists)

Line 
1diff --git a/django/contrib/auth/__init__.py b/django/contrib/auth/__init__.py
2index d5d4430..0fe0c91 100644
3--- a/django/contrib/auth/__init__.py
4+++ b/django/contrib/auth/__init__.py
5@@ -97,7 +97,10 @@ def get_user_model():
6     from django.conf import settings
7     from django.db.models import get_model
8 
9-    app_label, model_name = settings.AUTH_USER_MODEL.split('.')
10+    try:
11+        app_label, model_name = settings.AUTH_USER_MODEL.split('.')
12+    except ValueError:
13+        raise ImproperlyConfigured("Invalid AUTH_USER_MODEL setting, value must be of the form 'app_label.model_name'")
14     return get_model(app_label, model_name)
15 
16 
17diff --git a/django/core/management/validation.py b/django/core/management/validation.py
18index f613009..190fcb8 100644
19--- a/django/core/management/validation.py
20+++ b/django/core/management/validation.py
21@@ -23,7 +23,7 @@ def get_validation_errors(outfile, app=None):
22     """
23     from django.conf import settings
24     from django.db import models, connection
25-    from django.db.models.loading import get_app_errors
26+    from django.db.models.loading import get_app_errors, get_model
27     from django.db.models.fields.related import RelatedObject
28     from django.db.models.deletion import SET_NULL, SET_DEFAULT
29 
30@@ -283,6 +283,17 @@ def get_validation_errors(outfile, app=None):
31                     if r.get_accessor_name() == rel_query_name:
32                         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))
33 
34+        # Check swappable attribute.
35+        if opts.swappable and getattr(settings, opts.swappable, None):
36+            swappable_setting = getattr(settings, opts.swappable)
37+            try:
38+                app_label, model_name = swappable_setting.split('.')
39+            except ValueError:
40+                e.add(opts, "Invalid settings.%s, '%s' not of the form 'app_label.app_name' for swapped out model '%s'." % (opts.swappable, swappable_setting, cls._meta.object_name))
41+                continue
42+            if get_model(app_label, model_name) not in models.get_models():
43+                e.add(opts, "'%s' has been swapped out in settings.%s to a model '%s.%s' that does not exist." % (cls._meta.object_name, opts.swappable, app_label, model_name))
44+
45         # Check ordering attribute.
46         if opts.ordering:
47             for field_name in opts.ordering: