Restframework從入門到精通(三):Restframework之許可權設定
第一步:增加顯示操作人
檢視API
的這個介面預設是要登陸的,因為我上面我使用了admin
賬號去登陸,所以i才可以顯示這個頁面
但是預設的是所有賬號登陸進去都可以對API
進行增刪改查,這個完全不符合邏輯。正常的邏輯是誰建立的才能誰去改,沒有身份驗證進去的只能讀取操作。
如圖,是我去資料庫把我的session
資訊刪掉之後再檢視API的結果
依照官網的檔案演示步驟,要先在model
建立一個外來鍵欄位
......
class Publish(models.Model):
name=models.CharField(max_length=20,verbose_name="出版社名稱",unique=True )
address=models.CharField(max_length=128,verbose_name="地址")
operator = models.ForeignKey('auth.User',on_delete=models.CASCADE)
......
複製程式碼
因為添加了一個欄位,所以要進行資料庫的遷移:makemigrations
-> migrate
這裡因為添加了一個欄位,而之前的欄位沒有這個欄位的預設值,所以會出現錯誤,要把預設值賦值為1即可
使用如上操作之後在資料庫就已經生成了新的operator
欄位了,所以接下來要對序列化的檔案也新增這個欄位
class Publishserializer(serializers.ModelSerializer):
class Meta:
model=Publish
fields=(
"id","name","address","operator"
)
......
複製程式碼
再登陸admin
賬號檢視API
得到的結果應該如下:
這個得到的operator
的結果都為1
是當然沒問題的,ID
為1
就是代表admin
賬號,但是我們要顯示的是這個ID
的使用者名稱
所以我們要在序列化檔案裡面新增一個欄位
class Publishserializer(serializers.ModelSerializer):
operator=serializers.ReadOnlyField(source="operator.username")
class Meta:
model=Publish
fields=(
"id","operator"
)
複製程式碼
第二步:許可權設定
關於許可權設定在官網都有詳細的說明
依照檔案的說法,我們要在檢視檔案裡面新增一個欄位,使得未登入的使用者只具有讀取許可權,登入的使用者才具有讀寫許可權:
from rest_framework import permissions
....
class Publish_list(generics.ListCreateAPIView):
queryset = Publish.objects.all()
serializer_class = Publishserializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
class PublisherDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Publish.objects.all()
serializer_class = Publishserializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,)
複製程式碼
去演示一下,會發現未登入使用者只有讀取許可權,登陸的使用者才有寫許可權
這個permissions
欄位有好幾種,在檔案的API的許可權設定詳細檔案裡面有說明
在這裡因為我要設定的是誰錄入的API
誰才具有讀寫許可權,所以這裡我要用的是物件級別許可權
如圖所示:
依照檔案的說法,我們要新建一個permissions.py
檔案
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
# 只有該出版社的所有者才允許去讀寫
return obj.operator == request.user
複製程式碼
然後再去檢視函式裡面繼承permissions
的這個類
之後我們再去建立一個管理員賬號admin2
看看能不能修改admin
的API
哦吼,大功告成
第三步:新建儲存operator值的方法
還有最後的一個問題,假如我們新建一個使用者,就拿剛剛建立的admin2
來說,我建立一個新的API
資料,但是我的operator
的ID
是沒有的。
我之前建立的admin
賬號是我模型遷移之前設定了預設的值1
,但是我新建立的admin2
沒有operator
的值,所以我們還要建立一個類方法去編寫
我通俗的將不太好懂,這個原理如下:
使用post
去建立一個新的API
的時候是通過序列化去新增的,而我的序列化程式碼如下
序列化沒有自己的save
方法,預設儲存方法是在ModelSerializer
裡面的,也就是在Model
裡面儲存,但是我新建的使用者admin2
新增一個欄位,他的operator_id
都不知道去哪裡找,如果使用admin2
去新增API
資料的話,會出現如下情況:
對於這種情況,檔案的說明如下:
即是讓我們在檢視檔案建立一個.perform_create
方法
views.py
class Publish_list(generics.ListCreateAPIView):
queryset = Publish.objects.all()
serializer_class = Publishserializer
permission_classes = (permissions.IsAuthenticatedOrReadOnly,IsOwnerOrReadOnly)
def perform_create(self,serializer):
serializer.save(operator=self.request.user)
複製程式碼
好了現在再去試一下使用admin2去post請求
完美,搞定
留坑
專案開發可能更多用到的是token驗證,所以這裡留個坑,到時候我做個專案案例回來填