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将人民币转换大写的脚本代码
Feb 10 Python
Python实现删除文件中含“指定内容”的行示例
Jun 09 Python
python skimage 连通性区域检测方法
Jun 21 Python
Python实现将通信达.day文件读取为DataFrame
Dec 22 Python
python爬虫获取百度首页内容教学
Dec 23 Python
Python字符串的一些操作方法总结
Jun 10 Python
Python使用requests xpath 并开启多线程爬取西刺代理ip实例
Mar 06 Python
Python tornado上传文件的功能
Mar 26 Python
keras实现多GPU或指定GPU的使用介绍
Jun 17 Python
Python识别验证码的实现示例
Sep 30 Python
Python图像识别+KNN求解数独的实现
Nov 13 Python
OpenCV灰度化之后图片为绿色的解决
Dec 01 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
discuz 首页四格:最新话题+最新回复+热门话题+精华文章插件
2007/08/19 PHP
PHP中的排序函数sort、asort、rsort、krsort、ksort区别分析
2014/08/18 PHP
destoon实现调用当前栏目分类及子分类和三级分类的方法
2014/08/21 PHP
PHP邮件发送类PHPMailer用法实例详解
2014/09/22 PHP
ThinkPHP处理Ajax返回的方法
2014/11/22 PHP
Laravel实现构造函数自动依赖注入的方法
2016/03/16 PHP
PHP递归遍历指定文件夹内的文件实现方法
2016/11/15 PHP
phpstudy2018升级MySQL5.5为5.7教程(图文)
2018/10/24 PHP
jQuery 图片切换插件(代码比较少)
2012/05/07 Javascript
一个js过滤空格的小函数
2014/10/10 Javascript
javascript中setTimeout和setInterval的unref()和ref()用法示例
2014/11/26 Javascript
jQuery实现的网页左侧在线客服效果代码
2015/10/23 Javascript
基于jquery实现页面滚动时顶部导航显示隐藏
2020/04/20 Javascript
JavaScript中用let语句声明作用域的用法讲解
2016/05/20 Javascript
浅谈JS的基础类型与引用类型
2016/09/13 Javascript
JavaScript数据结构之链表的实现
2017/03/19 Javascript
jQuery 添加样式属性的优先级别方法(推荐)
2017/06/08 jQuery
Vue+Element使用富文本编辑器的示例代码
2017/08/14 Javascript
使用node.js对音视频文件加密的实例代码
2017/08/30 Javascript
JS 实现百度搜索功能
2018/02/01 Javascript
vue中如何实现后台管理系统的权限控制的方法示例
2018/09/19 Javascript
记一次vue去除#问题处理经过小结
2019/01/24 Javascript
JavaScript ES6常用基础知识总结
2019/02/09 Javascript
vue穿梭框实现上下移动
2021/01/29 Vue.js
Php多进程实现代码
2018/05/07 Python
使用Python读取二进制文件的实例讲解
2018/07/09 Python
keras得到每层的系数方式
2020/06/15 Python
Python命名空间及作用域原理实例解析
2020/08/12 Python
css3新单位vw、vh的使用教程
2018/03/23 HTML / CSS
集世界奢侈品和设计师品牌的意大利精品买手店:Tessabit
2019/08/17 全球购物
一套中级Java程序员笔试题
2015/01/14 面试题
财务管理专业毕业生求职信范文
2013/09/21 职场文书
团支书的期末学习总结自我评价
2013/11/01 职场文书
甲方资料员岗位职责
2013/12/13 职场文书
霸王洗发水广告词
2014/03/14 职场文书
Redis分布式锁的7种实现
2022/04/01 Redis