我的Django项目中的权限机制

本文主要介绍我在Django博客使用的权限设置,我的博客中几乎所有的权限设置都是我自己写的。这么做的原因是我在写Flask博客的时候,学到了一些这方面的知识,感觉很不错。因此就借鉴里面的逻辑,自己写了这方面的代码。

1、关于文章的访问权限

我就从Model和View两层来说。

首先我在Model中定义一个字段,用来指示是否公开,是否允许别人可见: 源代码如下:

1234567891011 ACCESS = {    100:u\’公开\’,    200:u\’私人可见\’}class Article(models.Model):     title = models.CharField(max_length=150,unique=True,verbose_name=u\’标题\’)    alias = models.CharField(max_length=150,verbose_name=u\’英文标题\’)    ..........    ..........    access = models.IntegerField(default=100,choices=ACCESS.items(),verbose_name=u\’文章权限,公开或者私人可见\’)

access字段指定该字段是否公开。如果设为公开那么所有人可以访问;如果设为私密,那么就不允许一些用户访问。那此时问题来了,该如何设置限制访问逻辑。我的代码如下,该方法也定义在Model中:

12345678 def can_access(self,user):    if self.access == 100:        return True    if self.access == 200:        if user is None:            return False        else:            return self.author.id == user.id or user.is_staff

上面的代码很简单,如果是私密的,只有文章作者或者管理员可以访问。

在View中的代码:

123456789101112131415161718 class ArticleDetailView(BaseMixin,DetailView):    queryset = Article.objects.filter(status=0)    slug_field = \’alias\’    context_object_name = \’article\’    template_name = \’article.html\’    object = None     def get(self, request, *args, **kwargs):        alias = self.kwargs.get(\’slug\’)        try:            self.object = self.queryset.get(alias=alias)        except Article.DoesNotExist:            logger.error(\’article does not exsists\’)            #I should rewrite the 404 html later            return HttpResponseNotFound(\’Page not Found\’)        # add permission,if the article has set permission,the web will raise one exveption        if not self.object.can_access(request.user):            raise PermissionDenied

看这段代码最后面,如果can_acees方法返回False,就抛出一个禁止Django内置的禁止访问的异常,即返回403页面。

2、自定义视图权限装饰器

首先自己定义一个装饰器函数,用来修饰要设置权限的视图函数或类方法。 装饰器函数源代码:

12345678910111213141516171819202122232425262728293031323334 from functools import wrapsfrom django.http import HttpResponse,HttpResponseRedirectmport wrapsfrom django.http import HttpResponse,HttpResponseRedirect觉很不错。因此就借鉴里面的逻辑,自己写了这方面的代码。

1、关于文章的访问权限

我就从Model和View两层来说。

首先我在Model中定义一个字段,用来指示是否公开,是否允许别人可见: 源代码如下:

1234567891011 ACCESS = {    100:u\’公开\’,    200:u\’私人可见\’}class Article(models.Model):     title = models.CharField(max_length=150,unique=True,verbose_name=u\’标题\’)    alias = models.CharField(max_length=150,verbose_name=u\’英文标题\’)    ..........    ..........    access = models.IntegerField(default=100,choices=ACCESS.items(),verbose_name=u\’文章权限,公开或者私人可见\’)

access字段指定该字段是否公开。如果设为公开那么所有人可以访问;如果设为私密,那么就不允许一些用户访问。那此时问题来了,该如何设置限制访问逻辑。我的代码如下,该方法也定义在Model中:

12345678 def can_access(self,user):    if self.access == 100:        return True    if self.access == 200:        if user is None:            return False        else:            return self.author.id == user.id or user.is_staff

上面的代码很简单,如果是私密的,只有文章作者或者管理员可以访问。

在View中的代码:

123456789101112131415161718 class ArticleDetailView(BaseMixin,DetailView):    queryset = Article.objects.filter(status=0)    slug_field = \’alias\’    context_object_name = \’article\’    template_name = \’article.html\’    object = None     def get(self, request, *args, **kwargs):        alias = self.kwargs.get(\’slug\’)        try:            self.object = self.queryset.get(alias=alias)        except Article.DoesNotExist:            logger.error(\’article does not exsists\’)            #I should rewrite the 404 html later            return HttpResponseNotFound(\’Page not Found\’)        # add permission,if the article has set permission,the web will raise one exveption        if not self.object.can_access(request.user):            raise PermissionDenied

看这段代码最后面,如果can_acees方法返回False,就抛出一个禁止Django内置的禁止访问的异常,即返回403页面。

2、自定义视图权限装饰器

首先自己定义一个装饰器函数,用来修饰要设置权限的视图函数或类方法。 装饰器函数源代码:

12345678910111213141516171819202122232425262728293031323334 from functools import wrapsfrom django.http import HttpResponse,HttpResponseRedirectno\” data-settings=\”dblclick\” readonly style=\”-moz-tab-size:4; -o-tab-size:4; -webkit-tab-size:4; tab-size:4; font-size: 13px !important; line-height: 15px !important;\”>
def can_access(self,user):
if self.access == 100:
return True
if self.access == 200:
if user is None:
return False
else:
return self.author.id == user.id or user.is_staff