django rest-framework 4.REST的认证和权限

目前,我们的API对谁可以编辑或删除代码段没有任何限制。我们想要一些更先进的行为,以确保:(这段话抄自官网)

  • 代码段始终与创建者相关联。
  • 只有身份验证的用户可以创建片段。
  • 只有片段的创建者可以更新或删除它。
  • 未经身份验证的请求应具有完全只读访问权限。

一、将信息添加至 model

使用官方例子在表中添加用户字段,该字段用来判断是否与登录用户有关系。

owner = models.ForeignKey('auth.User', related_name='snippets', on_delete=models.CASCADE)
highlighted = models.TextField()

这里的owner用户关联的为django admin的认证用户,该字段用与匹配登录用户是否有权限修改该数据(后面涉及到)。

二、为用户模型添加端点

为 auth.User 表添加到api中,首先需要添加序列化。由于snippets(这里的smippets为外键的related_name,默认为"表名_set")在用户模型上是反向关系,所以在使用ModelSerializer 类时它不会被默认包含,需要添加一个显示的字段。

# 用户序列化函数  serializers.py
from django.contrib.auth.models import User

class UserSerializer(serializers.ModelSerializer):
    snippets = serializers.PrimaryKeyRelatedField(many=True, queryset=Snippet.objects.all())

    class Meta:
        model = User
        fields = ('id', 'username', 'snippets')

# 用户视图函数  views.py
from django.contrib.auth.models import User
from snippets.serializers import UserSerializer

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


class UserDetail(generics.RetrieveAPIView):
    queryset = User.objects.all()
    serializer_class = UserSerializer
#  配置URL conf
url(r'^users/$', views.UserList.as_view()),
url(r'^users/(?P<pk>[0-9]+)/$', views.UserDetail.as_view()),
用户模型添加api

三、snippets 和 user 关联

关联用户通过重写SnippetList 视图类的 perform_create(),该方法修改实例保存的管理方式,并处理传入请求或request中的任何信息。

  SnippetList视图类上,添加以下方法:(个人理解:使保存的数据用户字段为登录用户的信息)

def perform_create(self, serializer):
    serializer.save(owner=self.request.user)

四、更新serializer

snippets 和 user关联后,在snippets中owner的信息默认为id信息,更新序列化类(serializer)是owner显示为用户名信息。

# 更新 SmippetSerializer 添加如下:
owner = serializers.ReadOnlyField(source='owner.username')

# 并确保 fields 中有owner字段。

  我们添加的是无类型的 ReadOnlyField 类,与其他类型的字段(CharField,BooleanField等)相比ReadOnlyField 总是只读的。如果设置为ReadOnlyField 该字段则不用用于更新(但是参数还是会传递到后端。),我们也可以使用CharField(read_only=Ture)来指定字段类型并且设置为只读字段。

五、为视图添加权限

  既然Snippet和user相关联,我们希望只有经过身份验证的用户才能创建,更新和删除代码片段。

  REST框架包含许多权限类,我们可以使用这些权限类来限制可以访问给定视图的人员。在这种情况下,我们正在寻找的是IsAuthenticatedOrReadOnly确保经过身份验证的请求获得读写访问权限,未经身份验证的请求获得只读访问权限。

  首先在视图模块中添加以下导入:

from rest_framework import permissions

接着,下面的属性添加到SnippetListSnippetDetail视图类。

permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

六、添加登录API

在适当的urls.py文件中天剑URLconf在添加可浏览API的登录视图。

from django.conf.urls import include

# 按需添加如下urlconf,r'^api-auth/'模式的部分实际上可以是您想要使用的任何URL。
urlpatterns += [
    url(r'^api-auth/', include('rest_framework.urls')),
]

七、对象级权限

  我们希望所有人都可以看到所有代码片段,但也要确保只有创建代码段的用户才能更新或删除它。为此,我们需要创建一个自定义权限。

在app中创建一个新文件,permissions.py

from rest_framework import permissions


class IsOwnerOrReadOnly(permissions.BasePermission):
    """
    Custom permission to only allow owners of an object to edit it.
    """

    def has_object_permission(self, request, view, obj):
        # Read permissions are allowed to any request,
        # so we'll always allow GET, HEAD or OPTIONS requests.
        # 当用户请求的为查询操作使,对用户没有限制
        if request.method in permissions.SAFE_METHODS:
            return True

        # Write permissions are only allowed to the owner of the snippet.
        # 否则判断用户是否与操作数据的用户相同,返回Ture or False
        return obj.owner == request.user    

  添加完之后在SnippetDetail类视图中添加 permission_classes属性来将该自定义权限加到代码中:

  记得导入 IsOwnerOrReadOnly  (from snippets.permissions import IsOwnerOrReadOnly

 

permission_classes = (permissions.IsAuthenticatedOrReadOnly,IsOwnerOrReadOnly,)

 

posted @ 2017-09-27 22:08  40块钱抓娃娃  阅读(287)  评论(0编辑  收藏  举报