django rest framework 數(shù)據(jù)的查找、過濾、排序的示例
對(duì)于管理系統(tǒng),常常需要展示列表數(shù)據(jù),我們對(duì)于列表內(nèi)的數(shù)據(jù)常常需要查找、過濾、排序等操作,其中查找等操作大部分是在后臺(tái)進(jìn)行的。django rest framework可以輕松的實(shí)現(xiàn)數(shù)據(jù)的查找、過濾等操作。接下來我們將以實(shí)際的例子進(jìn)行介紹。
示例代碼github地址: https://github.com/jinjidejuren/drf_learn
例如cmdb系統(tǒng),作為資產(chǎn)管理系統(tǒng)常常需要對(duì)數(shù)據(jù)進(jìn)行過濾或查找,獲取期望的信息。
實(shí)現(xiàn)model
1.在這個(gè)示例項(xiàng)目中,需要實(shí)現(xiàn)對(duì)物理服務(wù)器的條件過濾,物理服務(wù)器的model列表如下(apps/assets/models.py文件):
class Server(models.Model):
"""
物理服務(wù)器
"""
status_choice = (
('online', '上線'),
('offline', '下線'),
('normal', '正常'),
('abnormal', '異常')
)
server_name = models.CharField(verbose_name=u'服務(wù)器名稱', max_length=128, blank=False, null=False)
server_num = models.CharField(verbose_name=u'服務(wù)器編號(hào)', max_length=128, blank=True, null=True)
brand = models.CharField(verbose_name=u'品牌', max_length=64, blank=True, null=True)
model = models.CharField(verbose_name=u'型號(hào)', max_length=64, blank=True, null=True)
cpus = models.IntegerField(verbose_name=u'cpu核數(shù)', default=0)
ram = models.IntegerField(verbose_name=u'內(nèi)存大小', default=0)
disk = models.IntegerField(verbose_name=u'磁盤大小', default=0)
product_date = models.DateTimeField(verbose_name=u'生產(chǎn)日期', auto_now_add=True)
status = models.CharField(verbose_name=u'狀態(tài)', max_length=16, choices=status_choice)
created_time = models.DateTimeField(verbose_name=u'創(chuàng)建時(shí)間', auto_now_add=True)
modified_time = models.DateTimeField(verbose_name=u'修改時(shí)間', auto_now_add=True)
class Meta:
verbose_name = u'服務(wù)器'
verbose_name_plural = verbose_name
def __str__(self):
return self.server_name
實(shí)現(xiàn)serializer
接下來需要實(shí)現(xiàn)server這個(gè)model的序列化類,在apps/assets/serializers.py中編寫:
class ServiceSerializer(serializers.ModelSerializer):
"""
服務(wù)器序列化
"""
class Meta:
model = Server
fields = ('id', 'server_name', 'server_num', 'brand', 'model', 'cpus',
'ram', 'disk', 'product_date', 'status', 'created_time',
'modified_time')
對(duì)于fields來說,可以使用 _ all _ 來代表所有的字段,除了model中定義的field外,序列化還可以指定其他的信息,比如嵌套信息或者自定義的信息。具體可以取決于業(yè)務(wù)邏輯。
實(shí)現(xiàn)modelviewset
對(duì)于modelviewset,我們可以圍繞它對(duì)用戶請(qǐng)求做相應(yīng)的處理。常見的是對(duì)model進(jìn)行增加、刪除、查找、修改等。在這部分我們需要實(shí)現(xiàn)ServerViewSet:
class ServerViewSet(viewsets.ModelViewSet):
"""
物理服務(wù)器視圖
"""
queryset = Server.objects.all().order_by('-created_time')
serializer_class = ServerSerializer
pagination_class = MyFormatResultsSetPagination
queryset指定返回列表的形式,所有的信息都返回,并且按照創(chuàng)建時(shí)間逆序排列,這樣可以把最新的信息先返回,比較符合用戶的操作習(xí)慣。
serializer_class定義了返回的序列化格式為ServerSerializer所指定的fields內(nèi)容
pagination_class 指定了分頁的類型,這個(gè)MyFormatResultsSetPagination是我們的自定義類型
實(shí)現(xiàn)router
如果用戶想要訪問server的信息,需要指定server的路由,這個(gè)和之前介紹的類似。需要的嗯一個(gè)一個(gè)router對(duì)象,并且將server的路由注冊(cè)進(jìn)去。
from rest_framework import routers router = routers.DefaultRouter() router.register(r'servers', views.ServerViewSet, base_name='servers') urlpatterns = [ url(r'^', include(router.urls)) ]
對(duì)于servers的訪問都由ServerViewSet進(jìn)行處理。
嘗試訪問
http://127.0.0.1:8060/assets/v1/servers/ ,信息如下:

注:我們需要添加示例信息,作為后續(xù)的各種測(cè)試使用。
按照條件獲取
在日常操作中,我們需要獲取指定條件的數(shù)據(jù),例如對(duì)于物理服務(wù)器,我們需要指定品牌、指定cpu核數(shù)、指定內(nèi)存大小等。有時(shí)候我們需要按照cpu核數(shù)進(jìn)行排序。這些都需要我們對(duì)ServerViewSet進(jìn)行更多的拓展。
如果進(jìn)行條件過濾,需要首先安裝django-filter模塊:
pip install django-filter
在配置文件settings/base.py中添加應(yīng)用django_filters:
INSTALLED_APPS = [ # 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'django_filters', 'apps.assets', 'apps.rbac' ]
在apps/assets/views.py頂部包含如下包:
from django_filters.rest_framework import DjangoFilterBackend from rest_framework import filters from django_filters import rest_framework
ServerViewSet可以添加相應(yīng)的過濾條件:
class ServerViewSet(viewsets.ModelViewSet):
"""
物理服務(wù)器視圖
"""
queryset = Server.objects.all()
serializer_class = ServerSerializer
pagination_class = MyFormatResultsSetPagination
filter_backends = (rest_framework.DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter, )
filter_class = ServerFilter
search_fields = ('server_name', '=brand', 'status', )
ordering_fields = ('cpus', 'ram', 'disk', 'product_date', )
ordering = ('-created_time', )
這里的filter_backends指定了過濾的類型,此處設(shè)定了DjangoFilterBackend(過濾)、SearchFilter(搜索)和OrderingFIlter(排序)。
1.過濾
過濾設(shè)定了過濾的配置類為ServerFilter,關(guān)于ServerFilter在apps/assets/filters.py文件中進(jìn)行了定義:
import django_filters
from .models import *
class ServerFilter(django_filters.rest_framework.FilterSet):
"""
物理服務(wù)器過濾器
"""
server_name = django_filters.CharFilter(name='server_name', lookup_expr='icontains')
brand = django_filters.CharFilter(name='brand', lookup_expr='icontains')
cpus = django_filters.NumberFilter(name='cpus')
ram = django_filters.NumberFilter(name='ram')
disk = django_filters.NumberFilter(name='disk')
class Meta:
model = Server
fields = ['server_name', 'brand', 'cpus', 'ram', 'disk', ]
也就是說可以通過'server_name', ‘brand', ‘cpus', ‘ram', ‘disk'對(duì)物理服務(wù)器的信息進(jìn)行過濾,得到相應(yīng)的序列化列表。
例如獲取cpu為24核的物理服務(wù)器:

得到物理服務(wù)器列表中cpu都為24:
GET /assets/v1/servers/?server_name=&brand=&cpus=24&ram=&disk=
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"results": [
{
"id": 9,
"server_name": "data-server2",
"server_num": "server-01-shanghai",
"brand": "hp",
"model": "HPE Apollo 4200 Gen9",
"cpus": 24,
"ram": 64,
"disk": 2500,
"product_date": "2018-06-23T13:51:09.641473Z",
"status": "online",
"created_time": "2018-06-23T13:51:09.642583Z",
"modified_time": "2018-06-23T13:51:09.642764Z"
},
{
"id": 8,
"server_name": "data-server2",
"server_num": "server-01-shanghai",
"brand": "hp",
"model": "HPE Apollo 4200 Gen9",
"cpus": 24,
"ram": 64,
"disk": 5000,
"product_date": "2018-06-23T13:51:02.466031Z",
"status": "online",
"created_time": "2018-06-23T13:51:02.467274Z",
"modified_time": "2018-06-23T13:51:02.467471Z"
},
{
"id": 7,
"server_name": "data-server1",
"server_num": "server-01-shanghai",
"brand": "hp",
"model": "HPE Apollo 4200 Gen9",
"cpus": 24,
"ram": 64,
"disk": 5000,
"product_date": "2018-06-23T13:50:55.622403Z",
"status": "offline",
"created_time": "2018-06-23T13:50:55.623315Z",
"modified_time": "2018-06-23T13:50:55.623431Z"
},
{
"id": 6,
"server_name": "data-server",
"server_num": "server-01-shanghai",
"brand": "hp",
"model": "HPE Apollo 4200 Gen9",
"cpus": 24,
"ram": 64,
"disk": 5000,
"product_date": "2018-06-23T13:50:48.088028Z",
"status": "online",
"created_time": "2018-06-23T13:50:48.089433Z",
"modified_time": "2018-06-23T13:50:48.089703Z"
},
{
"id": 5,
"server_name": "harbor-server3",
"server_num": "server-01-beijing",
"brand": "dell",
"model": "Rack",
"cpus": 24,
"ram": 128,
"disk": 5000,
"product_date": "2018-06-23T13:49:27.590015Z",
"status": "offline",
"created_time": "2018-06-23T13:49:27.590980Z",
"modified_time": "2018-06-23T13:49:27.591097Z"
},
{
"id": 4,
"server_name": "harbor-server3",
"server_num": "server-01-beijing",
"brand": "dell",
"model": "Rack",
"cpus": 24,
"ram": 128,
"disk": 5000,
"product_date": "2018-06-23T13:49:23.783337Z",
"status": "abnormal",
"created_time": "2018-06-23T13:49:23.784243Z",
"modified_time": "2018-06-23T13:49:23.784500Z"
},
{
"id": 3,
"server_name": "harbor-server2",
"server_num": "server-01-beijing",
"brand": "dell",
"model": "Rack",
"cpus": 24,
"ram": 128,
"disk": 5000,
"product_date": "2018-06-23T13:49:16.348672Z",
"status": "online",
"created_time": "2018-06-23T13:49:16.349555Z",
"modified_time": "2018-06-23T13:49:16.349663Z"
},
{
"id": 2,
"server_name": "harbor-server1",
"server_num": "server-02-beijing",
"brand": "dell",
"model": "Rack",
"cpus": 24,
"ram": 128,
"disk": 5000,
"product_date": "2018-06-23T13:48:57.853354Z",
"status": "online",
"created_time": "2018-06-23T13:48:57.853990Z",
"modified_time": "2018-06-23T13:48:57.854098Z"
},
{
"id": 1,
"server_name": "harbor-server",
"server_num": "server-01-beijing",
"brand": "dell",
"model": "Rack",
"cpus": 24,
"ram": 128,
"disk": 5000,
"product_date": "2018-06-23T13:48:48.777153Z",
"status": "online",
"created_time": "2018-06-23T13:48:48.778048Z",
"modified_time": "2018-06-23T13:48:48.778166Z"
}
],
"pagination": 9,
"page_size": 10,
"page": 1
}
2.搜索
搜索需要指定 search 關(guān)鍵字需要查詢的信息,例如搜索名稱為‘test'開頭的服務(wù)器:
http://127.0.0.1:8060/assets/v1/servers/?search=test
獲取列表:
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"results": [
{
"id": 14,
"server_name": "test-server1",
"server_num": "server-01-shanghai",
"brand": "dell",
"model": "Modular",
"cpus": 32,
"ram": 256,
"disk": 500,
"product_date": "2018-06-23T13:52:40.583743Z",
"status": "offline",
"created_time": "2018-06-23T13:52:40.584409Z",
"modified_time": "2018-06-23T13:52:40.584512Z"
},
{
"id": 13,
"server_name": "test-server",
"server_num": "server-01-shanghai",
"brand": "dell",
"model": "Modular",
"cpus": 32,
"ram": 256,
"disk": 2500,
"product_date": "2018-06-23T13:52:24.760819Z",
"status": "normal",
"created_time": "2018-06-23T13:52:24.761475Z",
"modified_time": "2018-06-23T13:52:24.761578Z"
}
],
"pagination": 2,
"page_size": 10,
"page": 1
}
在search_fields中可以指定多種查找方式:
‘^name' 以name開頭
‘=name' 精確匹配
‘@' 全局檢索(只有mysql數(shù)據(jù)源支持)
‘$' 正則匹配
對(duì)應(yīng)的search_fileds示例如下:
search_fields = ('^server_name', '=brand', 'status', )
3.排序
在ordering字段指定了默認(rèn)排序方式(按照創(chuàng)建時(shí)間逆序排序):
ordering = ('-created_time', )
也可以使用如下方式指定:
queryset = Server.objects.all().order_by('-created_time')
如果要自定義排序字段,需要指定 ordering 字段的內(nèi)容:
例如按照內(nèi)存大小排列服務(wù)器:
http://127.0.0.1:8060/assets/v1/servers/?ordering=ram
獲取的信息列表如下:
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
{
"results": [
{
"id": 6,
"server_name": "data-server",
"server_num": "server-01-shanghai",
"brand": "hp",
"model": "HPE Apollo 4200 Gen9",
"cpus": 24,
"ram": 64,
"disk": 5000,
"product_date": "2018-06-23T13:50:48.088028Z",
"status": "online",
"created_time": "2018-06-23T13:50:48.089433Z",
"modified_time": "2018-06-23T13:50:48.089703Z"
},
{
"id": 7,
"server_name": "data-server1",
"server_num": "server-01-shanghai",
"brand": "hp",
"model": "HPE Apollo 4200 Gen9",
"cpus": 24,
"ram": 64,
"disk": 5000,
"product_date": "2018-06-23T13:50:55.622403Z",
"status": "offline",
"created_time": "2018-06-23T13:50:55.623315Z",
"modified_time": "2018-06-23T13:50:55.623431Z"
},
{
"id": 8,
"server_name": "data-server2",
"server_num": "server-01-shanghai",
"brand": "hp",
"model": "HPE Apollo 4200 Gen9",
"cpus": 24,
"ram": 64,
"disk": 5000,
"product_date": "2018-06-23T13:51:02.466031Z",
"status": "online",
"created_time": "2018-06-23T13:51:02.467274Z",
"modified_time": "2018-06-23T13:51:02.467471Z"
},
{
"id": 9,
"server_name": "data-server2",
"server_num": "server-01-shanghai",
"brand": "hp",
"model": "HPE Apollo 4200 Gen9",
"cpus": 24,
"ram": 64,
"disk": 2500,
"product_date": "2018-06-23T13:51:09.641473Z",
"status": "online",
"created_time": "2018-06-23T13:51:09.642583Z",
"modified_time": "2018-06-23T13:51:09.642764Z"
},
{
"id": 1,
"server_name": "harbor-server",
"server_num": "server-01-beijing",
"brand": "dell",
"model": "Rack",
"cpus": 24,
"ram": 128,
"disk": 5000,
"product_date": "2018-06-23T13:48:48.777153Z",
"status": "online",
"created_time": "2018-06-23T13:48:48.778048Z",
"modified_time": "2018-06-23T13:48:48.778166Z"
},
{
"id": 2,
"server_name": "harbor-server1",
"server_num": "server-02-beijing",
"brand": "dell",
"model": "Rack",
"cpus": 24,
"ram": 128,
"disk": 5000,
"product_date": "2018-06-23T13:48:57.853354Z",
"status": "online",
"created_time": "2018-06-23T13:48:57.853990Z",
"modified_time": "2018-06-23T13:48:57.854098Z"
},
{
"id": 3,
"server_name": "harbor-server2",
"server_num": "server-01-beijing",
"brand": "dell",
"model": "Rack",
"cpus": 24,
"ram": 128,
"disk": 5000,
"product_date": "2018-06-23T13:49:16.348672Z",
"status": "online",
"created_time": "2018-06-23T13:49:16.349555Z",
"modified_time": "2018-06-23T13:49:16.349663Z"
},
{
"id": 4,
"server_name": "harbor-server3",
"server_num": "server-01-beijing",
"brand": "dell",
"model": "Rack",
"cpus": 24,
"ram": 128,
"disk": 5000,
"product_date": "2018-06-23T13:49:23.783337Z",
"status": "abnormal",
"created_time": "2018-06-23T13:49:23.784243Z",
"modified_time": "2018-06-23T13:49:23.784500Z"
},
{
"id": 5,
"server_name": "harbor-server3",
"server_num": "server-01-beijing",
"brand": "dell",
"model": "Rack",
"cpus": 24,
"ram": 128,
"disk": 5000,
"product_date": "2018-06-23T13:49:27.590015Z",
"status": "offline",
"created_time": "2018-06-23T13:49:27.590980Z",
"modified_time": "2018-06-23T13:49:27.591097Z"
},
{
"id": 10,
"server_name": "data-server2",
"server_num": "server-01-shanghai",
"brand": "hp",
"model": "HPE Apollo 4200 Gen9",
"cpus": 32,
"ram": 256,
"disk": 2500,
"product_date": "2018-06-23T13:51:30.706187Z",
"status": "online",
"created_time": "2018-06-23T13:51:30.707754Z",
"modified_time": "2018-06-23T13:51:30.707878Z"
}
],
"pagination": 14,
"page_size": 10,
"page": 1
}
上述的排序、過濾等操作可以組合使用,一般為前端的列表搜索查詢提供接口支持。
小結(jié)
本章小結(jié)的內(nèi)容介紹了django rest framework如何進(jìn)行model的定義、序列化、增刪改查以及搜索、排序等功能,是書寫后端接口必須掌握的技巧。
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
python接入GoogleAuth的實(shí)現(xiàn)
經(jīng)常會(huì)用到GoogleAuth作為二次驗(yàn)證碼,本文主要介紹了python接入GoogleAuth的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-08-08
Django調(diào)用支付寶接口代碼實(shí)例詳解
這篇文章主要介紹了Django調(diào)用支付寶接口代碼實(shí)例詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04
Pandas之StyleFrame如何設(shè)置表格樣式
這篇文章主要介紹了Pandas之StyleFrame如何設(shè)置表格樣式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-07-07

