diff --git a/django/forms/models.py b/django/forms/models.py index 608b87bd33..42de898aa7 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -167,6 +167,7 @@ def fields_for_model(model, fields=None, exclude=None, widgets=None, formfield_c in the ``fields`` argument. """ field_list = [] + ignored = [] opts = model._meta for f in opts.fields + opts.many_to_many: if not f.editable: @@ -182,9 +183,14 @@ def fields_for_model(model, fields=None, exclude=None, widgets=None, formfield_c formfield = formfield_callback(f, **kwargs) if formfield: field_list.append((f.name, formfield)) + else: + ignored.append(f.name) field_dict = SortedDict(field_list) if fields: - field_dict = SortedDict([(f, field_dict.get(f)) for f in fields if (not exclude) or (exclude and f not in exclude)]) + field_dict = SortedDict( + [(f, field_dict.get(f)) for f in fields + if ((not exclude) or (exclude and f not in exclude)) and (f not in ignored)] + ) return field_dict class ModelFormOptions(object): diff --git a/tests/modeltests/model_forms/models.py b/tests/modeltests/model_forms/models.py index 998f212fae..e7c4022f6f 100644 --- a/tests/modeltests/model_forms/models.py +++ b/tests/modeltests/model_forms/models.py @@ -220,6 +220,22 @@ class BigInt(models.Model): def __unicode__(self): return unicode(self.biggie) +class MarkupField(models.CharField): + def __init__(self, *args, **kwargs): + kwargs["max_length"] = 20 + super(MarkupField, self).__init__(*args, **kwargs) + + def formfield(self, **kwargs): + # don't allow this field to be used in form (real use-case might be + # that you know the markup will always be X, but it is among an app + # that allows the user to say it could be something else) + # regressed at r10062 + return None + +class CustomFieldForExclusionModel(models.Model): + name = models.CharField(max_length=10) + markup = MarkupField() + __test__ = {'API_TESTS': """ >>> from django import forms >>> from django.forms.models import ModelForm, model_to_dict @@ -1540,6 +1556,19 @@ ValidationError: [u'Select a valid choice. z is not one of the available choices