Django Rest Framework学习进程(四) API权限

第四部分的学习主要是关于API的权限的,目前,我们的API对谁可以编辑或删除代码段没有任何限制。我们希望有更高级的行为,以确保:

(1) 代码片段始终与创建者相关联。

(2) 只有通过身份验证的用户可以创建片段。

(3) 只有代码片段的创建者可以更新或删除它。

(4) 未经身份验证的请求应具有完全只读访问权限。

  1.往我们的模型中加入一些信息

//编辑snippets/models.py文件,加入以下两个字段
#其中,owner用来存储创建snippet的用户,另一个则用来存储高亮的HTML内容
owner = models.ForeignKey('auth.User', related_name='snippets', on_delete=models.CASCADE)
highlighted = models.TextField()

//我们还需要用到pygments,使用它来填充要高亮显示的字段
//首先导入以下依赖包
from pygments.lexers import get_lexer_by_name
from pygments.formatters.html import HtmlFormatter
from pygments import highlight

//然后加入一个save函数
def save(self, *args, **kwargs):
    """
    使用`pygments`库创建一个高亮显示的HTML表示代码段。
    """
    lexer = get_lexer_by_name(self.language)
    linenos = self.linenos and 'table' or False
    options = self.title and {'title': self.title} or {}
    formatter = HtmlFormatter(style=self.style, linenos=linenos,
                              full=True, **options)
    self.highlighted = highlight(self.code, lexer, formatter)
    super(Snippet, self).save(*args, **kwargs)
    
//清空之前的数据库,重新进行数据库迁移操作
python manage.py makemigrations snippets
python manage.py migrate


//创建几个用户
python manage.py createsuperuser

  2.给用户模型增加路径

在snippets/serializers.py中,创建一个新的序列化器
//首先导入依赖包
from django.contrib.auth.models import User

//创建一个序列化器UserSerializer
class UserSerializer(serializers.ModelSerializer):
    snippets = serializers.PrimaryKeyRelatedField(many=True, queryset=Snippet.objects.all())
    
    //你可能会疑惑为啥snippets为作为字段传进去,
  //因为'snippets' 在用户模型中是一个反向关联关系。在使用 ModelSerializer 类时它默认不会被包含,所以我们需要为它添加一个显式字段 class Meta: model = User fields = ('id', 'username', 'snippets')

  3.编写views.py

//在views.py中,我们希望仅对用户使用只读视图,所以我们使用ListAPIView和RetrieveAPIView这两个通用的基类视图
//首先导入以下依赖包
from snippets.serializers import UserSerializer
from django.contrib.auth.models import User

class UserList(generics.ListAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer


class UserDetail(generics.RetrieveAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer

  4.URL的编写

//将以下路径加入到snippets/urls.py当中
url(r'^users/$', views.UserList.as_view()),
url(r'^users/(?P<pk>[0-9]+)/$', views.UserDetail.as_view()),

  5.将Snippet和用户关联

//在views.py中,将以下函数,添加到SnippetList当中
//目的是使序列化器的create()方法现在将被传递一个附加的'owner'字段以及来自请求的验证数据。
def perform_create(self, serializer):
    serializer.save(owner=self.request.user)

//在serializers.py的SnippetSerializer中,添加这个字段
//ReadOnlyField类表示始终只是可读的,只能用于序列化展示,不能用于在反序列化中更新模型实例
owner = serializers.ReadOnlyField(source='owner.username')

//别忘了还要把owner添加到Meta类中的fields中

  6.添加视图所需要的权限

//我们要确保经过身份验证的请求才能获得读写访问权限,未经身份验证的请求将获得只读访问权限
//在views.py中,导入permissions
from rest_framework import permissions

//在SnippetList和SnippetDetail当中,添加这行代码:
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

//编辑tutorial.py,添加urlpatterns
urlpatterns += [
    url(r'^api-auth/', include('rest_framework.urls',
                               namespace='rest_framework')),
]

  7.创建对象级别的权限

//在snippets下,创建一个permissions.py文件,并写入以下内容
from rest_framework import permissions
class IsOwnerOrReadOnly(permissions.BasePermission):
    """
    自定义权限只允许对象的所有者编辑它。
    """

    def has_object_permission(self, request, view, obj):
        # 读取权限允许任何请求,
        # 所以我们总是允许GET,HEAD或OPTIONS请求。
        if request.method in permissions.SAFE_METHODS:
            return True

        # 只有该snippet的所有者才允许写权限。
        return obj.owner == request.user

//接下来,编辑views.py,导入IsOwnerOrReadOnly
from snippets.permissions import IsOwnerOrReadOnly
在SnippetDetail的permission_classes中,加上IsOwnerOrReadOnly
permission_classes = (permissions.IsAuthenticatedOrReadOnly,
                      IsOwnerOrReadOnly,)

  8.完结撒花

//接下来,你运行项目可能会报'CSRFCheck' object has no attribute 'process_request' 这个错误在settings.py中,加入以下代码即可,如没报错即可忽略。
REST_FRAMEWORK = {
    "DEFAULT_AUTHENTICATION_CLASSES": []
}

 

    

    

    

posted on 2019-03-24 17:56  蓝同学  阅读(137)  评论(0编辑  收藏  举报

导航