diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index 1f8ff6d..6fe494e 100644
a
|
b
|
class BaseModelAdmin(object):
|
73 | 73 | overrides.update(self.formfield_overrides) |
74 | 74 | self.formfield_overrides = overrides |
75 | 75 | |
| 76 | def formfield_changelist_for_dbfield(self, db_field, **kwargs): |
| 77 | """ |
| 78 | Hook for specifying the form Field instance for a given database Field |
| 79 | instance when using 'list_editable' on the changelist. |
| 80 | |
| 81 | By default, returns formfield_for_dbfield. |
| 82 | """ |
| 83 | return self.formfield_for_dbfield(db_field, **kwargs) |
| 84 | |
76 | 85 | def formfield_for_dbfield(self, db_field, **kwargs): |
77 | 86 | """ |
78 | 87 | Hook for specifying the form Field instance for a given database Field |
… |
… |
class ModelAdmin(BaseModelAdmin):
|
392 | 401 | Returns a Form class for use in the Formset on the changelist page. |
393 | 402 | """ |
394 | 403 | defaults = { |
395 | | "formfield_callback": curry(self.formfield_for_dbfield, request=request), |
| 404 | "formfield_callback": curry(self.formfield_changelist_for_dbfield, request=request), |
396 | 405 | } |
397 | 406 | defaults.update(kwargs) |
398 | 407 | return modelform_factory(self.model, **defaults) |
… |
… |
class ModelAdmin(BaseModelAdmin):
|
403 | 412 | is used. |
404 | 413 | """ |
405 | 414 | defaults = { |
406 | | "formfield_callback": curry(self.formfield_for_dbfield, request=request), |
| 415 | "formfield_callback": curry(self.formfield_changelist_for_dbfield, request=request), |
407 | 416 | } |
408 | 417 | defaults.update(kwargs) |
409 | 418 | return modelformset_factory(self.model, |
diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt
index 7fee903..942c926 100644
a
|
b
|
you can pass a ``cacheable=True`` argument to :meth:`AdminSite.admin_view`::
|
853 | 853 | |
854 | 854 | (r'^my_view/$', self.admin_site.admin_view(self.my_view, cacheable=True)) |
855 | 855 | |
| 856 | .. method:: ModelAdmin.formfield_for_dbfield(self, db_field, **kwargs) |
| 857 | |
| 858 | The ``formfield_for_dbfield`` method on a ``ModelAdmin`` allows you to |
| 859 | override the default formfield used for a given database field. |
| 860 | |
| 861 | .. method:: ModelAdmin.formfield_changelist_for_dbfield(self, db_field, **kwargs) |
| 862 | |
| 863 | .. versionadded:: 1.3 |
| 864 | |
| 865 | The ``formfield_changelist_for_dbfield`` method on a ``ModelAdmin`` allows you to |
| 866 | override the default formfields used on a changelist page when list_editable is enabled. |
| 867 | Use this method to override a formfield only on the changelist. For example, to set |
| 868 | a CSS class for certain fields:: |
| 869 | |
| 870 | class MyModelAdmin(admin.ModelAdmin): |
| 871 | def formfield_changelist_for_dbfield(self, db_field, **kwargs): |
| 872 | field = super(MyModelAdmin, self).formfield_changelist_for_dbfield(db_field, **kwargs) |
| 873 | if db_field.name in ('short_field_1', 'short_field_2'): |
| 874 | field.widget.attrs['class']='smaller' |
| 875 | return field |
| 876 | |
| 877 | By default, this method just returns the result of ``formfield_for_dbfield``. |
| 878 | |
856 | 879 | .. method:: ModelAdmin.formfield_for_foreignkey(self, db_field, request, **kwargs) |
857 | 880 | |
858 | 881 | .. versionadded:: 1.1 |
diff --git a/tests/regressiontests/admin_views/customadmin.py b/tests/regressiontests/admin_views/customadmin.py
index 34e39ef..6d0632f 100644
a
|
b
|
class Admin2(admin.AdminSite):
|
26 | 26 | def my_view(self, request): |
27 | 27 | return HttpResponse("Django is a magical pony!") |
28 | 28 | |
29 | | site = Admin2(name="admin2") |
| 29 | site2 = Admin2(name="admin2") |
30 | 30 | |
31 | | site.register(models.Article, models.ArticleAdmin) |
32 | | site.register(models.Section, inlines=[models.ArticleInline]) |
33 | | site.register(models.Thing, models.ThingAdmin) |
34 | | site.register(models.Fabric, models.FabricAdmin) |
| 31 | site2.register(models.Article, models.ArticleAdmin) |
| 32 | site2.register(models.Section, inlines=[models.ArticleInline]) |
| 33 | site2.register(models.Thing, models.ThingAdmin) |
| 34 | site2.register(models.Fabric, models.FabricAdmin) |
| 35 | |
| 36 | |
| 37 | class Admin3(admin.AdminSite): pass |
| 38 | |
| 39 | site3 = Admin2(name="admin3") |
| 40 | site3.register(models.Article, models.CustomFieldsArticleAdmin) |
| 41 | site3.register(models.Section, inlines=[models.ArticleInline]) |
| 42 | site3.register(models.Thing, models.ThingAdmin) |
| 43 | site3.register(models.Fabric, models.FabricAdmin) |
diff --git a/tests/regressiontests/admin_views/models.py b/tests/regressiontests/admin_views/models.py
index a2700ba..c9eb48d 100644
a
|
b
|
class ArticleAdmin(admin.ModelAdmin):
|
106 | 106 | modeladmin_year.admin_order_field = 'date' |
107 | 107 | modeladmin_year.short_description = None |
108 | 108 | |
| 109 | class CustomFieldsArticleAdmin(admin.ModelAdmin): |
| 110 | list_display = ('pk', 'content', 'date') |
| 111 | list_editable = ('content', 'date') |
| 112 | |
| 113 | def formfield_for_dbfield(self, db_field, **kwargs): |
| 114 | field = super(CustomFieldsArticleAdmin, self).formfield_for_dbfield(db_field, **kwargs) |
| 115 | if db_field.name == 'content': |
| 116 | field.widget.attrs['class']='larger' |
| 117 | return field |
| 118 | |
| 119 | def formfield_changelist_for_dbfield(self, db_field, **kwargs): |
| 120 | field = super(CustomFieldsArticleAdmin, self).formfield_changelist_for_dbfield(db_field, **kwargs) |
| 121 | if db_field.name == 'content': |
| 122 | field.widget.attrs['class']='smaller' |
| 123 | return field |
| 124 | |
| 125 | |
109 | 126 | class CustomArticle(models.Model): |
110 | 127 | content = models.TextField() |
111 | 128 | date = models.DateTimeField() |
diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py
index 1385e5e..c88e9c2 100644
a
|
b
|
class CustomModelAdminTest(AdminViewBasicTest):
|
360 | 360 | response = self.client.get('/test_admin/%s/my_view/' % self.urlbit) |
361 | 361 | self.assert_(response.content == "Django is a magical pony!", response.content) |
362 | 362 | |
| 363 | class CustomFieldsAdminTest(TestCase): |
| 364 | fixtures = ['admin-views-users.xml', 'admin-views-colors.xml', 'admin-views-fabrics.xml'] |
| 365 | |
| 366 | def setUp(self): |
| 367 | self.old_language_code = settings.LANGUAGE_CODE |
| 368 | self.client.login(username='super', password='secret') |
| 369 | |
| 370 | def tearDown(self): |
| 371 | settings.LANGUAGE_CODE = self.old_language_code |
| 372 | self.client.logout() |
| 373 | |
| 374 | def testCustomFormField(self): |
| 375 | response = self.client.get('/test_admin/admin3/admin_views/article/1/') |
| 376 | self.failUnlessEqual(response.status_code, 200) |
| 377 | self.failUnless('class="larger"' in response.content) |
| 378 | self.failIf('class="smaller"' in response.content) |
| 379 | |
| 380 | def testCustomFormFieldOnList(self): |
| 381 | response = self.client.get('/test_admin/admin3/admin_views/article/') |
| 382 | self.failUnlessEqual(response.status_code, 200) |
| 383 | self.failUnless('class="smaller"' in response.content) |
| 384 | self.failIf('class="larger"' in response.content) |
| 385 | |
363 | 386 | def get_perm(Model, perm): |
364 | 387 | """Return the permission object, for the Model""" |
365 | 388 | ct = ContentType.objects.get_for_model(Model) |
diff --git a/tests/regressiontests/admin_views/urls.py b/tests/regressiontests/admin_views/urls.py
index f3f1fbd..d4b8d11 100644
a
|
b
|
urlpatterns = patterns('',
|
7 | 7 | (r'^admin/doc/', include('django.contrib.admindocs.urls')), |
8 | 8 | (r'^admin/secure-view/$', views.secure_view), |
9 | 9 | (r'^admin/', include(admin.site.urls)), |
10 | | (r'^admin2/', include(customadmin.site.urls)), |
| 10 | (r'^admin2/', include(customadmin.site2.urls)), |
| 11 | (r'^admin3/', include(customadmin.site3.urls)), |
11 | 12 | ) |