Code

Ticket #15126: django15126.testfields.diff

File django15126.testfields.diff, 3.1 KB (added by anonymous, 3 years ago)
Line 
1Index: tests/regressiontests/forms/tests/models.py
2===================================================================
3--- tests/regressiontests/forms/tests/models.py (revision 15361)
4+++ tests/regressiontests/forms/tests/models.py (working copy)
5@@ -1,6 +1,7 @@
6 # -*- coding: utf-8 -*-
7 import datetime
8 from django.core.files.uploadedfile import SimpleUploadedFile
9+from django.core.exceptions import FieldError
10 from django.forms import Form, ModelForm, FileField, ModelChoiceField
11 from django.test import TestCase
12 from regressiontests.forms.models import ChoiceModel, ChoiceOptionModel, ChoiceFieldModel, FileModel, Group, BoundaryModel, Defaults
13@@ -159,3 +160,35 @@
14         self.assertEqual(obj.name, u'class default value')
15         self.assertEqual(obj.value, 99)
16         self.assertEqual(obj.def_date, datetime.date(1999, 3, 2))
17+
18+    def test_fields_validation(self):
19+        """ Test whether 'fields' and 'exclude' options are validated #15126 """
20+
21+        class ValidModelForm(ModelForm):
22+            class Meta:
23+                model = Defaults
24+                fields = ('name', )
25+                exclude = ('value', )
26+
27+        valid_form = ValidModelForm()
28+        self.assertEqual(valid_form._meta.fields, ('name', ))
29+
30+        try:
31+            class InvalidFieldsModelForm(ModelForm):
32+                class Meta:
33+                    model = Defaults
34+                    fields = ('name') # Not a valid list, but a string
35+            self.fail('Incorrect "fields"-option type not detected on ModelForm')
36+        except TypeError: # correct TypeError
37+            pass
38+        except FieldError: # missing field because of faulty typing
39+            self.fail('Incorrect "fields"-option type not detected on ModelForm')
40+
41+        try:
42+            class InvalidExcludeModelForm(ModelForm):
43+                class Meta:
44+                    model = Defaults
45+                    exclude = ('name') # Not a valid list, but a string
46+            self.fail('Incorrect "exclude"-option type not detected on ModelForm')
47+        except TypeError: # correct TypeError
48+            pass
49Index: django/forms/models.py
50===================================================================
51--- django/forms/models.py      (revision 15361)
52+++ django/forms/models.py      (working copy)
53@@ -200,6 +200,17 @@
54         if 'media' not in attrs:
55             new_class.media = media_property(new_class)
56         opts = new_class._meta = ModelFormOptions(getattr(new_class, 'Meta', None))
57+
58+        def _check_option_iterable(option):
59+            """ Check whether option is a valid iterable and retrieve from options (#15126) """
60+            value = getattr(opts, option, None)
61+            if value is not None and isinstance(value, str):
62+                raise TypeError('Option "%s" on %s must be a valid list'
63+                    ', not "%s".' % (option, new_class.__name__, type(value).__name__))
64+
65+        _check_option_iterable('fields')
66+        _check_option_iterable('exclude')
67+       
68         if opts.model:
69             # If a model is defined, extract form fields from it.
70             fields = fields_for_model(opts.model, opts.fields,