侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

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

框架(架构)  /  管理员 发布于 7年前   156

对于管理系统,常常需要展示列表数据,我们对于列表内的数据常常需要查找、过滤、排序等操作,其中查找等操作大部分是在后台进行的。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 routersrouter = 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/ ,信息如下:

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

按照条件获取

在日常操作中,我们需要获取指定条件的数据,例如对于物理服务器,我们需要指定品牌、指定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 DjangoFilterBackendfrom rest_framework import filtersfrom 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_filtersfrom .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核的物理服务器:

得到物理服务器列表中cpu都为24:

GET /assets/v1/servers/?server_name=&brand=&cpus=24&ram=&disk=HTTP 200 OKAllow: GET, POST, HEAD, OPTIONSContent-Type: application/jsonVary: 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 OKAllow: GET, POST, HEAD, OPTIONSContent-Type: application/jsonVary: 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 OKAllow: GET, POST, HEAD, OPTIONSContent-Type: application/jsonVary: 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的定义、序列化、增删改查以及搜索、排序等功能,是书写后端接口必须掌握的技巧。

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


  • 上一条:
    详解Django+Uwsgi+Nginx的生产环境部署
    下一条:
    Django实现分页功能
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • Filament v3.1版本发布(0个评论)
    • docker + gitea搭建一个git服务器流程步骤(0个评论)
    • websocket的三种架构方式使用优缺点浅析(0个评论)
    • ubuntu20.4系统中宿主机安装nginx服务,docker容器中安装php8.2实现运行laravel10框架网站(0个评论)
    • phpstudy_pro(小皮面板)中安装最新php8.2.9版本流程步骤(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2018-05
    • 2020-02
    • 2020-03
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-08
    • 2020-11
    • 2021-03
    • 2021-09
    • 2021-10
    • 2021-11
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-08
    • 2023-08
    • 2023-10
    • 2023-12
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客