From 64e4ffc932c78e6ccd66f20d5d74083fda3a3915 Mon Sep 17 00:00:00 2001 From: Brian Rosner Date: Wed, 31 Mar 2010 08:08:29 +0000 Subject: [PATCH] [1.1.X] Restored pre-r10062 behavior allowing None from formfield_callback to exclude itself from the form Backported from r12891 from trunk git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.1.X@12892 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 1b2bf372c5..959c34e31f 100644 --- a/django/forms/models.py +++ b/django/forms/models.py @@ -154,6 +154,7 @@ def fields_for_model(model, fields=None, exclude=None, formfield_callback=lambda in the ``fields`` argument. """ field_list = [] + ignored = [] opts = model._meta for f in opts.fields + opts.many_to_many: if not f.editable: @@ -165,9 +166,14 @@ def fields_for_model(model, fields=None, exclude=None, formfield_callback=lambda formfield = formfield_callback(f) 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 92e05e19ef..b20d5dd8c9 100644 --- a/tests/modeltests/model_forms/models.py +++ b/tests/modeltests/model_forms/models.py @@ -205,6 +205,22 @@ class Post(models.Model): def __unicode__(self): return self.name +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 @@ -1547,6 +1563,19 @@ False >>> f.is_valid() True +# 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)