Ticket #14496: 14496.custom-admin-form-exclude.diff
File 14496.custom-admin-form-exclude.diff, 6.8 KB (added by , 13 years ago) |
---|
-
django/contrib/admin/options.py
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index c603210..af0c146 100644
a b class ModelAdmin(BaseModelAdmin): 428 428 exclude = list(self.exclude) 429 429 exclude.extend(kwargs.get("exclude", [])) 430 430 exclude.extend(self.get_readonly_fields(request, obj)) 431 if hasattr(self.form, '_meta') and self.form._meta.exclude: 432 # Take into account the custom ModelForm's Meta.exclude. 433 exclude.extend(self.form.Meta.exclude) 431 434 # if exclude is an empty list we pass None to be consistant with the 432 435 # default on modelform_factory 433 436 exclude = exclude or None … … class InlineModelAdmin(BaseModelAdmin): 1330 1333 exclude = list(self.exclude) 1331 1334 exclude.extend(kwargs.get("exclude", [])) 1332 1335 exclude.extend(self.get_readonly_fields(request, obj)) 1336 if hasattr(self.form, '_meta') and self.form._meta.exclude: 1337 # Take into account the custom ModelForm's Meta.exclude. 1338 exclude.extend(self.form.Meta.exclude) 1333 1339 # if exclude is an empty list we use None, since that's the actual 1334 1340 # default 1335 1341 exclude = exclude or None -
docs/ref/contrib/admin/index.txt
diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt index fb48ba8..ba1593d 100644
a b subclass:: 293 293 294 294 For an example see the section `Adding custom validation to the admin`_. 295 295 296 .. admonition:: Note 297 298 .. versionchanged:: 1.4 299 300 If your own ``ModelForm`` defines an ``exclude`` list of fields in its 301 ``Meta`` options, then that list of fields will automatically 302 be combined to that of the ``ModelAdmin``'s own ``exclude`` list:: 303 304 class PersonForm(forms.ModelForm): 305 306 class Meta: 307 model = Person 308 exclude = ['name'] 309 310 class PersonAdmin(admin.ModelAdmin): 311 exclude = ['age'] 312 form = PersonForm 313 314 In the above example, the two fields "name" and "age" will be excluded from the 315 generated form. 316 296 317 .. attribute:: ModelAdmin.formfield_overrides 297 318 298 319 This provides a quick-and-dirty way to override some of the -
docs/releases/1.4.txt
diff --git a/docs/releases/1.4.txt b/docs/releases/1.4.txt index 6a126ed..fef786a 100644
a b A new helper function, 60 60 ``template.Library`` to ease the creation of template tags that store some 61 61 data in a specified context variable. 62 62 63 ``exclude`` in ``ModelAdmin`` and custom admin forms 64 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 65 66 If you define a custom ``ModelForm`` in a ``ModelAdmin`` and that form 67 defines an ``exclude`` list of fields in its ``Meta`` options, then that list 68 of fields will automatically be combined to that of the ``ModelAdmin``'s own 69 ``exclude`` list:: 70 71 class PersonForm(forms.ModelForm): 72 73 class Meta: 74 model = Person 75 exclude = ['name'] 76 77 class PersonAdmin(admin.ModelAdmin): 78 exclude = ['age'] 79 form = PersonForm 80 81 In the above example, the two fields "name" and "age" will be excluded from the 82 generated form. 83 63 84 .. _backwards-incompatible-changes-1.4: 64 85 65 86 Backwards incompatible changes in 1.4 -
tests/regressiontests/modeladmin/tests.py
diff --git a/tests/regressiontests/modeladmin/tests.py b/tests/regressiontests/modeladmin/tests.py index 530b476..70b3e3e 100644
a b class ModelAdminTests(TestCase): 119 119 ma = BandAdmin(Band, self.site) 120 120 self.assertEqual(ma.get_form(request).base_fields.keys(), 121 121 ['name']) 122 123 def test_custom_form_meta_exclude_with_readonly(self): 124 """ 125 Ensure that the custom ModelForm's `Meta.exclude` is respected when 126 used in conjunction with readonly fields. 127 Refs #14496. 128 """ 129 # First, with `ModelAdmin` ----------------------- 130 131 class AdminBandForm(forms.ModelForm): 132 133 class Meta: 134 model = Band 135 exclude = ['bio'] 122 136 137 class BandAdmin(ModelAdmin): 138 readonly_fields = ['name'] 139 form = AdminBandForm 140 141 ma = BandAdmin(Band, self.site) 142 self.assertEqual(ma.get_form(request).base_fields.keys(), 143 ['sign_date',]) 144 145 # Then, with `InlineModelAdmin` ----------------- 146 147 class AdminConcertForm(forms.ModelForm): 148 149 class Meta: 150 model = Concert 151 exclude = ['day'] 152 153 class ConcertInline(TabularInline): 154 readonly_fields = ['transport'] 155 form = AdminConcertForm 156 fk_name = 'main_band' 157 model = Concert 158 159 class BandAdmin(ModelAdmin): 160 inlines = [ 161 ConcertInline 162 ] 163 164 ma = BandAdmin(Band, self.site) 165 self.assertEqual( 166 list(ma.get_formsets(request))[0]().forms[0].fields.keys(), 167 ['main_band', 'opening_band', 'id', 'DELETE',]) 168 169 def test_custom_form_meta_exclude(self): 170 """ 171 Ensure that the custom ModelForm's `Meta.exclude` is respected. 172 Refs #14496. 173 """ 174 # First, with `ModelAdmin` ----------------------- 175 176 class AdminBandForm(forms.ModelForm): 177 178 class Meta: 179 model = Band 180 exclude = ['bio'] 181 182 class BandAdmin(ModelAdmin): 183 exclude = ['name'] 184 form = AdminBandForm 185 186 ma = BandAdmin(Band, self.site) 187 self.assertEqual(ma.get_form(request).base_fields.keys(), 188 ['sign_date',]) 189 190 # Then, with `InlineModelAdmin` ----------------- 191 192 class AdminConcertForm(forms.ModelForm): 193 194 class Meta: 195 model = Concert 196 exclude = ['day'] 197 198 class ConcertInline(TabularInline): 199 exclude = ['transport'] 200 form = AdminConcertForm 201 fk_name = 'main_band' 202 model = Concert 203 204 class BandAdmin(ModelAdmin): 205 inlines = [ 206 ConcertInline 207 ] 208 209 ma = BandAdmin(Band, self.site) 210 self.assertEqual( 211 list(ma.get_formsets(request))[0]().forms[0].fields.keys(), 212 ['main_band', 'opening_band', 'id', 'DELETE',]) 213 123 214 def test_custom_form_validation(self): 124 215 # If we specify a form, it should use it allowing custom validation to work 125 216 # properly. This won't, however, break any of the admin widgets or media.