Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fixed #11905: Raise an error on model form creation if a non-existent…
… field was listed in fields. Thanks ben and copelco.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@13739 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
kmtracey committed Sep 11, 2010
1 parent 9802a73 commit 3444b06
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 1 deletion.
12 changes: 11 additions & 1 deletion django/forms/models.py
Expand Up @@ -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
Expand Down Expand Up @@ -224,6 +225,15 @@ def __new__(cls, name, bases, attrs):
# 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)
Expand Down
39 changes: 39 additions & 0 deletions tests/regressiontests/model_forms_regress/tests.py
Expand Up @@ -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
Expand Down Expand Up @@ -294,3 +295,41 @@ def test_bad_callback(self):
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'])

0 comments on commit 3444b06

Please sign in to comment.