mirror of https://github.com/django/django.git
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
This commit is contained in:
parent
9802a73e25
commit
3444b065ba
|
@ -9,7 +9,8 @@ from django.utils.datastructures import SortedDict
|
||||||
from django.utils.text import get_text_list, capfirst
|
from django.utils.text import get_text_list, capfirst
|
||||||
from django.utils.translation import ugettext_lazy as _, ugettext
|
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 django.core.validators import EMPTY_VALUES
|
||||||
from util import ErrorList
|
from util import ErrorList
|
||||||
from forms import BaseForm, get_declared_fields
|
from forms import BaseForm, get_declared_fields
|
||||||
|
@ -224,6 +225,15 @@ class ModelFormMetaclass(type):
|
||||||
# If a model is defined, extract form fields from it.
|
# If a model is defined, extract form fields from it.
|
||||||
fields = fields_for_model(opts.model, opts.fields,
|
fields = fields_for_model(opts.model, opts.fields,
|
||||||
opts.exclude, opts.widgets, formfield_callback)
|
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
|
# Override default model fields with any custom declared ones
|
||||||
# (plus, include all the other declared fields).
|
# (plus, include all the other declared fields).
|
||||||
fields.update(declared_fields)
|
fields.update(declared_fields)
|
||||||
|
|
|
@ -5,6 +5,7 @@ from django import forms
|
||||||
from django.forms.models import modelform_factory, ModelChoiceField
|
from django.forms.models import modelform_factory, ModelChoiceField
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.test import TestCase
|
from django.test import TestCase
|
||||||
|
from django.core.exceptions import FieldError
|
||||||
|
|
||||||
from models import Person, RealPerson, Triple, FilePathModel, Article, \
|
from models import Person, RealPerson, Triple, FilePathModel, Article, \
|
||||||
Publication, CustomFF, Author, Author1, Homepage
|
Publication, CustomFF, Author, Author1, Homepage
|
||||||
|
@ -294,3 +295,41 @@ class FormFieldCallbackTests(TestCase):
|
||||||
self.assertRaises(TypeError, modelform_factory, Person,
|
self.assertRaises(TypeError, modelform_factory, Person,
|
||||||
formfield_callback='not a function or callable')
|
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'])
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue