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

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

  • 代码段始终与建立者相关联。
  • 只有身份验证的用户能够建立片断。
  • 只有片断的建立者能够更新或删除它。
  • 未经身份验证的请求应具备彻底只读访问权限。

1、将信息添加至 model

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

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

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

2、为用户模型添加端点

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

# 用户序列化函数  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

3、snippets 和 user 关联

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

  SnippetList视图类上,添加如下方法:(我的理解:使保存的数据用户字段为登陆用户的信息)框架

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

4、更新serializer

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

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

# 并确保 fields 中有owner字段。

  咱们添加的是无类型的 ReadOnlyField 类,与其余类型的字段(CharField,BooleanField等)相比ReadOnlyField 老是只读的。若是设置为ReadOnlyField 该字段则不用用于更新(可是参数仍是会传递到后端。),咱们也可使用CharField(read_only=Ture)来指定字段类型而且设置为只读字段。函数

5、为视图添加权限

  既然Snippet和user相关联,咱们但愿只有通过身份验证的用户才能建立,更新和删除代码片断。
url

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

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

from rest_framework import permissions

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

permission_classes = (permissions.IsAuthenticatedOrReadOnly,)

6、添加登陆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')),
]

7、对象级权限

  咱们但愿全部人均可以看到全部代码片断,但也要确保只有建立代码段的用户才能更新或删除它。为此,咱们须要建立一个自定义权限。

在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,)
相关文章
相关标签/搜索