Request 與 Response
- Request
REST framework 傳入視圖的request對象不再是Django默認(rèn)的HttpRequest對象,而是REST framework提供的擴(kuò)展了HttpRequest類的Request類的對象痒玩。REST framework 提供了Parser解析器嵌牺,在接收到請求后會自動根據(jù)Content-Type指明的請求數(shù)據(jù)類型(如JSON、表單等)將請求數(shù)據(jù)進(jìn)行parse解析速址,解析為類字典對象保存到Request對象中玩焰。
Request對象的數(shù)據(jù)是自動根據(jù)前端發(fā)送數(shù)據(jù)的格式進(jìn)行解析之后的結(jié)果。無論前端發(fā)送的哪種格式的數(shù)據(jù)芍锚,我們都可以以統(tǒng)一的方式讀取數(shù)據(jù)昔园。
常用屬性
1).data
request.data 返回解析之后的請求體數(shù)據(jù)。類似于Django中標(biāo)準(zhǔn)的request.POST和 request.FILES屬性
2).query_params
request.query_params與Django標(biāo)準(zhǔn)的request.GET相同闹炉,只是更換了更正確的名稱而已蒿赢。
- Response
rest_framework.response.Response
REST framework提供了一個響應(yīng)類Response,使用該類構(gòu)造響應(yīng)對象時渣触,響應(yīng)的具體數(shù)據(jù)內(nèi)容會被轉(zhuǎn)換(render渲染)成符合前端需求的類型羡棵。
REST framework提供了Renderer 渲染器,用來根據(jù)請求頭中的Accept(接收數(shù)據(jù)類型聲明)來自動轉(zhuǎn)換響應(yīng)數(shù)據(jù)到對應(yīng)格式嗅钻。如果前端請求中未進(jìn)行Accept聲明皂冰,則會采用默認(rèn)方式處理響應(yīng)數(shù)據(jù),我們可以通過配置來修改默認(rèn)響應(yīng)格式养篓。
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': ( # 默認(rèn)響應(yīng)渲染類
'rest_framework.renderers.JSONRenderer', # json渲染器
'rest_framework.renderers.BrowsableAPIRenderer', # 瀏覽API渲染器
)
}
構(gòu)造方式
Response(data, status=None, template_name=None, headers=None, content_type=None)
data數(shù)據(jù)不要是render處理之后的數(shù)據(jù)秃流,只需傳遞python的內(nèi)建類型數(shù)據(jù)即可,REST framework會使用renderer渲染器處理data柳弄。
data不能是復(fù)雜結(jié)構(gòu)的數(shù)據(jù)舶胀,如Django的模型類對象,對于這樣的數(shù)據(jù)我們可以使用Serializer序列化器序列化處理后(轉(zhuǎn)為了Python字典類型)再傳遞給data參數(shù)碧注。
參數(shù)說明:
data: 為響應(yīng)準(zhǔn)備的序列化處理后的數(shù)據(jù)嚣伐;
status: 狀態(tài)碼,默認(rèn)200萍丐;
template_name: 模板名稱轩端,如果使用HTMLRenderer 時需指明;
headers: 用于存放響應(yīng)頭信息的字典逝变;
content_type: 響應(yīng)數(shù)據(jù)的Content-Type基茵,通常此參數(shù)無需傳遞奋构,REST framework會根據(jù)前端所需類型數(shù)據(jù)來設(shè)置該參數(shù)。
常用屬性:
1).data
傳給response對象的序列化后拱层,但尚未render處理的數(shù)據(jù)
2).status_code
狀態(tài)碼的數(shù)字
3).content
經(jīng)過render處理后的響應(yīng)數(shù)據(jù)
視圖
- 兩個基類
1)APIView
rest_framework.views.APIView
APIView是REST framework提供的所有視圖的基類弥臼,繼承自Django的View父類。
APIView與View的不同之處在于:
傳入到視圖方法中的是REST framework的Request對象舱呻,而不是Django的HttpRequeset對象醋火;
視圖方法可以返回REST framework的Response對象,視圖會為響應(yīng)數(shù)據(jù)設(shè)置(render)符合前端要求的格式箱吕;
任何APIException異常都會被捕獲到芥驳,并且處理成合適的響應(yīng)信息;
在進(jìn)行dispatch()分發(fā)前茬高,會對請求進(jìn)行身份認(rèn)證兆旬、權(quán)限檢查、流量控制怎栽。
支持定義的屬性:
authentication_classes 列表或元祖丽猬,身份認(rèn)證類
permissoin_classes 列表或元祖,權(quán)限檢查類
throttle_classes 列表或元祖熏瞄,流量控制類
在APIView中仍以常規(guī)的類視圖定義方法來實現(xiàn)get() 脚祟、post() 或者其他請求方式的方法。
2)GenericAPIView
rest_framework.generics.GenericAPIView
繼承自APIVIew强饮,增加了對于列表視圖和詳情視圖可能用到的通用支持方法由桌。通常使用時,可搭配一個或多個Mixin擴(kuò)展類邮丰。
支持定義的屬性:
列表視圖與詳情視圖通用:
queryset 列表視圖的查詢集
serializer_class 視圖使用的序列化器
列表視圖使用:
pagination_class 分頁控制類
filter_backends 過濾控制后端
詳情頁視圖使用:
lookup_field 查詢單一數(shù)據(jù)庫對象時使用的條件字段行您,默認(rèn)為'pk'
lookup_url_kwarg 查詢單一數(shù)據(jù)時URL中的參數(shù)關(guān)鍵字名稱,默認(rèn)與look_field相同
提供的方法:
列表視圖與詳情視圖通用:
get_queryset(self)
返回視圖使用的查詢集剪廉,是列表視圖與詳情視圖獲取數(shù)據(jù)的基礎(chǔ)娃循,默認(rèn)返回queryset屬性,可以重寫斗蒋,例如:
def get_queryset(self):
user = self.request.user
return user.accounts.all()
get_serializer_class(self)
返回序列化器類捌斧,默認(rèn)返回serializer_class,可以重寫泉沾,例如:
def get_serializer_class(self):
if self.request.user.is_staff:
return FullAccountSerializer
return BasicAccountSerializer
get_serializer(self, args, *kwargs)
返回序列化器對象捞蚂,被其他視圖或擴(kuò)展類使用,如果我們在視圖中想要獲取序列化器對象爆哑,可以直接調(diào)用此方法。注意舆吮,在提供序列化器對象的時候揭朝,REST framework會向?qū)ο蟮腸ontext屬性補(bǔ)充三個數(shù)據(jù):request队贱、format、view潭袱,這三個數(shù)據(jù)對象可以在定義序列化器時使用柱嫌。
詳情視圖使用:
get_object(self) 返回詳情視圖所需的模型類數(shù)據(jù)對象,默認(rèn)使用lookup_field參數(shù)來過濾queryset屯换。 在試圖中可以調(diào)用該方法獲取詳情信息的模型類對象编丘。若詳情訪問的模型類對象不存在,會返回404彤悔。該方法會默認(rèn)使用APIView提供的check_object_permissions方法檢查當(dāng)前對象是否有權(quán)限被訪問嘉抓。
- 五個擴(kuò)展類
1)ListModelMixin
列表視圖擴(kuò)展類,提供list(request, *args, **kwargs)方法快速實現(xiàn)列表視圖晕窑,返回200狀態(tài)碼抑片。
該Mixin的list方法會對數(shù)據(jù)進(jìn)行過濾和分頁。
2)CreateModelMixin
創(chuàng)建視圖擴(kuò)展類杨赤,提供create(request, *args, **kwargs)方法快速實現(xiàn)創(chuàng)建資源的視圖敞斋,成功返回201狀態(tài)碼。如果序列化器對前端發(fā)送的數(shù)據(jù)驗證失敗疾牲,返回400錯誤植捎。
3) RetrieveModelMixin
詳情視圖擴(kuò)展類,提供retrieve(request, *args, **kwargs)方法阳柔,可以快速實現(xiàn)返回一個存在的數(shù)據(jù)對象焰枢。如果存在,返回200盔沫, 否則返回404医咨。
4)UpdateModelMixin
更新視圖擴(kuò)展類,提供update(request, *args, **kwargs)方法架诞,可以快速實現(xiàn)更新一個存在的數(shù)據(jù)對象拟淮。同時也提供partial_update(request, *args, **kwargs)方法,可以實現(xiàn)局部更新谴忧。
成功返回200很泊,序列化器校驗數(shù)據(jù)失敗時,返回400錯誤沾谓。
5)DestroyModelMixin
刪除視圖擴(kuò)展類委造,提供destroy(request, *args, **kwargs)方法,可以快速實現(xiàn)刪除一個存在的數(shù)據(jù)對象均驶。成功返回204昏兆,不存在返回404。
- 幾個可用子類視圖
1) CreateAPIView
提供 post 方法,繼承自: GenericAPIView妇穴、CreateModelMixin
2)ListAPIView
提供 get 方法,繼承自:GenericAPIView爬虱、ListModelMixin
3)RetireveAPIView
提供 get 方法,繼承自: GenericAPIView隶债、RetrieveModelMixin
4)DestoryAPIView
提供 delete 方法,繼承自:GenericAPIView、DestoryModelMixin
5)UpdateAPIView
提供 put 和 patch 方法,繼承自:GenericAPIView跑筝、UpdateModelMixin
6)RetrieveUpdateAPIView
提供 get死讹、put、patch方法
繼承自: GenericAPIView曲梗、RetrieveModelMixin赞警、UpdateModelMixin
7)RetrieveUpdateDestoryAPIView
提供 get、put虏两、patch愧旦、delete方法,繼承自:GenericAPIView、RetrieveModelMixin碘举、UpdateModelMixin忘瓦、DestoryModelMixin
視圖集ViewSet
使用視圖集ViewSet,可以將一系列邏輯相關(guān)的動作放到一個類中:
ist() 提供一組數(shù)據(jù)
retrieve() 提供單個數(shù)據(jù)
create() 創(chuàng)建數(shù)據(jù)
update() 保存數(shù)據(jù)
destory() 刪除數(shù)據(jù)
ViewSet視圖集類不再實現(xiàn)get()引颈、post()等方法耕皮,而是實現(xiàn)動作 action 如 list() 、create() 等蝙场。視圖集只在使用as_view()方法的時候凌停,才會將action動作與具體請求方式對應(yīng)上。如:
class BookInfoViewSet(viewsets.ViewSet):
def list(self, request):
...
def retrieve(self, request, pk=None):
...
在設(shè)置路由時售滤,我們可以如下操作
urlpatterns = [
url(r'^books/', BookInfoViewSet.as_view('get', 'retrieve'))
]
action屬性
在視圖集中罚拟,我們可以通過action對象屬性來獲取當(dāng)前請求視圖集時的action動作是哪個。
例如:
def get_serializer_class(self):
if self.action == 'create':
return OrderCommitSerializer
else:
return OrderDataSerializer
常用視圖集父類
1) ViewSet
繼承自APIView完箩,作用也與APIView基本類似赐俗,提供了身份認(rèn)證、權(quán)限校驗弊知、流量管理等阻逮。在ViewSet中,沒有提供任何動作action方法秩彤,需要我們自己實現(xiàn)action方法叔扼。
2)GenericViewSet
繼承自GenericAPIView,作用也與GenericAPIVIew類似漫雷,提供了get_object瓜富、get_queryset等方法便于列表視圖與詳情信息視圖的開發(fā)。
3)ModelViewSet
繼承自GenericAPIVIew降盹,同時包括了ListModelMixin与柑、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin价捧、DestoryModelMixin每辟。
4)ReadOnlyModelViewSet
繼承自GenericAPIVIew,同時包括了ListModelMixin干旧、RetrieveModelMixin。
視圖集中定義附加action動作
在視圖集中妹蔽,除了上述默認(rèn)的方法動作外椎眯,還可以添加自定義動作。添加自定義動作需要使用rest_framework.decorators.action裝飾器胳岂。以action裝飾器裝飾的方法名會作為action動作名编整,與list、retrieve等同乳丰。
action裝飾器可以接收兩個參數(shù):
methods: 該action支持的請求方式掌测,列表傳遞
detail: 表示是action中要處理的是否是視圖資源的對象(即是否通過url路徑獲取主鍵)
True 表示使用通過URL獲取的主鍵對應(yīng)的數(shù)據(jù)對象
False 表示不使用URL獲取主鍵
路由Routers
對于視圖集ViewSet,我們除了可以自己手動指明請求方式與動作action之間的對應(yīng)關(guān)系外产园,還可以使用Routers來幫助我們快速實現(xiàn)路由信息汞斧。
REST framework提供了兩個router
- SimpleRouter
- DefaultRouter
1. 使用方法
1) 創(chuàng)建router對象,并注冊視圖集什燕,例如
from rest_framework import routers
router = routers.SimpleRouter()
router.register(r'books', BookInfoViewSet, base_name='book')
register(prefix, viewset, base_name)
- prefix 該視圖集的路由前綴
- viewset 視圖集
- base_name 路由名稱的前綴
如上述代碼會形成的路由如下:
^books/$ name: book-list
^books/{pk}/$ name: book-detail
2)添加路由數(shù)據(jù)
可以有兩種方式:
urlpatterns = [
...
]
urlpatterns += router.urls
或
urlpatterns = [
...
url(r'^', include(router.urls))
]
2. 視圖集中包含附加action的
class BookInfoViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
queryset = BookInfo.objects.all()
serializer_class = BookInfoSerializer
@action(methods=['get'], detail=False)
def latest(self, request):
...
@action(methods=['put'], detail=True)
def read(self, request, pk):
...
此視圖集會形成的路由:
^books/latest/$ name: book-latest
^books/{pk}/read/$ name: book-read
3. 路由router形成URL的方式
1) SimpleRouter
2)DefaultRouter
DefaultRouter與SimpleRouter的區(qū)別是粘勒,DefaultRouter會多附帶一個默認(rèn)的API根視圖,返回一個包含所有列表視圖的超鏈接響應(yīng)數(shù)據(jù)屎即。