視圖/視圖集/路由

Request 與 Response

  1. 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相同闹炉,只是更換了更正確的名稱而已蒿赢。

  1. 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. 兩個基類
    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)限被訪問嘉抓。

  1. 五個擴(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. 幾個可用子類視圖
    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', 'list')), url(r'^books/(?P<pk>\d+)/', 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ù)屎即。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末庙睡,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子技俐,更是在濱河造成了極大的恐慌乘陪,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件雕擂,死亡現(xiàn)場離奇詭異啡邑,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)捂刺,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門谣拣,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人族展,你說我怎么就攤上這事森缠。” “怎么了仪缸?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵贵涵,是天一觀的道長。 經(jīng)常有香客問我,道長宾茂,這世上最難降的妖魔是什么瓷马? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮跨晴,結(jié)果婚禮上欧聘,老公的妹妹穿的比我還像新娘。我一直安慰自己端盆,他們只是感情好怀骤,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著焕妙,像睡著了一般蒋伦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上焚鹊,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天痕届,我揣著相機(jī)與錄音,去河邊找鬼末患。 笑死研叫,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的璧针。 我是一名探鬼主播蓝撇,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼陈莽!你這毒婦竟也來了渤昌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤走搁,失蹤者是張志新(化名)和其女友劉穎独柑,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體私植,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡忌栅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了曲稼。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片索绪。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖贫悄,靈堂內(nèi)的尸體忽然破棺而出瑞驱,到底是詐尸還是另有隱情,我是刑警寧澤窄坦,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布唤反,位于F島的核電站凳寺,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏彤侍。R本人自食惡果不足惜肠缨,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一盏阶、第九天 我趴在偏房一處隱蔽的房頂上張望晒奕。 院中可真熱鬧名斟,春花似錦、人聲如沸蒸眠。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至脾歇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間藕各,已是汗流浹背池摧。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工作彤, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人乌逐。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像浙踢,于是被迫代替她去往敵國和親绢慢。 傳聞我的和親對象是個殘疾皇子洛波,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容