Django:从调用视图中解除权限检查

时间:2016-03-24 08:57:33

标签: django permissions

Django:从调用视图中解除权限检查

我想在django中解除权限检查。

当前缺点:如果您使用像login_required这样的装饰器,那么您无法事先知道用户是否有权这样做。

我想将其分为两个步骤:

  1. 检查权限
  2. 调用视图。
  3. 使用案例1:管理工具

    我想要一个管理员工具,他们可以检查用户的访问权限。这需要:

    1. 检查不能使用当前request.user,因为这是错误的用户对象。
    2. 检查实际上不能调用视图,因为这可能会改变数据。
    3. 使用案例2:将链接显示为已禁用。

      如果用户没有查看链接页面的权限,我想将链接显示为已禁用(灰显且没有“href”)。

      返回“ok”和“permission denied”的布尔值很好。但最大的好处是如果管理员可以获得理由

      示例:

      1. 管理员打开“检查烫发工具”
      2. 他选择了一个视图/网址
      3. 管理员点击“提交”
      4. 结果:

        ------------------------------
        | User     | Allowed | Reason
        ------------------------------
        | fooadmin |  Yes    | is_superuser
        | foouser  |  No     | missing permission "view-bar-at-midnight"
        | foobar   |  Yes    | User has permission "view-bar-at-midnight"
        

        问题

        如何实现这个梦想?

        ...仅仅是为了记录,我在django-develop列表上发布了这个想法:https://groups.google.com/forum/#!topic/django-developers/rpTh4G3BgIQ

1 个答案:

答案 0 :(得分:3)

我假设您已经拥有查看每个视图/网址所需的所有权限的列表?即您知道网址/bar需要提前superuserview-bar-at-night权限吗?

如果有,请先尝试将ViewPermissions模型添加到models.py

from django.db import models

class ViewPermissions(models.Model):
    view_url = models.CharField(help_text="The URL of this view")

然后在admin.py

from models import ViewPermissions
from django.contrib.admin.widgets import FilteredSelectMultiple
from django.contrib.auth.models import Permission
from django.contrib import admin
from django import forms

class ViewPermissionFormField(forms.ModelForm):
    permissions = forms.ModelMultipleChoiceField(
        widget=FilteredSelectMultiple("Permissions", is_stacked=False),
        queryset=models.Permission.objects.all()
    )

    def save(self, commit=True):
        extra_field = self.cleaned_data.get('extra_field', None)
    return super(ViewPermissionFormField, self).save(commit=commit)

    class Meta:
        fields = '__all__'
        model = ViewPermissions

class ViewPermissionsAdmin(admin.ModelAdmin):
    form = ViewPermissionsFormField
    fieldsets = (
        (None, {
            'fields': 'view_url', 'permissions'
        })
    )

现在,您可以在admin中为每个视图网址添加权限,以便跟踪事物。仅供参考,你可以create your own custom permissions将它们添加到Django现有的。

您可以创建一个管理表单来提取用户,列出他们的权限,然后利用ViewPermissions查看用户可以根据他们拥有的权限访问哪些URL(用例1)。

您现在可以在视图功能中查看用户的权限(如果您定义视图的方式,则可以查看类):

from django.contrib.auth.models import Permission
from models import ViewPermissions

def my_view(request)
    view_url = request.get_current_url()
    permissions_required = ViewPermissions.objects.filter(view_url = view_url).permissions
    context['user_permissions'] = []
    for p in permissions_required:
        if request.user.has_permission(p):
            context['user_permissions'].append(p)

现在,您可以将这些权限传递到模板中并相应地灰显链接(用例2)。

所以这样的事情可能有用......