Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: don't break when user overrides ModelAdmin.has_change_permission #27

Merged
merged 1 commit into from
Jul 3, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 24 additions & 18 deletions admin_view_permission/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,8 @@ def __init__(self, *args, **kwargs):
# If user has only view permission change the title of the changelist
# view
if self.model_admin.has_view_permission(self.request) and \
not self.model_admin.has_change_permission(self.request,
only_change=True):
not self.model_admin.has_change_permission_only_change(
self.request):
if self.is_popup:
title = _('Select %s')
else:
Expand Down Expand Up @@ -79,7 +79,7 @@ def has_view_permission(self, request, obj=None):
codename = get_permission_codename('view', opts)
return request.user.has_perm("%s.%s" % (opts.app_label, codename))

def has_change_permission(self, request, obj=None, only_change=False):
def has_change_permission(self, request, obj=None):
"""
Override this method in order to return True whenever a user has view
permission and avoid re-implementing the change_view and
Expand All @@ -88,13 +88,15 @@ def has_change_permission(self, request, obj=None, only_change=False):
"""
change_permission = super(AdminViewPermissionBaseModelAdmin,
self).has_change_permission(request, obj)
if only_change:
return change_permission
if change_permission or self.has_view_permission(request, obj):
return True
else:
if change_permission or self.has_view_permission(request, obj):
return True
else:
return change_permission
return change_permission

def has_change_permission_only_change(self, request, obj=None):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add some tests for this function? Also, could you make this function private as it is used internally only? I think has_change_permission_only it would be better name. The _change I think it is redundant.

change_permission = super(AdminViewPermissionBaseModelAdmin,
self).has_change_permission(request, obj)
return change_permission

def get_excluded_fields(self):
"""
Expand All @@ -121,7 +123,8 @@ def get_fields(self, request, obj=None):
which are in fields attr
"""
if ((self.has_view_permission(request, obj) and (
obj and not self.has_change_permission(request, obj, True))) or (
obj and
not self.has_change_permission_only_change(request, obj))) or (
obj is None and not self.has_add_permission(request))):
fields = super(
AdminViewPermissionBaseModelAdmin,
Expand All @@ -147,7 +150,8 @@ def get_readonly_fields(self, request, obj=None):
self).get_readonly_fields(request, obj)

if ((self.has_view_permission(request, obj) and (
obj and not self.has_change_permission(request, obj, True))) or (
obj and
not self.has_change_permission_only_change(request, obj))) or (
obj is None and not self.has_add_permission(request))):
readonly_fields = (
list(readonly_fields) +
Expand Down Expand Up @@ -186,7 +190,7 @@ def get_actions(self, request):
request)

if self.has_view_permission(request) and \
not self.has_change_permission(request, only_change=True):
not self.has_change_permission_only_change(request):
# If the user doesn't have delete permission return an empty
# OrderDict otherwise return only the default admin_site actions
if not self.has_delete_permission(request):
Expand All @@ -209,7 +213,7 @@ def get_queryset(self, request):
admin site. This is used by changelist_view.
"""
if self.has_view_permission(request) and \
not self.has_change_permission(request, None, True):
not self.has_change_permission_only_change(request, None):
return super(AdminViewPermissionInlineModelAdmin, self)\
.get_queryset(request)
else:
Expand Down Expand Up @@ -240,11 +244,13 @@ def get_inline_instances(self, request, obj=None):
if request:
if not (inline.has_view_permission(request, obj) or
inline.has_add_permission(request) or
inline.has_change_permission(request, obj, True) or
inline.has_change_permission_only_change(
request, obj) or
inline.has_delete_permission(request, obj)):
continue
if inline.has_view_permission(request, obj) and \
not inline.has_change_permission(request, obj, True):
not inline.has_change_permission_only_change(
request, obj):
inline.can_delete = False
if not inline.has_add_permission(request):
inline.max_num = 0
Expand All @@ -268,7 +274,7 @@ def change_view(self, request, object_id, form_url='', extra_context=None):
obj = self.get_object(request, unquote(object_id), to_field)

if self.has_view_permission(request, obj) and \
not self.has_change_permission(request, obj, True):
not self.has_change_permission_only_change(request, obj):
extra_context = extra_context or {}
extra_context['title'] = _('View %s') % force_text(
opts.verbose_name)
Expand All @@ -280,7 +286,7 @@ def change_view(self, request, object_id, form_url='', extra_context=None):

inlines = self.get_inline_instances(request, obj)
for inline in inlines:
if (inline.has_change_permission(request, obj, True) or
if (inline.has_change_permission_only_change(request, obj) or
inline.has_add_permission(request)):
extra_context['show_save'] = True
extra_context['show_save_and_continue'] = True
Expand All @@ -293,7 +299,7 @@ def changelist_view(self, request, extra_context=None):
resp = super(AdminViewPermissionModelAdmin, self).changelist_view(
request, extra_context)
if self.has_view_permission(request) and \
not self.has_change_permission(request, only_change=True):
not self.has_change_permission_only_change(request):
resp.context_data['cl'].formset = None

return resp
Expand Down
4 changes: 2 additions & 2 deletions tests/tests/unit/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -831,8 +831,8 @@ def test_has_change_permission(self, name, request_user, obj_func,
request.user = getattr(self, request_user.user)
has_change_permission_default = modeladmin.has_change_permission(
request, obj=obj)
has_change_permission_only = modeladmin.has_change_permission(
request, obj=obj, only_change=True)
has_change_permission_only = \
modeladmin.has_change_permission_only_change(request, obj=obj)

assert (has_change_permission_default ==
result['has_change_permission']['default'])
Expand Down