【Python】利用Django搭建REST風格API後臺服務(三)關於DRF的搜尋、分頁、排序
簡介
這是第三篇內容,接下來我們介紹一下如何使用REST framework框架自帶的一些功能來豐富你的API。
我們都知道利用API獲取資源的場景下,不止是傻傻的查詢所有資料,然後對資料程序採集。我們如果要按照要求來篩選我們要的資料呢?
比如,我們不想要一次顯示這麼多條資料,我們在前臺不需要載入這麼多。或者,我們需要有條件的去篩查資料,或者有順序的去取資料。
這些在REST framework都已經幫你把功能設計好了,只需要引用和稍作定製就可以使用了。
我們分別來簡單的介紹一下REST framework的分頁、搜尋、排序的使用方法。
實驗我們還是拿上次試驗的那個Student類
分頁
我們在實際開發當中,不可能直接一個檢視下顯示所有的資料,一般web端會用分頁來劃分,而手機端一般是用“上拉載入”的辦法來進行新增資料的操作。這樣的操作無疑是減輕了前後臺兩端對資料庫操作的工作量,讓使用者需要吃多少就拿多少,不會造成大量的資源浪費。
REST framework為我們提供了比較不錯的分頁功能,
全域性分頁
分頁的方式有分兩種,一種是全域性設定,在setting.py下配置即可設定全域性分頁的功能。
REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination' }
分類中有許多屬性可以自己設定。網上有位大佬整理的很不錯,大家可以看看他寫的內容。
PageNumberPagination類包括可以覆蓋以修改分頁樣式的許多屬性,要設定這些屬性,應覆蓋PageNumberPagination類,然後如上所示啟用自定義分頁類。
django_paginator_class:使用的Django Paginator類,預設是django.core.paginator.Paginator,對大部分用例是適用的。
page_size:數值,頁面大小,預設是全域性PAGE_SIZE的值。
page_query_param:字串,查詢引數的名稱,預設是'page'page_size_query_param:字串,請求設定頁面大小的引數名稱,預設是None,表示客戶端可能無法控制請求的頁面大小。
max_page_size:字串,最大允許請求的頁面大小, 此屬性僅在page_size_query_param也被設定時有效。
last_page_strings:字串列表或者元組,預設是('last',)template:分頁控制元件使用的模板的名稱,可以覆蓋或設定為None,預設為"rest_framework/pagination/numbers.html"
———————————————註明出處分割線————————————————————————
來源:簡書簡書著作權歸作者所有,
任何形式的轉載都請聯絡作者獲得授權並註明出處。
設定完全域性分頁後,只需要輸入URL的形式就可以訪問
http://127.0.0.1:8000/api/student/?page=2
自定義分頁
當然,這裡我們更推薦的是自定義分頁的方法,畢竟這種方法畢竟靈活。在實際開發當中,也不是所有的資源都需要進行分頁的,或者不是所有資源都是一樣的分頁屬性,有的一頁10條,有的一頁只需要3條,這樣該怎麼做呢?
我們先在views.py下定義好一個分頁的配置:
# 記得要導包啊
from rest_framework import viewsets,filters,pagination
class PageSet(pagination.PageNumberPagination):
#每頁顯示多少個
page_size = 3
#預設每頁顯示3個
page_size_query_param = "size"
#最大頁數
max_page_size = 10
#獲取頁碼數的
page_query_param = "page"
然後我們在我們之前定義好的Viewsets類下使用它即可
class StudentViewSet(viewsets.ModelViewSet):
# 指定結果集並設定排序
queryset = Student.objects.all().order_by('-pk')
# 指定序列化的類
serializer_class = StudentSerializers
#指定分頁配置
pagination_class = PageSet
執行專案檢視檢視,是不是又變了?
可以看到右上角多了分頁的按鈕可以進行分頁。當然也可以通過URL來進行訪問分頁後的內容:
http://127.0.0.1:8000/api/student/?page=1
可以看到,返回的結果集也和之前不一樣了:
{
"count": 5,
"next": "http://127.0.0.1:8000/api/student/?page=2",
"previous": null,
"results": [
{
"pk": 6,
"name": "煞筆啊",
"sex": "male",
"sid": "0"
},
{
"pk": 4,
"name": "小明",
"sex": "???",
"sid": "113"
},
{
"pk": 3,
"name": "小王八",
"sex": "男",
"sid": "112"
}
]
}
—
count是該資源下的所有資源的數量。
next是下一頁的URL,這個非常重要,在許多場景下會使用得到。
previous則是上一頁,也是一個重要的功能
results則是我們的結果集了。
這樣一來簡單的自定義分頁就寫好了,有的同學可能要問了,在一些特殊的場景下,比如我臨時查詢的資料為5條而不是預設設定的3條,該怎麼查呢?
很簡單,我們在URL引數內設定好引數傳入即可,如下:
http://127.0.0.1:8000/api/student/?page=1&size=5
這樣就可以把size設定為5進行分頁查詢。是不是很方便?
按照資源對應的位置
我們在其他的場景下,可能會需要訪問到,第x個資源的那頁,就是按照位置來定位某一頁的內容。
比如我們一頁設定3個資源,我們需要訪問第4個資源的那頁,也就是第二頁。
這樣該如何來寫?參考下面程式碼:
class LimitSet(pagination.LimitOffsetPagination):
# 每頁預設幾條
default_limit = 3
# 設定傳入頁碼數引數名
page_query_param = "page"
# 設定傳入條數引數名
limit_query_param = 'limit'
# 設定傳入位置引數名
offset_query_param = 'offset'
# 最大每頁顯示條數
max_limit = None
使用方法和上一步一樣
class StudentViewSet(viewsets.ModelViewSet):
# 指定結果集並設定排序
queryset = Student.objects.all().order_by('-pk')
# 指定序列化的類
serializer_class = StudentSerializers
#指定分頁配置
pagination_class = LimitSet
輸入URL就按照位置來查詢了,比如查詢每頁3條、第4條的位置所在的分頁情況
http://127.0.0.1:8000/api/student/?limit=3&offset=4
常用的分頁功能暫時講到這裡吧
搜尋功能
搜尋功能可以說是當下必備的一個功能了,他用來檢索和過濾使用者所需要的資訊。
搜尋的實現方法非常多,REST framework有提供了一個相對比較簡潔的搜尋功能給我們使用。開啟views.py來裡的定義好的viewsets類來設定搜尋功能吧。
# 記得要導包啊
from rest_framework import viewsets,filters,pagination
class StudentViewSet(viewsets.ModelViewSet):
# 指定結果集並設定排序
queryset = Student.objects.all().order_by('-pk')
# 指定序列化的類
serializer_class = StudentSerializers
# 指定分頁配置
pagination_class = LimitSet
# 配置搜尋功能
filter_backends = (filters.SearchFilter,)
# 設定搜尋的關鍵字
search_fields = ('=name','sid')
這裡指的注意的是,在search_fields這個元組中,我們設定需要過濾的欄位分別為姓名name和學號sid。
我們可以發現檢視右上角多了一個filter的按鈕,點選可以進行搜尋
可以說非常貼心了
搜尋的URL也很簡單。
http://example.com/list/?search=?search=keyword
姓名這樣寫:=name 表示完全匹配。例如我寫小王,只能搜到小王,不能搜到小王八。
http://127.0.0.1:8000/api/student/?search=?search=小王
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"pk": 2,
"name": "小王",
"sex": "女",
"sid": "110"
}
]
}
而學號在不加任何修飾符下,是模糊搜尋,只有搜尋內容中有相關的字串都會被抓取出來。下載我們嘗試搜尋一下學號帶有 1 的學生。
http://127.0.0.1:8000/api/student/?search=1
{
"count": 4,
"next": "http://127.0.0.1:8000/api/student/?limit=3&offset=3&search=1",
"previous": null,
"results": [
{
"pk": 4,
"name": "小明",
"sex": "???",
"sid": "113"
},
{
"pk": 3,
"name": "小王八",
"sex": "男",
"sid": "112"
},
{
"pk": 2,
"name": "小王",
"sex": "女",
"sid": "110"
}
]
}
修飾符有以下幾種大家根據實際需求來選擇使用:
^ :搜尋關鍵字開頭的資料
= :完全匹配搜尋
@ :全文搜尋(目前只支援MySQL)
$ :正則表示式搜尋
簡單的檢索功能介紹就到此為止了。
排序功能
排序功能在資料量大的情況下便顯得非常有用了。我們在第一篇中有提到的預設排序,但是在未來的開發中,還有其他的需求在等著我們。比如拿這個Student類來說,我們需要對學生做排序,讓學生以姓名、學號、班級、成績等熟悉來進行有效的排序。該怎麼做?
還是開啟views.py下定義好的viewsets類進行新增程式碼
class StudentViewSet(viewsets.ModelViewSet):
# 指定結果集並設定排序
queryset = Student.objects.all().order_by('-pk')
# 指定序列化的類
serializer_class = StudentSerializers
# 指定分頁配置
pagination_class = PageSet
# 配置搜尋功能和排序功能
filter_backends = (filters.SearchFilter,filters.OrderingFilter,)
# 設定搜尋的關鍵字
search_fields = ('=name','sid')
# 設定需要被排序的欄位
ordering_fields = ('name', 'sid')
注意filter_backends元組下要新增filters.OrderingFilter才能實現排序功能
配置完畢後。我們這邊對name和sid兩個欄位註冊了排序的功能,這時就可以通過檢視或者URL來進行排序查詢了。
http://127.0.0.1:8000/api/student/?ordering=name&size=10
為了方便檢視更多結果,這邊我們把分頁數量的屬性設定成10條。
利用學生姓名欄位來進行排序,原來預設的是利用主鍵pk來排序的。
{
"count": 5,
"next": null,
"previous": null,
"results": [
{
"pk": 4,
"name": "小明",
"sex": "???",
"sid": "113"
},
{
"pk": 2,
"name": "小王",
"sex": "女",
"sid": "110"
},
{
"pk": 3,
"name": "小王八",
"sex": "男",
"sid": "112"
},
{
"pk": 1,
"name": "小紅",
"sex": "男",
"sid": "111"
},
{
"pk": 6,
"name": "煞筆啊",
"sex": "male",
"sid": "0"
}
]
}
結果出來了,排序分為兩種:升序和降序,使用方法就是在欄位前面加不加”-“號的區別而已,非常簡潔方便。
這已經是第三篇了。還有一些功能下次會繼續提出來,比如如何使用api進行多表聯查等功能。
其實有了這些功能以及足夠搭建一個微小的服務平臺了。
接下去有時間我會更新一下實戰專案,比如製作一套前後臺分離的系統,前臺分別用web端和android端來實現。
新手,寫的不好,有很多地方的借鑑網上大佬和官方文件的寫法。謝謝。
相關推薦
【Python】利用Django搭建REST風格API後臺服務(三)關於DRF的搜尋、分頁、排序
原文地址 簡介 這是第三篇內容,接下來我們介紹一下如何使用REST framework框架自帶的一些功能來豐富你的API。 我們都知道利用API獲取資源的場景下,不止是傻傻的查詢所有資料,然後對資料程序採集。我們如果要按照要求來篩選我們要的資料呢? 比如,
【Python】利用Django搭建REST風格API後臺服務(二)關於JWT認證
原文地址 簡介 上一篇我們介紹瞭如何搭建一個後臺,並且提供API服務。 顯然那太簡單了,功能上是遠遠達不到使用的級別的。一套完整的API還需要擴充套件非常多的東西才能達到要求。 上個實驗只是搭建一個最簡單的後臺服務。細心的朋友可能會問了,一個api怎麼可以被隨意的
【SpringMVC】9.REST風格的CRUD實戰(三)之新增操作
##注意!!! URI:emp 請求方式:GET 顯示效果 ####新增員工資訊 URI:emp 請求方式:POST 顯示效果:完成新增,重定向到 list 頁面。 ##二、介面分析 顯示頁面的URL都是emp,但是請求方式分別是GET和POS
【Linux】企業實戰-搭建高可用的WEB群集(全過程)
大家好,今天給大家帶來web高可用,其中服務包括(Nginx,PHP,MySQL,Memcached,zabbix,keepalived以及Xcahce外掛等; 其中包含: Nginx (Nginx的安裝及Nginx反向代理配置,對Ngin
【銅】第124篇 一對一視頻錄制(三)及網站註冊 周四
一對一視頻錄制 網站註冊 關鍵詞:一對一視頻錄制,網站註冊一、一對一視頻錄制1.1 參考網址https://www.webrtc-experiment.com/RecordRTC/視頻錄制下載網址:https://github.com/muaz-khan/RecordRTC1.2 網頁錄制本地:ht
【 MATLAB 】MATLAB 實現模擬訊號取樣後的重建(三)一階保持(FOH)內插
這篇博文我們使用一階保持(FOH)內插來重建訊號,採用的案例依然是上篇博文中的案例: 模擬訊號: 對該訊號使用兩種不同的取樣頻率取樣。 a. 在 fs = 5000 對訊號進行取樣 b.
【 MATLAB 】MATLAB 實現模擬訊號取樣後的重建(三)應用三次樣條函式spline實現內插
前三篇博文講了三種方法進行內插重建訊號: 這篇文章使用三次樣條函式spline來實現內插重建,並分析重建誤差。 採用的案例依然是上篇博文中的案例: 模擬訊號: 對該訊號使用兩種不
【matlab】MarkDown Letex 編碼 之 隨機過程及應用(三)
**Provement of Gaussian Distribution:** 設正態分佈概率密度函式是 $$f(x)=\frac{1}{\sqrt{2π}\sigma}*e^{\
【更新】Essential Studio for Xamarin更新至2018 v4(三)
下載Essential Studio for Xamarin最新版本 Essential Studio for Xamarin是全面的Xamarin.iOS、Xamarin.Android和Xamarin.Forms元件套包,包含最快的圖表和網格。 ESSENTIAL PDF OpenType字型
【SpringMVC】7.REST風格的CRUD實戰(一)之前期工作
一、什麼是REST和CRUD? 1.有關REST 有關REST的解釋我已近在之前的SpringMVC系列文章提到過,如果有興趣的同學可以翻看《【SpringMVC】3.REST表現層狀態轉換》進行檢視。 2.有關CRUD In comp
Python基礎入門,利用Django搭建第一個web框架!(文末福利)
本文面向:有Python基礎,剛接觸web框架的Django初學者。 環境:windows7 python3.5.1 pycharm Django 1.10版 pip3 一、Django簡介 百度百科:一個開放原始碼的Web框架,由Python語言編寫......
【SpringMVC】10.REST風格的CRUD實戰(四)之刪除操作
注意!!! 一、前情提要 刪除操作 URL:emp/{id} 請求方式:DELETE 刪除後效果:對應記錄從資料表中刪除 二、具體步驟 1.配置HiddenHttpMethodFilter 由於HTML只支援常見的Get和POST方法,而DELE
【SpringMVC】8.REST風格的CRUD實戰(二)之查詢操作
##注意!!! URI:emps 請求方式:GET 顯示效果 所以我們就圍繞這個需求來進行程式設計。 ##二、具體步驟 ###1.把Handler方法寫好 EmployeeHandler相關程式碼 package com.springmvc.cru
【Python】呼叫百度REST API實現語音識別
目前,語音識別,即將語音內容轉換為文字的技術已經比較成熟,遙想當時錘子釋出會上展示的訊飛輸入法語音識別,著實讓訊飛火了一把。由於此類語音識別需要採集大量的樣本,才能達到一定的準確度,個人很難從零開
【總結】利用AWS搭建混合雲的架構
1.邱洋的理解 定義了混合IT架構的概念(因為有些企業本地可能還沒有云,但是需要構建雲+物理的架構) 混合IT架構是趨勢,但最終不是公有云一統天下,而本地IT必然繼續存在,因為: 資料合規性要求(例:歐洲的資料只能在歐洲) 特殊硬體要求(例:加密狗等)
【問題解決】【Python】解決 django 中 mysql gone away 的問題
最近在專案中,我使用 Django Command 模組寫了一個指令碼,處理從 MQ 發來的訊息,併入庫。在測試過程中,程式執行良好,但是在程式上線並執行一段時間後,出現了以下錯誤: OperationalError: (2006, 'MySQL server has
【Python】利用count函式求list中每個元素出現的次數,求眾數的改進
在《【Python】利用setdefault函式實現dict的轉置(key與value對互換),統計value出現的次數》(點選開啟連結)中介紹過,如何統計dict中相同value的key的出現次數。本文介紹如何利用list自帶的count函式,來統計list中每個元素出現
【Python】利用python自動傳送郵件
## 前言 在訓練網路的過程中,需要大量的時間,雖然可以預估網路訓練完成時間,但蹲點看結果著實有點不太聰明的亞子。 因此,參照師兄之前發的python利用smtp自動發郵件的程式碼,我作了些調整,並參照網上的開原始碼,整理出了加強版(可以傳檔案),這樣訓練的log還有model,或者是遠端電腦上的檔案都可
【Python】使用Microsoft Azure的人臉API進行本地圖片情緒識別並存入excel
win exce xls 圖片 獲取時間 contain resp 每分鐘 ats 準備工作 首先,需要在Microsoft的主頁(https://azure.microsoft.com/zh-cn/)註冊一個賬號,然後進入門戶去創建新資源,選擇AI+Cognitive S
【WCF】利用WCF實現上傳下載檔案服務
引言 前段時間,用WCF做了一個小專案,其中涉及到檔案的上傳下載。出於複習鞏固的目的,今天簡單梳理了一下,整理出來,下面展示如何一步步實現一個上傳下載的WCF服務。 服務端 1.首先新建一個名為FileService的WCF服務庫專案,如下圖: