Loading django/forms/models.py +7 −1 Original line number Diff line number Diff line Loading @@ -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: Loading @@ -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): Loading tests/modeltests/model_forms/models.py +29 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -1540,6 +1556,19 @@ ValidationError: [u'Select a valid choice. z is not one of the available choices <tr><th><label for="id_description">Description:</label></th><td><input type="text" name="description" id="id_description" /></td></tr> <tr><th><label for="id_url">The URL:</label></th><td><input id="id_url" type="text" name="url" maxlength="40" /></td></tr> # 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() <tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="text" name="name" maxlength="10" /></td></tr> # Clean up >>> import shutil >>> shutil.rmtree(temp_storage_dir) Loading Loading
django/forms/models.py +7 −1 Original line number Diff line number Diff line Loading @@ -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: Loading @@ -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): Loading
tests/modeltests/model_forms/models.py +29 −0 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -1540,6 +1556,19 @@ ValidationError: [u'Select a valid choice. z is not one of the available choices <tr><th><label for="id_description">Description:</label></th><td><input type="text" name="description" id="id_description" /></td></tr> <tr><th><label for="id_url">The URL:</label></th><td><input id="id_url" type="text" name="url" maxlength="40" /></td></tr> # 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() <tr><th><label for="id_name">Name:</label></th><td><input id="id_name" type="text" name="name" maxlength="10" /></td></tr> # Clean up >>> import shutil >>> shutil.rmtree(temp_storage_dir) Loading