Author: mtredinnick
Date: 2010-09-10 11:56:36 -0500 (Fri, 10 Sep 2010)
New Revision: 13708
Modified:
django/trunk/django/contrib/admin/options.py
django/trunk/django/contrib/admin/widgets.py
django/trunk/tests/regressiontests/admin_views/tests.py
Log:
Adding related objects in the admin (via popup) respects user
permissions. Patch from SmileyChris. Fixed #1035.
Modified: django/trunk/django/contrib/admin/options.py
===================================================================
--- django/trunk/django/contrib/admin/options.py 2010-09-10 13:17:38 UTC
(rev 13707)
+++ django/trunk/django/contrib/admin/options.py 2010-09-10 16:56:36 UTC
(rev 13708)
@@ -107,7 +107,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
Modified: django/trunk/django/contrib/admin/widgets.py
===================================================================
--- django/trunk/django/contrib/admin/widgets.py 2010-09-10 13:17:38 UTC
(rev 13707)
+++ django/trunk/django/contrib/admin/widgets.py 2010-09-10 16:56:36 UTC
(rev 13708)
@@ -205,13 +205,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
@@ -236,7 +241,7 @@
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);"> ' % \
Modified: django/trunk/tests/regressiontests/admin_views/tests.py
===================================================================
--- django/trunk/tests/regressiontests/admin_views/tests.py 2010-09-10
13:17:38 UTC (rev 13707)
+++ django/trunk/tests/regressiontests/admin_views/tests.py 2010-09-10
16:56:36 UTC (rev 13708)
@@ -604,6 +604,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)
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en.