Adding related objects in the admin (via popup) respects user
permissions. Patch from SmileyChris. Fixed #1035. git-svn-id: http://code.djangoproject.com/svn/django/trunk@13708 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
92b91d6e7b
commit
30610719d5
|
@ -107,7 +107,13 @@ class BaseModelAdmin(object):
|
|||
# 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
|
||||
|
||||
|
|
|
@ -205,13 +205,18 @@ class RelatedFieldWidgetWrapper(forms.Widget):
|
|||
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
|
||||
|
||||
|
@ -236,7 +241,7 @@ class RelatedFieldWidgetWrapper(forms.Widget):
|
|||
related_url = '%s%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);"> ' % \
|
||||
|
|
|
@ -604,6 +604,28 @@ class AdminViewPermissionsTest(TestCase):
|
|||
'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)
|
||||
|
|
Loading…
Reference in New Issue