Ticket #8620: 8620_3.diff

File 8620_3.diff, 3.4 KB (added by koenb, 3 years ago)

patch with test and doc for 8620

  • docs/topics/forms/modelforms.txt

     
    516516This adds the extra method from the ``EnhancedArticleForm`` and modifies
    517517the original ``ArticleForm.Meta`` to remove one field.
    518518
     519If you need to remove a field from the child form that was explicitly defined in
     520a parent form, you can include it in the ``Meta.exclude`` list.
     521
     522An example::
     523
     524    class ArticleForm(ModelForm):
     525        notes = TextField()
     526       
     527        class Meta:
     528            model = Article
     529
     530    class EnhancedArticleForm(ArticleForm):
     531        class Meta(ArticleForm.Meta):
     532            exclude = ('notes',)
     533
     534The ``EnhancedArticleForm`` will not include the field ``notes``, though it was
     535explicitly declared on ``ArticleForm``.
     536
    519537There are a couple of things to note, however.
    520538
    521539* Normal Python name resolution rules apply. If you have multiple base
  • django/forms/models.py

     
    215215                raise FieldError(message)
    216216            # Override default model fields with any custom declared ones
    217217            # (plus, include all the other declared fields).
     218            # Leave out custom declared fields mentioned in exclude
     219            if opts.exclude:
     220                [declared_fields.pop(f) for f in declared_fields.keys() if f in opts.exclude]
    218221            fields.update(declared_fields)
    219222        else:
    220223            fields = declared_fields
  • tests/regressiontests/forms/tests/models.py

     
    55
    66from django.core.files.uploadedfile import SimpleUploadedFile
    77from django.db import models
    8 from django.forms import Form, ModelForm, FileField, ModelChoiceField
     8from django.forms import Form, ModelForm, FileField, ModelChoiceField, CharField
    99from django.forms.models import ModelFormMetaclass
    1010from django.test import TestCase
    1111
     
    160160
    161161        f = ExcludingForm({'name': u'Hello', 'value': 99, 'def_date': datetime.date(1999, 3, 2)})
    162162        self.assertTrue(f.is_valid())
    163         self.assertEqual(f.cleaned_data['name'], u'Hello')
     163        self.assertNotIn('name', f.cleaned_data)
    164164        obj = f.save()
    165165        self.assertEqual(obj.name, u'class default value')
    166166        self.assertEqual(obj.value, 99)
     
    196196            model=A
    197197
    198198        self.assertTrue(issubclass(ModelFormMetaclass('Form', (ModelForm,), {'Meta': Meta}), ModelForm))
     199
     200
     201class TestTicket8620(TestCase):
     202    '''Allow exclusion of not only model fields but also form fields (as
     203    might be defined in a superclass) using the exclude Meta attribute.'''
     204
     205    class ParentForm(ModelForm):
     206        extra_non_model_field = CharField()
     207
     208    class ChildForm(ParentForm):
     209        class Meta:
     210            model = Defaults  # any model is suitable for this test
     211            exclude = ('extra_non_model_field',)
     212
     213    def test_extra_non_model_field_is_excluded(self):
     214        form = TestTicket8620.ChildForm()
     215        self.assertNotIn('extra_non_model_field', form.fields)
     216
Back to Top