django rest framework 数据的查找、过滤、排序的示例


Posted in Python onJune 25, 2018

对于管理系统,常常需要展示列表数据,我们对于列表内的数据常常需要查找、过滤、排序等操作,其中查找等操作大部分是在后台进行的。django rest framework可以轻松的实现数据的查找、过滤等操作。接下来我们将以实际的例子进行介绍。

示例代码github地址: https://github.com/jinjidejuren/drf_learn

例如cmdb系统,作为资产管理系统常常需要对数据进行过滤或查找,获取期望的信息。

实现model

1.在这个示例项目中,需要实现对物理服务器的条件过滤,物理服务器的model列表如下(apps/assets/models.py文件):

class Server(models.Model):
  """
  物理服务器
  """
  status_choice = (
    ('online', '上线'),
    ('offline', '下线'),
    ('normal', '正常'),
    ('abnormal', '异常')
  )

  server_name = models.CharField(verbose_name=u'服务器名称', max_length=128, blank=False, null=False)
  server_num = models.CharField(verbose_name=u'服务器编号', 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'型号', max_length=64, blank=True, null=True)
  cpus = models.IntegerField(verbose_name=u'cpu核数', default=0)
  ram = models.IntegerField(verbose_name=u'内存大小', default=0)
  disk = models.IntegerField(verbose_name=u'磁盘大小', default=0)
  product_date = models.DateTimeField(verbose_name=u'生产日期', auto_now_add=True)
  status = models.CharField(verbose_name=u'状态', max_length=16, choices=status_choice)

  created_time = models.DateTimeField(verbose_name=u'创建时间', auto_now_add=True)
  modified_time = models.DateTimeField(verbose_name=u'修改时间', auto_now_add=True)

  class Meta:
    verbose_name = u'服务器'
    verbose_name_plural = verbose_name

  def __str__(self):
    return self.server_name

实现serializer

接下来需要实现server这个model的序列化类,在apps/assets/serializers.py中编写:

class ServiceSerializer(serializers.ModelSerializer):
  """
  服务器序列化
  """

  class Meta:
    model = Server
    fields = ('id', 'server_name', 'server_num', 'brand', 'model', 'cpus',
         'ram', 'disk', 'product_date', 'status', 'created_time',
         'modified_time')

对于fields来说,可以使用 _ all _ 来代表所有的字段,除了model中定义的field外,序列化还可以指定其他的信息,比如嵌套信息或者自定义的信息。具体可以取决于业务逻辑。

实现modelviewset

对于modelviewset,我们可以围绕它对用户请求做相应的处理。常见的是对model进行增加、删除、查找、修改等。在这部分我们需要实现ServerViewSet:

class ServerViewSet(viewsets.ModelViewSet):
  """
  物理服务器视图
  """
  queryset = Server.objects.all().order_by('-created_time')
  serializer_class = ServerSerializer
  pagination_class = MyFormatResultsSetPagination

queryset指定返回列表的形式,所有的信息都返回,并且按照创建时间逆序排列,这样可以把最新的信息先返回,比较符合用户的操作习惯。

serializer_class定义了返回的序列化格式为ServerSerializer所指定的fields内容

pagination_class 指定了分页的类型,这个MyFormatResultsSetPagination是我们的自定义类型

实现router

如果用户想要访问server的信息,需要指定server的路由,这个和之前介绍的类似。需要的嗯一个一个router对象,并且将server的路由注册进去。

from rest_framework import routers

router = routers.DefaultRouter()
router.register(r'servers', views.ServerViewSet, base_name='servers')

urlpatterns = [
  url(r'^', include(router.urls))
]

对于servers的访问都由ServerViewSet进行处理。

尝试访问

http://127.0.0.1:8060/assets/v1/servers/ ,信息如下:

django rest framework 数据的查找、过滤、排序的示例

注:我们需要添加示例信息,作为后续的各种测试使用。

按照条件获取

在日常操作中,我们需要获取指定条件的数据,例如对于物理服务器,我们需要指定品牌、指定cpu核数、指定内存大小等。有时候我们需要按照cpu核数进行排序。这些都需要我们对ServerViewSet进行更多的拓展。

如果进行条件过滤,需要首先安装django-filter模块:

pip install django-filter

在配置文件settings/base.py中添加应用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可以添加相应的过滤条件:

class ServerViewSet(viewsets.ModelViewSet):
  """
  物理服务器视图
  """
  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指定了过滤的类型,此处设定了DjangoFilterBackend(过滤)、SearchFilter(搜索)和OrderingFIlter(排序)。

1.过滤

过滤设定了过滤的配置类为ServerFilter,关于ServerFilter在apps/assets/filters.py文件中进行了定义:

import django_filters

from .models import *


class ServerFilter(django_filters.rest_framework.FilterSet):
  """
  物理服务器过滤器
  """

  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'对物理服务器的信息进行过滤,得到相应的序列化列表。

例如获取cpu为24核的物理服务器:

django rest framework 数据的查找、过滤、排序的示例

得到物理服务器列表中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 关键字需要查询的信息,例如搜索名称为‘test'开头的服务器:

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数据源支持)

‘$' 正则匹配

对应的search_fileds示例如下:

search_fields = ('^server_name', '=brand', 'status', )

3.排序

在ordering字段指定了默认排序方式(按照创建时间逆序排序):

ordering = ('-created_time', )

也可以使用如下方式指定:

queryset = Server.objects.all().order_by('-created_time')

如果要自定义排序字段,需要指定 ordering 字段的内容:

例如按照内存大小排列服务器:

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
}

上述的排序、过滤等操作可以组合使用,一般为前端的列表搜索查询提供接口支持。

小结

本章小结的内容介绍了django rest framework如何进行model的定义、序列化、增删改查以及搜索、排序等功能,是书写后端接口必须掌握的技巧。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python 元组(Tuple)操作详解
Mar 11 Python
python实现将文本转换成语音的方法
May 28 Python
Python中datetime常用时间处理方法
Jun 15 Python
Python 文件管理实例详解
Nov 10 Python
利用Hyperic调用Python实现进程守护
Jan 02 Python
运用PyTorch动手搭建一个共享单车预测器
Aug 06 Python
Python使用Tkinter实现转盘抽奖器的步骤详解
Jan 06 Python
Django 博客实现简单的全文搜索的示例代码
Feb 17 Python
python sklearn包——混淆矩阵、分类报告等自动生成方式
Feb 28 Python
pyautogui自动化控制鼠标和键盘操作的步骤
Apr 01 Python
python树莓派通过队列实现进程交互的程序分析
Jul 04 Python
Python代码实现双链表
May 25 Python
python使用turtle库绘制树
Jun 25 #Python
使用Python微信库itchat获得好友和群组已撤回的消息
Jun 24 #Python
python库lxml在linux和WIN系统下的安装
Jun 24 #Python
Python3中详解fabfile的编写
Jun 24 #Python
关于python写入文件自动换行的问题
Jun 23 #Python
利用Python读取txt文档的方法讲解
Jun 23 #Python
python读取一个目录下所有txt里面的内容方法
Jun 23 #Python
You might like
php中CI操作多个数据库的代码
2012/07/05 PHP
PHP 闭包详解及实例代码
2016/09/28 PHP
通过源码解析Laravel的依赖注入
2018/01/22 PHP
PHP实现Snowflake生成分布式唯一ID的方法示例
2020/08/30 PHP
用JavaScript 处理 URL 的两个函数代码
2007/08/13 Javascript
mapper--图片热点区域高亮组件官方站点
2007/12/22 Javascript
js类式继承的具体实现方法
2013/12/31 Javascript
AngularJS基础 ng-model 指令详解及示例代码
2016/08/02 Javascript
jQuery中table数据的值拷贝和拆分
2017/03/19 Javascript
Angular将填入表单的数据渲染到表格的方法
2017/09/22 Javascript
Vue实现PopupWindow组件详解
2018/04/28 Javascript
NodeJS 文件夹拷贝以及删除功能
2019/09/03 NodeJs
使用layui+ajax实现简单的菜单权限管理及排序的方法
2019/09/10 Javascript
vue cli4下环境变量和模式示例详解
2020/04/09 Javascript
python执行get提交的方法
2015/04/29 Python
python绘制多个曲线的折线图
2020/03/23 Python
TensorFlow实现简单的CNN的方法
2019/07/18 Python
利用Pytorch实现简单的线性回归算法
2020/01/15 Python
2021年值得向Python开发者推荐的VS Code扩展插件
2021/01/25 Python
匡威英国官网:Converse英国
2018/12/02 全球购物
奥地利婴儿用品和玩具购物网站:baby-markt.at
2020/01/26 全球购物
毕业生找工作的自我评价
2013/10/18 职场文书
党员2014两会学习心得体会
2014/03/17 职场文书
幼儿园中班开学寄语
2014/04/03 职场文书
工会换届选举方案
2014/05/21 职场文书
汽车维修求职信
2014/06/15 职场文书
大学毕业生个人自荐书
2014/07/02 职场文书
公司离职证明标准样本
2014/10/05 职场文书
事业单位工作人员年度考核个人总结
2015/02/12 职场文书
2015年世界无烟日演讲稿
2015/03/18 职场文书
幼儿园辞职信
2015/05/13 职场文书
大学生如何逃脱“毕业季创业队即散伙”魔咒?
2019/08/19 职场文书
python 如何做一个识别率百分百的OCR
2021/05/29 Python
详细谈谈JavaScript中循环之间的差异
2021/08/23 Javascript
python单向链表实例详解
2022/05/25 Python
vue中data里面的数据相互使用方式
2022/06/05 Vue.js