django admin缺少默认的view权限控制,于是又只能自力更生。为此必须得修改django代码,这里的改动基于django 1.3.5.

具体步骤

  • 修改django.contrib.auth.management.create_permissions, _get_all_permissions
 def _get_all_permissions(opts):
     "Returns (codename, name) for all permissions in the given opts."
     perms = []
     for action in ('add', 'change', 'delete', 'view'):
         perms.append((_get_permission_codename(action, opts), u'Can %s %s' % (action, opts.verbose_name_raw)))
     return perms + list(opts.permissions)
  • 修改django.db.models.options.Options, 增加get_view_permission
 def get_view_permission(self):
     return 'view_%s' % self.object_name.lower()
  • 修改django.contrib.admin.options.ModelAdmin,增加has_view_permission,修改get_model_perms
 def has_view_permission(self, request):
     """
     Returns True if the given request has permission to add an object.
     Can be overriden by the user in subclasses.
     """
     opts = self.opts
     return request.user.has_perm(opts.app_label + '.' + opts.get_view_permission())

 def get_model_perms(self, request):
     """
     Returns a dict of all perms for this model. This dict has the keys
     ``add``, ``change``, and ``delete`` mapping to the True/False for each
     of those actions.
     """
     return {
         'add': self.has_add_permission(request),
         'change': self.has_change_permission(request),
         'delete': self.has_delete_permission(request),
         'view': self.has_view_permission(request),
     }
  • 修改django.contrib.admin.templates.admin.index.html
 {% if model.perms.change %}
     <th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
 {% else %}
     {% if model.perms.view %}
         <th scope="row"><a href="{{ model.admin_url }}">{{ model.name }}</a></th>
     {% else %}
         <th scope="row">{{ model.name }}</th>
     {% endif %}
 {% endif %}
  • 修改django.contrib.admin.options.ModelAdmin,修改change_view、change list_view
 // change_view
 if request.method == 'GET' and not self.has_change_permission(request, obj) and not self.has_view_permission(request):
     raise PermissionDenied

 if request.method == 'POST' and not self.has_change_permission(request, obj):
     raise PermissionDenied

 // changelist_view
 if request.method == 'GET' and not self.has_change_permission(request, None) and not self.has_view_permission(request):
     raise PermissionDenied

 if request.method == 'POST' and not self.has_change_permission(request, None):
     raise PermissionDenied
  • 修改django.contrib.admin.templatetags.admin_modify,修改submit_row
 'show_save': context['has_change_permission’]