django-rest-framework(更新中)
阿新 • • 發佈:2022-12-01
@
目錄(三十六)Web應用模式
在Web開發中,有兩種模式:
- 前後端分離
#前後端分離: 只專注於後端,返回json格式資料
- 前後端不分離
# 前後端混合開發(前後端不分離) 返回的是HTML的內容,需要寫模板
# 動態頁面(查資料庫),靜態頁面(一個靜止的html)
# 頁面靜態化
(三十七)API介面
通過網路,規定了前後端資訊互動的url連線,也就是前後端資訊互動的媒介
(三十八)Restful規範
REST全稱是Representational State Transfer,中文意思是表述(編者注:通常譯為表徵性狀態轉移)。它首次出現在2000年Roy Fielding的博士論文中 RESTFUL是一種定義Web API介面的設計風格,尤其適合前後端分離的應用模式中。 這種風格的理念認為後端開發任務就是提供資料的,對外提供的是資料資源訪問的介面,所以在定義介面時,客戶端訪問的URL路徑就表示這種需要操作的資料資源 事實上,我們可以使用任何一種框架都可以實現符合RESTFUL規範的API介面
- 資料的安全保障
url連結一般都採用https協議進行傳輸,注:採用Https協議,可以提高資料 互動過程中的安全性
- 介面的特徵表現
-用api關鍵字標識介面url:
-[https://api.baidu.com](https://api.baidu.com/)
-https://www.baidu.com/api
注:看到api欄位,就代表該請求url連結是完成前後端資料互動的
- 多版本共存
-在url連結中標識資料版本 -https://api.baidu.com/v1 -https://api.baidu.com/v2 注:url連結中的v1,v2,就是不同資料版本的提現,(只有在一種資料資源有多版本情況下)
- 資料即資源
介面作為前後端互動的媒介其互動的資料又被叫做資源,推薦使用名詞或者名詞的複數形式,對於某些特殊介面,我們可以使用動詞(api/books api/login)
- 介面一般都是前後端資料的互動,互動的資料稱之為資源
- https://api.baidu.com/users
- https://api.baidu.com/books
- **資源操作由請求方式決定 ** (method)
資源的操作我們直接通過提交的請求方式來決定(get、post、put/patch、delete)
- 操作資源一般都涉及到增刪改查,以下請求方式來標識增刪改查動作
https://api.baidu.com/books -get請求:獲取所有書
https://api.baidu.com/books/1 -get請求:獲取主鍵為1 的書
https://api.baidu.com/books -post請求: 新增一本書
https://api.baidu.com/books/1 -put請求:整體修改主鍵為1的書
https://api.baidu.com/books/1 -patch請求:區域性修改主鍵為1 的書
https://api.baidu.com/books/1 -delete請求:刪除主鍵為1 的書
- 過濾
我們可以再url上傳參的形式傳遞搜尋條件
https://api.example.com/v1/people?limit=10 :指定返回記錄的數量
https://api.example.com/v1/people?offset=10 :指定返回記錄的開始位置
https://api.example.com/v1/people?page=2&per_page=100 :指定第幾頁,以及每頁的記錄數
https://api.example.com/v1/people?sortby=name&order=asc:指定返回結果按照哪個屬性排序,以及排序順序
https://api.example.com/v1/people?animal_type_id=1 :指定篩選條件
- 響應狀態碼
# 正常響應
200(正常請求)、
201(建立成功)、
# 重定向響應
301(永久重定向)、
302(臨時重定向)、
# 客戶端異常
403(請求無許可權)、
404(請求路徑不存在)、
405(請求方法不存在)、
# 服務端異常
500(伺服器異常)、
- 錯誤處理
應當返回錯誤資訊 error當作key
{
error:'無許可權操作'
}
- 返回結果
根據不同的請求以及請求得到的資料, 服務端返回不同的結果
GET /collection:返回資源物件的列表(陣列)
GET /collection/resource:返回單個資源物件
POST /collection:返回新生成的資源物件
PUT /collection/resource:返回完整的資源物件
PATCH /collection/resource:返回完成的資源物件
DELETE /collection/resource:返回一個空文件
- 需要url請求的資源需要訪問資源的請求連結
# Hypermedia API ,RESTFUL API最好做到Hypermedia,即返回結果中提供連結,連向其他API方法,使得使用者不查文件,也知道下一步應該做什麼
{
"status":0,
"msg":"OK",
"results":[
{
"name":"肯德基",
"img":"https://image.baidu.com/ftc/001.png"
}
........
]
}
(三十九)drf安裝和簡單使用
1、安裝
#安裝
pip install djangorestframework
2、使用
1.settings.py中
INSTALLED_APPS = [
'rest_framework'
]
2.在models.py中寫表模型
class Book(models.Model):
nid = models.AutoField(primary_key=True)
name = models.CharField(max_length=32)
price = models.DecimalField(max_digits=8, decimal_places=2)
author = models.CharField(max_length=32)
3. 新建一個序列化類 (新建一個py檔名字隨意)
from rest_framework.serializers import ModelSerializer
from App.models import Book
class BookModelSerializer(ModelSerializer):
class Meta:
model = Book
fields = '__all__'
4.檢視中寫檢視類(CBV)
from rest_framework.viewsets import ModelViewSet
from .models import Book
from .ser import BookModelSerializer #ser指的是第三步中建立的py檔案
class BooksViewSet(ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookModelSerializer
5.寫路由關係
from django.contrib import admin
from django.urls import path
from rest_framework.routers import DefaultRouter
from App import views
router = DefaultRouter() # 可以處理檢視的路由器
router.register('book', views.BooksViewSet) # 向路由中註冊檢視集
# 將路由器中的所有路由資訊追溯到django的路由列表中
urlpatterns = [
path('admin/', admin.site.urls),
]
# 兩個列表相加
urlpatterns += router.urls # router.urls是一個列表
6. 資料遷移
python manage.py makemigrations
python manage.py migrate
7.啟動專案,測試
啟動專案程式
3、postman測試
在postman
中測試,postman
中最後要加/
,瀏覽器會自動重定向,但postman
不會,所以在postman
中最後要加/
- 查資料
- 刪資料
將2
刪除後,就找不到資料
刪除2
資料後,再檢視所有資料
- 修改資料
修改完後,再次查詢所有
- 增加資料
增加後再次檢視所有資料
(四十)原始碼分析
cbv
ModelViewSet繼承與View (djanog原生View)
path('books/',views.Books.as_view())#在這個地方應該寫函式記憶體地址,views.Books.as_view()執行完,是個函式記憶體地址,as_view是一個類方法,類直接來呼叫,會把類自動傳入
放入了一個view的記憶體地址,(View--》as_view--》內層函式)
class Books(View):
# 只能接收get請求
http_method_names = ['get']
def get(self, request):
print(self.request)
return HttpResponse('ok')
"""原始碼分析"""
#請求來了,如果路徑匹配,會執行,函式記憶體地址(request)
def view(request, *args, **kwargs):
#request是當次請求的request
self = cls(**initkwargs)
self.setup(request, *args, **kwargs)
if not hasattr(self, 'request'): #例項化得到一個物件 Book物件
raise AttributeError(
"%s instance has no 'request' attribute. Did you override "
"setup() and forget to call super()?" % cls.__name__
)
return self.dispatch(request, *args, **kwargs)
def dispatch(self, request, *args, **kwargs):
#request就是當次請求的request selef是Book物件
if request.method.lower() in self.http_method_names:
#handle是自己寫的Book類的get方法的記憶體地址
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
return handler(request, *args, **kwargs) #執行get(request)
APIView原始碼分析
#urls.py
path('booksapiview/', views.BooksAPIView.as_view()),在這個地方應該寫函式記憶體地址
#views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.request import Request
class BooksAPIView(APIView):
def get(self, request):
#request已經不是原生的django的request了,是drf自己定義的request物件
print(self.request)
return HttpResponse('ok')
"""原始碼分析"""
#APIView的as_view方法(類的繫結方法)
@classmethod
def as_view(cls, **initkwargs):
view = super().as_view(**initkwargs)#呼叫父類(View)的as_view方法,
view.cls = cls
view.initkwargs = initkwargs
#以後所有的請求都沒有csrf認證了,只要繼承了APIV i額外,就沒有csrf認證了
return csrf_exempt(view)
#請求來了,路由匹配上,會執行view(request),呼叫了self.dispatch(),會執行apiview的self.dispatch()
#APIView的dispatch方法
def dispatch(self, request, *args, **kwargs):
self.args = args
self.kwargs = kwargs
#請求模組(解析模組)
# self.initialize_request(request, *args, **kwargs) 這裡的request是當次請求的request
#request= self.initialize_request 這裡的request是一個新的request物件
#重新包裝成一個request物件,以後再用的request物件,就是新的request物件
request = self.initialize_request(request, *args, **kwargs)
self.request = request
self.headers = self.default_response_headers # deprecate?
try:
#
self.initial(request, *args, **kwargs)
# Get the appropriate handler method
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(),
self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
#響應模組
response = handler(request, *args, **kwargs)
except Exception as exc:
#異常模組
response = self.handle_exception(exc)
#渲染模組
self.response = self.finalize_response(request, response, *args, **kwargs)
return self.response
補充:
一切皆物件
def foo(a, b):
return a + b
foo.name = 'zhao'
print(foo(1, 3))
print(foo.name)
區域性禁用csrf
#檢視函式中加裝飾器@csrf_exempt
#csrf_exempt(view)和在檢視函式上加裝飾器是一摸一樣的
from django.views.decorators.csrf import csrf_exempt
urlpatterns = [
path('test/',csrf_exempt(views.test))#也是禁用csrf認證
]
drf的Request類
from rest_framework.request import Request
#只要繼承了APIView,檢視中的request物件,都是新的,也就是上面這個request的物件,
#老的request在新的request._request裡
#以後使用request物件,就像使用之前的request是一摸一樣的(因為重寫了__getattr__方法)
def __getattr__(self, attr):
try:
return getattr(self._request, attr) #通過反射,取原生的request物件,取出屬性和方法
except AttributeError:
return self.__getattribute__(attr)
#request.data 感覺是資料屬性,其實是個方法,@property修飾了
它是一個欄位,post請求不管使用社麼編碼,傳過來的資料,都在request.data中