【问题标题】:Why does Django not have a view permission?为什么Django没有查看权限?
【发布时间】:2016-01-17 07:42:38
【问题描述】:

我有一个活跃的 Django 项目,其中管理面板供客户支持团队使用。 Django 缺少view 权限,因此我必须将更改权限分配给客户支持团队,这有点危险。我有一些模型,由于安全问题,客户支持团队只需要查看访问权限而不需要更改访问权限。为什么 Django 中缺少 view 权限?有什么解决方法吗?

【问题讨论】:

  • 您的意思是要将管理员中的信息设为只读吗?
  • @marksweb :是的,但仅适用于特定的用户组。我不会让它在所有组中全局只读。
  • 没有人回答为什么缺少view 权限的问题。
  • 我怀疑您使用了自定义管理器,并且首先过滤掉了不可见的对象,因此无需检查查看权限。但我不确定这是否适用于所有情况,例如相关模型。

标签: python django django-models django-admin django-views


【解决方案1】:

这里有一个解决方法。

模型

通过从 mixin 继承来简单地创建具有查看权限的模型:

class ViewPermissionsMixin(models.Model):
    """
        Mixin adds view permission to model.
    """
    class Meta:
        abstract=True
        default_permissions = ('add', 'change', 'delete', 'view')

示例模型:

class ExampleModel(ViewPermissionsMixin):
    name = models.CharField(max_length=255)

    class Meta(ViewPermissionsMixin.Meta):
        abstract = False

这将添加可以分配给特定用户/组的查看权限。但是如果没有适当的管理员修改,这样的权限是没有用的。

管理员

这是为您的管理员准备的 mixin:

class AdminViewMixin(admin.ModelAdmin):

    def has_perm(self,user,permission):
        """
            Usefull shortcut for `user.has_perm()`
        """
        if user.has_perm("%s.%s_%s" % (self.model._meta.app_label,permission,self.model.__name__.lower(),)):
            return True
        return False

    def has_module_permission(self, request): # Django 1.8
        pass

    def has_change_permission(self, request, obj=None):
        """
            Necessary permission check to let Django show change_form for `view` permissions
        """
        if request.user.is_superuser:
            return True
        elif self.has_perm(request.user,'change'):
            return True
        elif self.has_perm(request.user,'view'):
            return True
        return super(AdminMixin, self).has_change_permission(request, obj)

    def get_readonly_fields(self, request, obj=None):
        """
            Turn each model field into read-only for `viewers`
        """
        all_model_fields = []
        for field in self.model._meta.fields:
            # TODO in Django 1.8 use ModelAdmin.get_fields()
            if not field.auto_created \
                and (not hasattr(field,'auto_now_add') or not field.auto_now_add) \
                and (not hasattr(field,'auto_now') or not field.auto_now) \
                :
                all_model_fields.append(field.name)
        if request.user.is_superuser:
            return self.readonly_fields
        elif self.has_perm(request.user,'change'):
            return self.readonly_fields
        elif self.has_perm(request.user,'view'):
            return all_model_fields
        return self.readonly_fields

    def change_view(self, request, object_id, extra_context=None):
        """
            Disable buttons for `viewers` in `change_view`
        """
        if request.user.is_superuser:
            pass
        elif self.has_perm(request.user,'change'):
            pass
        elif self.has_perm(request.user,'view'):
            extra_context = extra_context or {}
            extra_context['hide_save_buttons'] = True
        return super(AdminViewMixin, self).change_view(request, object_id, extra_context=extra_context)

示例管理员:

@admin.register(models.ExampleModel)
class ExampleAdmin(AdminViewMixin):
    list_display = ('name',)
    pass

最后只需将特定模型的 view 权限分配给 Django Admin 中的任何用户或组。

【讨论】:

【解决方案2】:

我认为这应该可行:

1.添加“查看”权限,见https://stackoverflow.com/a/23411901/1266258

2.自定义“更改”权限:

class FooAdmin(ModelAdmin):
    def has_change_permission(self, request, obj=None):
        # user can view the change list
        if not obj and request.user.has_perm('myapp.view_foo'):
            return True
        # user can view the change form and change the obj
        return request.user.has_perm('myapp.change_foo')

【讨论】:

  • 我希望在不同组之间分配不同的权限,就像我对问题的评论一样。
  • user.has_perm() 将检查用户权限和组权限。
猜你喜欢
  • 1970-01-01
  • 2022-06-17
  • 2020-04-29
  • 2011-02-20
  • 1970-01-01
  • 2014-05-31
  • 1970-01-01
  • 1970-01-01
  • 2013-05-15
相关资源
最近更新 更多