SoFunction
Updated on 2024-10-30

Examples of finding, filtering, and sorting data in the django rest framework

For management systems , often need to show the list of data , we often need to find the list of data , filtering , sorting and other operations , which find most of the operations are carried out in the background . django rest framework can be easily implemented to find the data , filtering and other operations . Next we will introduce the actual example.

Example code github address:/jinjidejuren/drf_learn

The cmdb system, for example, as an asset management system often needs to filter or look up data to get the desired information.

Implementing the model

1. In this sample project, you need to implement conditional filtering on physical servers, the list of physical server mods is as follows (apps/assets/file):.

class Server():
  """
  Physical servers
  """
  status_choice = (
    ('online', 'Going live'),
    ('offline', 'Down the line'),
    ('normal', 'Normal'),
    ('abnormal', 'Anomalies')
  )

  server_name = (verbose_name=u'Server name', max_length=128, blank=False, null=False)
  server_num = (verbose_name=u'Server number', max_length=128, blank=True, null=True)
  brand = (verbose_name=u'Brand', max_length=64, blank=True, null=True)
  model = (verbose_name=u'Model', max_length=64, blank=True, null=True)
  cpus = (verbose_name=u'cpu cores', default=0)
  ram = (verbose_name=u'Memory size', default=0)
  disk = (verbose_name=u'Disk size', default=0)
  product_date = (verbose_name=u'Date of manufacture', auto_now_add=True)
  status = (verbose_name=u'Status', max_length=16, choices=status_choice)

  created_time = (verbose_name=u'Creation time', auto_now_add=True)
  modified_time = (verbose_name=u'Modify time', auto_now_add=True)

  class Meta:
    verbose_name = u'Server'
    verbose_name_plural = verbose_name

  def __str__(self):
    return self.server_name

Implementing the serializer

Next you need to implement the serialization class for the model server, write in apps/assets/:.

class ServiceSerializer():
  """
  Server Serialization
  """

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

For fields, you can use _ all _ to represent all fields, in addition to the fields defined in the model, serialization can also specify other information, such as nested information or custom information. The details can depend on the business logic.

Implementing modelviewset

For modelviewset, we can do appropriate processing of user requests around it. The common ones are adding, deleting, finding, modifying, etc. to the model. In this part we need to implement ServerViewSet:

class ServerViewSet():
  """
  Physical Server View
  """
  queryset = ().order_by('-created_time')
  serializer_class = ServerSerializer
  pagination_class = MyFormatResultsSetPagination

queryset specifies the form of the return list, all the information is returned, and according to the creation time of the reverse order, so that the latest information can be returned first, more in line with the user's operating habits.

serializer_class defines the returned serialization format as the contents of the fields specified by ServerSerializer.

pagination_class specifies the type of pagination, this MyFormatResultsSetPagination is our custom type

Implementing a router

If the user wants to access the information of the server, he needs to specify the route of the server, which is similar to the one described before. This is similar to what was described before. What is needed is to create a router object and register the server's route with it.

from rest_framework import routers

router = ()
(r'servers', , base_name='servers')

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

Access to servers is handled by the ServerViewSet.

Trying to access

http://127.0.0.1:8060/assets/v1/servers/ with the following information:

Note: We need to add sample information to be used as a follow-up for various tests.

Access by condition

In daily operation, we need to get the data with specified conditions, for example, for physical servers, we need to specify the brand, specify the number of cpu cores, specify the memory size, etc. Sometimes we need to sort by the number of cpu cores. Sometimes we need to sort by cpu cores. All these need us to expand ServerViewSet more.

If you do conditional filtering, you need to install the django-filter module first:

pip install django-filter

Add the application django_filters to the configuration file settings/:

INSTALLED_APPS = [
  # '',
  '',
  '',
  '',
  '',
  '',
  'rest_framework',
  'django_filters',
  '',
  ''
]

Include the following package at the top of apps/assets/:

from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import filters
from django_filters import rest_framework

ServerViewSet can add the appropriate filter conditions:

class ServerViewSet():
  """
  Physical Server View
  """
  queryset = ()
  serializer_class = ServerSerializer
  pagination_class = MyFormatResultsSetPagination
  filter_backends = (rest_framework.DjangoFilterBackend, , , )
  filter_class = ServerFilter
  search_fields = ('server_name', '=brand', 'status', )
  ordering_fields = ('cpus', 'ram', 'disk', 'product_date', )
  ordering = ('-created_time', )

Here filter_backends specifies the type of filtering, here DjangoFilterBackend (filtering), SearchFilter (searching) and OrderingFIlter (sorting) are set.

1. Filtering

Filtering sets the configuration class for filtering to ServerFilter, about which is defined in the apps/assets/ file:

import django_filters

from .models import *


class ServerFilter(django_filters.rest_framework.FilterSet):
  """
  Physical Server Filters
  """

  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', ]

This means that the information about the physical server can be filtered by 'server_name', 'brand', 'cpus', 'ram', 'disk' to get the corresponding serialized list.

For example get physical servers with a cpu of 24 cores:

Getting the list of physical servers with cpu's all 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

To search, you need to specify the information to be queried by the search keyword, for example, to search for servers with names starting with 'test':

http://127.0.0.1:8060/assets/v1/servers/?search=test

Get the list:

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
}

Multiple lookup methods can be specified in search_fields:

'^name' starts with name.

'=name' Exact match

‘@' Global search (only supported by mysql data source)

'$' Regular Match

An example of the corresponding search_fileds is shown below:

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

3. Sorting

The default sorting is specified in the ORDERING field (reverse chronological order by creation time):

ordering = ('-created_time', )

It can also be specified using the following:

queryset = ().order_by('-created_time')

To customize the ordering field, you need to specify the contents of the ordering field:

For example, arranging servers by memory size:

http://127.0.0.1:8060/assets/v1/servers/?ordering=ram

The list of information obtained is given below:

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
}

The above operations such as sorting and filtering can be used in combination and generally provide interface support for front-end list search queries.

wrap-up

The content of this chapter summary describes how the django rest framework for the definition of the model, serialization, add, delete, change and search, sorting and other functions, is to write the back-end interface must master the skills.

This is the whole content of this article.