1. 程式人生 > >【Python】利用Django搭建REST風格API後臺服務(三)關於DRF的搜尋、分頁、排序

【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

執行專案檢視檢視,是不是又變了?

image.png

可以看到右上角多了分頁的按鈕可以進行分頁。當然也可以通過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的按鈕,點選可以進行搜尋

image.png

可以說非常貼心了

image.png

搜尋的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來進行排序查詢了。

image.png

  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怎麼可以被隨意的

SpringMVC9.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來實現內插重建,並分析重建誤差。 採用的案例依然是上篇博文中的案例: 模擬訊號: 對該訊號使用兩種不

matlabMarkDown 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字型

SpringMVC7.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語言編寫......

SpringMVC10.REST風格的CRUD實戰之刪除操作

注意!!! 一、前情提要 刪除操作 URL:emp/{id} 請求方式:DELETE 刪除後效果:對應記錄從資料表中刪除 二、具體步驟 1.配置HiddenHttpMethodFilter 由於HTML只支援常見的Get和POST方法,而DELE

SpringMVC8.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服務庫專案,如下圖: