From e58c75fbdfbc2f11a1d3d6fd949f7375199c6663 Mon Sep 17 00:00:00 2001 From: Brian Rosner Date: Wed, 31 Mar 2010 07:43:52 +0000 Subject: [PATCH] Restored pre-r10062 behavior allowing None from formfield_callback to exclude itself from the form git-svn-id: http://code.djangoproject.com/svn/django/trunk@12891 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/forms/models.py | 8 ++++++- tests/modeltests/model_forms/models.py | 29 ++++++++++++++++++++++++++ 2 files changed, 36 insertions(+), 1 deletion(-) 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 +# Model field that returns None to exclude itself with explicit fields ######## + +>>> class CustomFieldForExclusionForm(ModelForm): +... class Meta: +... model = CustomFieldForExclusionModel +... fields = ['name', 'markup'] + +>>> CustomFieldForExclusionForm.base_fields.keys() +['name'] + +>>> print CustomFieldForExclusionForm() + + # Clean up >>> import shutil >>> shutil.rmtree(temp_storage_dir)