目前,咱們的API對誰能夠編輯或刪除代碼段沒有任何限制。咱們想要一些更先進的行爲,以確保:(這段話抄自官網)python
使用官方例子在表中添加用戶字段,該字段用來判斷是否與登陸用戶有關係。django
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 類時它不會被默認包含,須要添加一個顯示的字段。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()),
關聯用戶經過重寫SnippetList 視圖類的 perform_create(),該方法修改實例保存的管理方式,並處理傳入請求或request中的任何信息。app
在SnippetList
視圖類上,添加如下方法:(我的理解:使保存的數據用戶字段爲登陸用戶的信息)框架
def perform_create(self, serializer): serializer.save(owner=self.request.user)
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)來指定字段類型而且設置爲只讀字段。函數
既然Snippet和user相關聯,咱們但願只有通過身份驗證的用戶才能建立,更新和刪除代碼片斷。
url
REST框架包含許多權限類,咱們可使用這些權限類來限制能夠訪問給定視圖的人員。在這種狀況下,咱們正在尋找的是IsAuthenticatedOrReadOnly
確保通過身份驗證的請求得到讀寫訪問權限,未經身份驗證的請求得到只讀訪問權限。spa
首先在視圖模塊中添加如下導入:
from rest_framework import permissions
接着,下面的屬性添加到都在SnippetList
和SnippetDetail
視圖類。
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
在適當的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,)