这就是我更改 Django 1.0.2 以添加“查看”权限的方式。抱歉,没有可用的差异。
[X] 1. 在默认权限列表中添加“查看”
#./contrib/auth/management/__init__.py
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)
[X] 2. 测试 'view' 权限被添加到所有模型
run manage.py syncdb
我确认现在为 auth_permissions 表中的所有表添加了查看权限
[X] 3. 将“get_view_permission”添加到默认模型类。
向模型类添加了 get_view_permission。您可以在文件 ./db/models/options.py 中找到它,这将在下一步中由管理类使用。
def get_view_permission(self):
return 'view_%s' % self.object_name.lower()
[X] 4. 将“has_view_permission”添加到默认管理类
为了保持一致,我将在系统中添加“has_view_permission”。看起来它应该在contrib/admin/options.py的某个地方。确保用户是否具有更改权限,然后自动隐含查看权限。
# /contrib/admin/options.py
# Added has_view_permissions
def has_view_permission(self, request, obj=None):
"""
Returns True if the given request has permission to change or view
the given Django model instance.
If `obj` is None, this should return True if the given request has
permission to change *any* object of the given type.
"""
opts = self.opts
return self.has_change_permission(request, obj) or \
request.user.has_perm(opts.app_label + '.' + opts.get_view_permission())
# modified get_model_perms to include 'view' too.
# No idea where this may be used, but trying to stay consistent
def get_model_perms(self, request):
"""
Returns a dict of all perms for this model. This dict has the keys
``add``, ``change``, and ``delete`` and ``view`` 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),
}
# modified response_add function to return the user to the mode list
# if they added a unit and have view rights
...
else:
self.message_user(request, msg)
# Figure out where to redirect. If the user has change permission,
# redirect to the change-list page for this object. Otherwise,
# redirect to the admin index.
#if self.has_change_permission(request, None):
if self.has_change_permission(request, None) or self.has_view_permission(request, None):
post_url = '../'
else:
post_url = '../../../'
return HttpResponseRedirect(post_url)
# modified the change_view function so it becomes the details
# for users with view permission
#if not self.has_change_permission(request, obj):
if not (self.has_change_permission(request, obj) or (self.has_view_permission(request, obj) and not request.POST)):
raise PermissionDenied
# modified the changelist_view function so it shows the list of items
# if you have view permissions
def changelist_view(self, request, extra_context=None):
"The 'change list' admin view for this model."
from django.contrib.admin.views.main import ChangeList, ERROR_FLAG
opts = self.model._meta
app_label = opts.app_label
#if not self.has_change_permission(request, None):
if not (self.has_change_permission(request, None) or self.has_view_permission(request, None)):
raise PermissionDenied
[X] 5. 如果用户有查看权限,则更新默认模板以列出模型
我修改了 contrib/admin/templates/admin/index.html 中的默认模板。这也可以通过将文件复制到本地模板目录来处理。我对两者都进行了更改,因此如果以后的升级覆盖了我的更改,我会有一份副本。
{% for model in app.models %}
<tr>
{% 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 %}
[X] 6. 确认用户可以“查看”但不能“更改”模型
发现 contrib/admin/templatetags/admin_modify.py 似乎可以控制是否出现保存/保存和继续按钮。将“保存”字段从默认的始终为真更改,以检查上下文和权限。如果他们有更改或添加权限,用户应该能够保存。
'show_save': (change and context['has_change_permission']) or (context['add'] and context['has_add_permission'])
[X] 7. 如果用户正在查看项目,请删除“保存并添加另一个”按钮
再次修改 contrib/admin/templatetags/admin_modify.py。我不知道“save_as”是什么意思,所以也许我弄坏了一些东西,但它似乎有效。
#'show_save_and_add_another': context['has_add_permission'] and
# not is_popup and (not save_as or context['add']) ,
'show_save_and_add_another': not is_popup and
(( change and context['has_change_permission']) or (context['add'] and context['has_add_permission']))
and
(not save_as or context['add']),
[X] 8.修改“查看”权限使表单只读
如果用户具有“查看”权限和“更改”权限,则什么也不做。更改覆盖视图。
如果用户在没有“更改”的情况下拥有“查看”权限,则更改默认表单并将 DISABLED 或 READONLY 属性添加到表单元素。并非所有浏览器都支持这一点,但出于我的目的,我可以要求用户使用正确的浏览器。 禁用/只读示例
发现并非所有浏览器都支持“只读”,因此它将一些控件设置为只读,将其他控件设置为禁用。这允许用户在需要时从文本控件复制数据。
#/django/contrib/admin/templates/admin/change_form.html
{# JavaScript for prepopulated fields #}
{% prepopulated_fields_js %}
</div>
</form></div>
{% if has_view_permission and not has_change_permission %}
<script type="text/javascript">
jQuery('input:text').attr('readonly', 'readonly');
jQuery('textarea').attr('readonly', 'readonly');
jQuery('input:checkbox').attr('disabled', true);
jQuery('select').attr('disabled', true);
jQuery('.add-another').hide();
</script>
{% endif %}