Commit eb0751a4 authored by Joseph Kocherhans's avatar Joseph Kocherhans
Browse files

Fixed #12901. Exclude overridden form fields from model field validation. Thanks, Honza Král.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12496 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent 9b8c44c3
Loading
Loading
Loading
Loading
+21 −3
Original line number Diff line number Diff line
@@ -276,10 +276,18 @@ class BaseModelForm(BaseForm):
            # 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.
@@ -719,16 +727,26 @@ class BaseInlineFormSet(BaseModelFormSet):
    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]
+21 −0
Original line number Diff line number Diff line
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()