Python Optimized List Interface for Paging Sample Implementation

  • 2021-12-04 19:13:32
  • OfStack

Directory Paging Destination Interface Design Interface Interpretation CaseService.get_case_list Method CaseService.get_count Method

Purpose of paging

Let's assume that there are 1W pieces of data added to the use case library. If you want to show them in the form of a list, return 1W pieces of data once;

This has two drawbacks:

1. The interface written in this way will be slow. Think about what should I do if this number becomes 10W and 100W with the development of time?

2. Unfriendly to the front end. Render 1W pieces of data with the front end, which would not be done by rational development.

Therefore, the purpose of paging is mainly to improve performance and experience.

My side of the development language is Python, Web framework is Tornado, the background database is Mongodb.

Interface design

First of all, we do the design of the interface as follows:


HTTP URL: /api/admin/v1/case/list
HTTP Method: GET
Request Params
Reponse Data
{
    "code": 0,
    "message": null,
    "data": {
        "cases": [
            {
                "method": str,
                "url": str,
                "request_data"?: str,
                "request_params"?: str,
                "header": dict,
                "reponse_data"?: str
            },
            ...
        ],
        "count": int
    }
}

Returns data structure parsing:

The value of cases is a list containing multiple case objects; count refers to the total number of case, so that the front end can judge how many pages there are in 1 through count, and then directly request the data of the corresponding page for display through the number of pages clicked, which can effectively control the amount of data returned and the return time, and improve the user experience.

According to the above interface convention, the interface implementation is as follows (only the key code is shown):


class CaseList(APIHandler):
    async def get_handler(self):
        page = self.input.page or 1
        limit = self.input.limit or 12
        page, limit = int(page), int(limit)
        skip = limit * (page - 1)
        return {
            'customers': await CaseService.get_case_list(filter_={}, skip=skip, limit=limit),
            'count': await CaseService.get_count(filter_={})
        }

Interface interpretation

Let's read this interface line by line.

1. According to the API convention, page and limit do not need to be transmitted and have default values, so they can be directly written as self. input. page or 1, where self. input. page is None when page is not transmitted.

2. The request parameter of GET request obtained by the back end is String, so int () needs to be converted into integer type. Here, int (page) can be directly used, because after the previous processing, page must have a value.

3. Calculate how many are skipped by limit * (page-1); The function of skip described in vernacular is to start with the first skip object, take the next limit and return.

4. The value of the filter_ parameter of the get_case_list method and the get_count method should be kept at 1, because they both operate on the case object, except that count is a total.

CaseService.get_case_list method


async def get_case_list(filter_: dict, skip: int = None, limit: int = None) -> Optional[List[dict]]:
    """  Get  case  List  """
        sort = [('create_time', -1)]
    if skip is not None and limit is not None:
        ret = await cls.find('case', filter=filter_, sort=sort, limit=limit, skip=skip)
    else:
        ret = await cls.find('case', filter=filter_, sort=sort)
    return ret

1. To judge the null value of skip and limit, use is not None, because skip may be, and if if skip is used to judge, skip = 0 will also enter the branch.

2. The incoming of sort = [('create_time',-1)] causes the returned list to be arranged flashback according to the creation time. If you don't do this, I believe the test classmates in charge will ask you a "usability question".

3. sort + skip + limit have execution priority, and their priority is sort → skip → limit, and the priority of skip + limit is skip → limit.

Here, we should not consider whether sort, skip and limit will be automatically executed according to the priority when pymogo is executed. When transmitting parameters, it is good to transmit parameters according to the priority, so as to develop good habits and not worry about others.

CaseService.get_count method


async def get_count(cls, filter_: dict) -> int:
    """  Get  case  Total  """
    return await ModelHandler.count('case', filter=filter_)

Here use count to get data, you can get the total directly, instead of taking out list and then seeking length, avoiding the waste of memory space.

The above is the whole process of paging the list interface. Thank you for reading. This is not a feeding tutorial. It takes you familiar with the whole process of writing this interface and its details. The specific implementation needs everyone to practice.

The above is the Python optimization list interface for paging sample implementation details, more information about Python optimization please pay attention to other related articles on this site!


Related articles: