Author: kmtracey
Date: 2010-09-10 20:39:16 -0500 (Fri, 10 Sep 2010)
New Revision: 13739

Modified:
   django/trunk/django/forms/models.py
   django/trunk/tests/regressiontests/model_forms_regress/tests.py
Log:
Fixed #11905: Raise an error on model form creation if a non-existent field was 
listed in fields. Thanks ben and copelco.


Modified: django/trunk/django/forms/models.py
===================================================================
--- django/trunk/django/forms/models.py 2010-09-11 00:20:35 UTC (rev 13738)
+++ django/trunk/django/forms/models.py 2010-09-11 01:39:16 UTC (rev 13739)
@@ -9,7 +9,8 @@
 from django.utils.text import get_text_list, capfirst
 from django.utils.translation import ugettext_lazy as _, ugettext
 
-from django.core.exceptions import ValidationError, NON_FIELD_ERRORS
+from django.core.exceptions import ValidationError, NON_FIELD_ERRORS, \
+                                   FieldError
 from django.core.validators import EMPTY_VALUES
 from util import ErrorList
 from forms import BaseForm, get_declared_fields
@@ -224,6 +225,15 @@
             # If a model is defined, extract form fields from it.
             fields = fields_for_model(opts.model, opts.fields,
                                       opts.exclude, opts.widgets, 
formfield_callback)
+            # make sure opts.fields doesn't specify an invalid field
+            none_model_fields = [k for k, v in fields.iteritems() if not v]
+            missing_fields = set(none_model_fields) - \
+                             set(declared_fields.keys())
+            if missing_fields:
+                message = 'Unknown field(s) (%s) specified for %s'
+                message = message % (', '.join(missing_fields),
+                                     opts.model.__name__)
+                raise FieldError(message)
             # Override default model fields with any custom declared ones
             # (plus, include all the other declared fields).
             fields.update(declared_fields)

Modified: django/trunk/tests/regressiontests/model_forms_regress/tests.py
===================================================================
--- django/trunk/tests/regressiontests/model_forms_regress/tests.py     
2010-09-11 00:20:35 UTC (rev 13738)
+++ django/trunk/tests/regressiontests/model_forms_regress/tests.py     
2010-09-11 01:39:16 UTC (rev 13739)
@@ -5,6 +5,7 @@
 from django.forms.models import modelform_factory, ModelChoiceField
 from django.conf import settings
 from django.test import TestCase
+from django.core.exceptions import FieldError
 
 from models import Person, RealPerson, Triple, FilePathModel, Article, \
     Publication, CustomFF, Author, Author1, Homepage
@@ -294,3 +295,41 @@
         self.assertRaises(TypeError, modelform_factory, Person,
                           formfield_callback='not a function or callable')
 
+
+class InvalidFieldAndFactory(TestCase):
+    """ Tests for #11905 """
+
+    def test_extra_field_model_form(self):
+        try:
+            class ExtraPersonForm(forms.ModelForm):
+                """ ModelForm with an extra field """
+
+                age = forms.IntegerField()
+
+                class Meta:
+                    model = Person
+                    fields = ('name', 'no-field')
+        except FieldError, e:
+            # Make sure the exception contains some reference to the 
+            # field responsible for the problem.
+            self.assertTrue('no-field' in e.args[0])
+        else:
+            self.fail('Invalid "no-field" field not caught')
+
+    def test_extra_declared_field_model_form(self):
+        try:
+            class ExtraPersonForm(forms.ModelForm):
+                """ ModelForm with an extra field """
+
+                age = forms.IntegerField()
+
+                class Meta:
+                    model = Person
+                    fields = ('name', 'age')
+        except FieldError:
+            self.fail('Declarative field raised FieldError incorrectly')
+
+    def test_extra_field_modelform_factory(self):
+        self.assertRaises(FieldError, modelform_factory,
+                          Person, fields=['no-field', 'name'])
+

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to