Bob's Blog

Web开发、测试框架、自动化平台、APP开发、机器学习等

返回上页首页

Django中访问权限的控制



在使用django时,常常有需求关于限定特定的人的查看和操作行为等,比如未登录无法查看内容,比如只有赋予权限的人才能新增记录。对此这样的需求,有几种处理方式。

(如果是用到了django restframework,则可以参考另一篇文章:Django restframework加Vue打造前后端分离的网站(八)权限控制)

django的每一个model对象都有四种操作类型,在admin也能看到:view, add, change, delete,分别对应查看、添加、修改、删除。对于superuser则是默认拥有所有权限,对于普通用户可以单独赋予某种对象的某种操作的权限,也可以创建一个群组group定义好权限列表,并将该用户添加到该群组。

但我们需要指定哪种类型的用户或者哪种类型的权限能做什么事。

该文章分成两个部分:按django权限类型管理按自定义逻辑判断。

1. 按django权限类型管理

django提供了可供使用的装饰器:login_required,permission_required。此外还有PermissionRequiredMixin可以用。

login_required是指要求必须登录;在参数中如果指定了login_url则会在未登录时跳转该地址。

比如下面的例子,在views.py中定义,如果此时未登录,则无法查看该页面了。

from django.contrib.auth.decorators import login_required

@login_required
def about_site(request):
    return render(request, 'blog/about_site.html')

permission_required是指要求拥有某个权限,且可以有多重的permission_required装饰器。在参数中如果指定了login_url则会在未登录时跳转该地址。在参数中如果指定了raise_exception为True时则会抛出403的错误。

需要指定权限类型,格式是app_label和model name,app_label就是在settings里写的app,model name就是自己定义的model加上操作类型。

比如下面的例子,是需要有blog这个app的add_post权限,才被允许使用对应的views函数,才能看到post的详细内容。既然是装饰器,那么多重权限检查也是支持的。

from django.contrib.auth.decorators import permission_required

@permission_required('blog.add_post', raise_exception=True)
# @permission_required('blog.view_post', raise_exception=True)
def post_detail(request, post_id):
    post = get_object_or_404(Post, pk=post_id)
    return render(request, 'blog/post_detail.html', {'post': post})

如果views里定义的是一个class,那么还可以继承PermissionRequiredMixin来控制,需要指定单个或者多个的permission_required,和上面的装饰器的作用一样。比如官方的这个例子:

from django.contrib.auth.mixins import PermissionRequiredMixin

class MyView(PermissionRequiredMixin, View):
    permission_required = 'polls.add_choice'
    # Or multiple of permissions:
    permission_required = ('polls.view_choice', 'polls.change_choice')

2. 按自定义逻辑判断

自定义逻辑就是根据根据django内置方法来设置条件,根据条件来决定是否展示或者提供操作。当然这个不如方法1那么合理,但也能产生类似的效果。只是需要注意的是,这里即使无法访问,一般仍会根据条件来走并返回200而不是403,并不规范。但这种方式也不是完全没用途,像遇到自定义字段的区别来展示不同内容时,遇到不同设备来展示不同内容时,这是非常方便的。

自定义的逻辑可以在views中,也可以在template中。

按上述的例子,我们再来做一遍。

判断是否登录,就可以用user.is_authenticated。

在views中可以是这样:

def about_site(request):
    if request.user.is_authenticated:
        return render(request, 'blog/about_site.html')
    else:
        return render(request, 'error/unauthenticated.html')

在template中可以是这样:

{% if user.is_authenticated %}
<h3>this is topic</h3>
{% else %}
<h3>Please login first to view this page</h3>
{% endif %}

判断是否有操作权限,可以用has_perm。

在views中可以是这样:

def post_detail(request, post_id):
    if request.user.has_perm('blog.add_post'):
        post = get_object_or_404(Post, pk=post_id)
        return render(request, 'blog/post_detail.html', {'post': post})
    else:
        return render(request, 'error/unauthenticated.html')

用户所拥有的权限被存储在{{ perms }},views中的request.user.has_perm('blog.add_post') 就等同于 template中的 {% if perms.blog.add_post %}。

于是在template中可以是这样:

{% if perms.blog.view_post %}
<h3>this is topic</h3>
{% else %}
<h3>Please login first to view this page</h3>
{% endif %}

到此就介绍完了django中怎么根据权限来控制展示和行为了。

下一篇:  scrcpy在Mac上的使用
上一篇:  mongodb的备份和恢复

共有0条评论

添加评论

暂无评论