### Eclipse Workspace Patch 1.0
#P Django trunk
Index: django/contrib/admin/widgets.py
===================================================================
--- django/contrib/admin/widgets.py	(revision 11231)
+++ django/contrib/admin/widgets.py	(working copy)
@@ -197,13 +197,18 @@
     This class is a wrapper to a given widget to add the add icon for the
     admin interface.
     """
-    def __init__(self, widget, rel, admin_site):
+    def __init__(self, widget, rel, admin_site, can_add_related=None):
         self.is_hidden = widget.is_hidden
         self.needs_multipart_form = widget.needs_multipart_form
         self.attrs = widget.attrs
         self.choices = widget.choices
         self.widget = widget
         self.rel = rel
+        # Backwards compatible check for whether a user can add related
+        # objects.
+        if can_add_related is None:
+            can_add_related = rel_to in self.admin_site._registry
+        self.can_add_related = can_add_related
         # so we can check if the related object is registered with this AdminSite
         self.admin_site = admin_site
 
@@ -228,7 +233,7 @@
             related_url = '../../../%s/%s/add/' % info
         self.widget.choices = self.choices
         output = [self.widget.render(name, value, *args, **kwargs)]
-        if rel_to in self.admin_site._registry: # If the related object has an admin interface:
+        if self.can_add_related:
             # TODO: "id_" is hard-coded here. This should instead use the correct
             # API to determine the ID dynamically.
             output.append(u'<a href="%s" class="add-another" id="add_id_%s" onclick="return showAddAnotherPopup(this);"> ' % \
Index: django/contrib/admin/options.py
===================================================================
--- django/contrib/admin/options.py	(revision 11231)
+++ django/contrib/admin/options.py	(working copy)
@@ -102,7 +102,13 @@
             # rendered output. formfield can be None if it came from a
             # OneToOneField with parent_link=True or a M2M intermediary.
             if formfield and db_field.name not in self.raw_id_fields:
-                formfield.widget = widgets.RelatedFieldWidgetWrapper(formfield.widget, db_field.rel, self.admin_site)
+                related_modeladmin = self.admin_site._registry.get(
+                                                            db_field.rel.to)
+                can_add_related = bool(related_modeladmin and
+                            related_modeladmin.has_add_permission(request))
+                formfield.widget = widgets.RelatedFieldWidgetWrapper(
+                            formfield.widget, db_field.rel, self.admin_site,
+                            can_add_related=can_add_related)
 
             return formfield
 
Index: tests/regressiontests/admin_views/tests.py
===================================================================
--- tests/regressiontests/admin_views/tests.py	(revision 11231)
+++ tests/regressiontests/admin_views/tests.py	(working copy)
@@ -516,6 +516,28 @@
                         'Plural error message not found in response to post with multiple errors.')
         self.client.get('/test_admin/admin/logout/')
 
+    def testConditionallyShowAddSectionLink(self):
+        """
+        The foreign key widget should only show the "add related" button if the
+        user has permission to add that related item.
+        """
+        # Set up and log in user.
+        url = '/test_admin/admin/admin_views/article/add/'
+        add_link_text = ' class="add-another"'
+        self.client.get('/test_admin/admin/')
+        self.client.post('/test_admin/admin/', self.adduser_login)
+        # The add user can't add sections yet, so they shouldn't see the "add
+        # section" link.
+        response = self.client.get(url)
+        self.assertNotContains(response, add_link_text)
+        # Allow the add user to add sections too. Now they can see the "add
+        # section" link.
+        add_user = User.objects.get(username='adduser')
+        perm = get_perm(Section, Section._meta.get_add_permission())
+        add_user.user_permissions.add(perm)
+        response = self.client.get(url)
+        self.assertContains(response, add_link_text)
+
     def testCustomModelAdminTemplates(self):
         self.client.get('/test_admin/admin/')
         self.client.post('/test_admin/admin/', self.super_login)
