diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index c603210..206399b 100644
a
|
b
|
class BaseModelAdmin(object):
|
70 | 70 | formfield_overrides = {} |
71 | 71 | readonly_fields = () |
72 | 72 | ordering = None |
| 73 | exclude_add = [] |
73 | 74 | |
74 | 75 | def __init__(self): |
75 | 76 | overrides = FORMFIELD_FOR_DBFIELD_DEFAULTS.copy() |
… |
… |
class BaseModelAdmin(object):
|
113 | 114 | related_modeladmin = self.admin_site._registry.get( |
114 | 115 | db_field.rel.to) |
115 | 116 | can_add_related = bool(related_modeladmin and |
116 | | related_modeladmin.has_add_permission(request)) |
| 117 | related_modeladmin.has_add_permission(request) and |
| 118 | db_field.name not in self.exclude_add) |
117 | 119 | formfield.widget = widgets.RelatedFieldWidgetWrapper( |
118 | 120 | formfield.widget, db_field.rel, self.admin_site, |
119 | 121 | can_add_related=can_add_related) |
diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt
index fb48ba8..e0f1c25 100644
a
|
b
|
subclass::
|
267 | 267 | ``django.utils.html.escape()`` to escape any HTML special |
268 | 268 | characters. |
269 | 269 | |
| 270 | .. attribute:: ModelAdmin.exclude_add |
| 271 | |
| 272 | Disable the related field "add another" popup for any field listed. |
| 273 | |
| 274 | For example:: |
| 275 | |
| 276 | class BookAdmin(admin.ModelAdmin): |
| 277 | exclude_add = ['author'] |
| 278 | |
| 279 | In the admin form for the Book model, the author field will appear without |
| 280 | the popup link next to it. |
| 281 | |
270 | 282 | .. attribute:: ModelAdmin.filter_horizontal |
271 | 283 | |
272 | 284 | By default, a :class:`~django.db.models.ManyToManyField` is displayed in |
diff --git a/tests/regressiontests/admin_views/models.py b/tests/regressiontests/admin_views/models.py
index 854fb60..4c7e8b8 100644
a
|
b
|
class Answer(models.Model):
|
723 | 723 | def __unicode__(self): |
724 | 724 | return self.answer |
725 | 725 | |
| 726 | class AnswerAdmin(admin.ModelAdmin): |
| 727 | exclude_add = ['question'] |
| 728 | |
726 | 729 | class Reservation(models.Model): |
727 | 730 | start_date = models.DateTimeField() |
728 | 731 | price = models.IntegerField() |
… |
… |
admin.site.register(Pizza, PizzaAdmin)
|
864 | 867 | admin.site.register(Topping) |
865 | 868 | admin.site.register(Album, AlbumAdmin) |
866 | 869 | admin.site.register(Question) |
867 | | admin.site.register(Answer) |
| 870 | admin.site.register(Answer, AnswerAdmin) |
868 | 871 | admin.site.register(PrePopulatedPost, PrePopulatedPostAdmin) |
diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py
index 25740bc..33dd6bf 100644
a
|
b
|
class AdminViewBasicTest(TestCase):
|
119 | 119 | response = self.client.post('/test_admin/%s/admin_views/section/add/' % self.urlbit, post_data) |
120 | 120 | self.assertEqual(response.status_code, 302) # redirect somewhere |
121 | 121 | |
| 122 | def testExcludeAdd(self): |
| 123 | """ |
| 124 | Test if we can disable "add" popup links in the admin |
| 125 | """ |
| 126 | response = self.client.get(reverse('admin:admin_views_answer_add')) |
| 127 | self.assertNotContains(response, """<a href="/test_admin/admin/admin_views/question/add/" class="add-another" id="add_id_question" onclick="return showAddAnotherPopup(this);"> <img src="/static/admin/img/admin/icon_addlink.gif" width="10" height="10" alt="Add Another"/></a>""") |
| 128 | |
122 | 129 | def testPopupAddPost(self): |
123 | 130 | """ |
124 | 131 | Ensure http response from a popup is properly escaped. |