Skip to content

Commit

Permalink
Fixed #12901. Exclude overridden form fields from model field validat…
Browse files Browse the repository at this point in the history
…ion. Thanks, Honza Král.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12496 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
jkocherhans committed Feb 22, 2010
1 parent 9b8c44c commit eb0751a
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 3 deletions.
24 changes: 21 additions & 3 deletions django/forms/models.py
Expand Up @@ -276,10 +276,18 @@ def _get_validation_exclusions(self):
# adding these values to the model after form validation.
if field not in self.fields:
exclude.append(f.name)

# Don't perform model validation on fields that were defined
# manually on the form and excluded via the ModelForm's Meta
# class. See #12901.
elif self._meta.fields and field not in self._meta.fields:
exclude.append(f.name)

# Exclude fields that failed form validation. There's no need for
# the model fields to validate them as well.
elif field in self._errors.keys():
exclude.append(f.name)

# Exclude empty fields that are not required by the form. The
# underlying model field may be required, so this keeps the model
# field from raising that error.
Expand Down Expand Up @@ -719,16 +727,26 @@ def save_new(self, form, commit=True):
def add_fields(self, form, index):
super(BaseInlineFormSet, self).add_fields(form, index)
if self._pk_field == self.fk:
form.fields[self._pk_field.name] = InlineForeignKeyField(self.instance, pk_field=True)
name = self._pk_field.name
kwargs = {'pk_field': True}
else:
# The foreign key field might not be on the form, so we poke at the
# Model field to get the label, since we need that for error messages.
name = self.fk.name
kwargs = {
'label': getattr(form.fields.get(self.fk.name), 'label', capfirst(self.fk.verbose_name))
'label': getattr(form.fields.get(name), 'label', capfirst(self.fk.verbose_name))
}
if self.fk.rel.field_name != self.fk.rel.to._meta.pk.name:
kwargs['to_field'] = self.fk.rel.field_name
form.fields[self.fk.name] = InlineForeignKeyField(self.instance, **kwargs)

form.fields[name] = InlineForeignKeyField(self.instance, **kwargs)

# Add the generated field to form._meta.fields if it's defined to make
# sure validation isn't skipped on that field.
if form._meta.fields:
if isinstance(form._meta.fields, tuple):
form._meta.fields = list(form._meta.fields)
form._meta.fields.append(self.fk.name)

def get_unique_error_message(self, unique_check):
unique_check = [field for field in unique_check if field != self.fk.name]
Expand Down
21 changes: 21 additions & 0 deletions tests/modeltests/model_forms/tests.py
@@ -0,0 +1,21 @@
from django.test import TestCase
from django import forms
from models import Category


class IncompleteCategoryForm(forms.ModelForm):
"""
A form that replaces the model's url field with a custom one. This should
prevent the model field's validation from being called.
"""
url = forms.CharField(required=False)

class Meta:
fields = ('name', 'slug')
model = Category

class ValidationTest(TestCase):
def test_validates_with_replaced_field(self):
form = IncompleteCategoryForm(data={'name': 'some name', 'slug': 'some-slug'})
assert form.is_valid()

0 comments on commit eb0751a

Please sign in to comment.