def new_function(*args, **kwargs): """ Wrapped function """ request = _find_request(args) # 1. Pre-loading request data sort = request.QUERY_PARAMS.get('sort') if sort is None and default_sort is not None: sort = default_sort sort = None if sort is None else [s for s in reversed(sort.split(','))] page = request.QUERY_PARAMS.get('page') page = int(page) if page is not None and page.isdigit() else None page_size = request.QUERY_PARAMS.get('page_size') page_size = int(page_size) if page_size is not None and page_size.isdigit() else None page_size = page_size if page_size in [10, 25, 50, 100] else 10 contents = request.QUERY_PARAMS.get('contents') contents = None if contents is None else contents.split(',') # 2. Construct hints for decorated function (so it can provide full objects if required) if 'hints' not in kwargs: kwargs['hints'] = {} kwargs['hints']['full'] = sort is not None or contents is not None # 3. Fetch data data_list = f(*args, **kwargs) guid_list = isinstance(data_list, list) and len(data_list) > 0 and isinstance(data_list[0], basestring) # 4. Sorting if sort is not None: if guid_list is True: data_list = [object_type(guid) for guid in data_list] guid_list = False # The list is converted to objects for sort_item in sort: desc = sort_item[0] == '-' field = sort_item[1 if desc else 0:] data_list.sort(key=lambda e: Toolbox.extract_key(e, field), reverse=desc) # 5. Paging total_items = len(data_list) page_metadata = {'total_items': total_items, 'current_page': 1, 'max_page': 1, 'page_size': page_size, 'start_number': min(1, total_items), 'end_number': total_items} if page is not None: max_page = int(math.ceil(total_items / (page_size * 1.0))) if page > max_page: page = max_page if page == 0: start_number = -1 end_number = 0 else: start_number = (page - 1) * page_size # Index - e.g. 0 for page 1, 10 for page 2 end_number = start_number + page_size # Index - e.g. 10 for page 1, 20 for page 2 data_list = data_list[start_number: end_number] page_metadata = dict(page_metadata.items() + {'current_page': max(1, page), 'max_page': max(1, max_page), 'start_number': start_number + 1, 'end_number': min(total_items, end_number)}.items()) # 6. Serializing if contents is not None: if guid_list is True: data_list = [object_type(guid) for guid in data_list] data = FullSerializer(object_type, contents=contents, instance=data_list, many=True).data else: if guid_list is False: data_list = [item.guid for item in data_list] data = data_list result = {'data': data, '_paging': page_metadata, '_contents': contents, '_sorting': [s for s in reversed(sort)] if sort else sort} # 7. Building response return Response(result, status=status.HTTP_200_OK)
def new_function(self, request, *args, **kwargs): """ Wrapped function """ _ = self # 1. Pre-loading request data sort = request.QUERY_PARAMS.get('sort') if sort is None and default_sort is not None: sort = default_sort sort = None if sort is None else [ s for s in reversed(sort.split(',')) ] page = request.QUERY_PARAMS.get('page') page = int(page) if page is not None and page.isdigit() else None contents = request.QUERY_PARAMS.get('contents') contents = None if contents is None else contents.split(',') # 2. Construct hints for decorated function (so it can provide full objects if required) if 'hints' not in kwargs: kwargs['hints'] = {} kwargs['hints']['full'] = sort is not None or contents is not None # 3. Fetch data data_list = f(self, request=request, *args, **kwargs) guid_list = isinstance(data_list, list) and len(data_list) > 0 and isinstance( data_list[0], basestring) # 4. Sorting if sort is not None: if guid_list is True: data_list = [object_type(guid) for guid in data_list] guid_list = False # The list is converted to objects for sort_item in sort: desc = sort_item[0] == '-' field = sort_item[1 if desc else 0:] data_list.sort(key=lambda e: Toolbox.extract_key(e, field), reverse=desc) # 5. Paging items_pp = 10 total_items = len(data_list) page_metadata = { 'total_items': total_items, 'current_page': 1, 'max_page': 1, 'start_number': min(1, total_items), 'end_number': total_items } if page is not None: max_page = int(math.ceil(total_items / (items_pp * 1.0))) if page > max_page: page = max_page if page == 0: start_number = -1 end_number = 0 else: start_number = ( page - 1 ) * items_pp # Index - e.g. 0 for page 1, 10 for page 2 end_number = start_number + items_pp # Index - e.g. 10 for page 1, 20 for page 2 data_list = data_list[start_number:end_number] page_metadata = dict( page_metadata.items() + { 'current_page': max(1, page), 'max_page': max(1, max_page), 'start_number': start_number + 1, 'end_number': min(total_items, end_number) }.items()) # 6. Serializing if contents is not None: if guid_list is True: data_list = [object_type(guid) for guid in data_list] data = FullSerializer(object_type, contents=contents, instance=data_list, many=True).data else: if guid_list is False: data_list = [item.guid for item in data_list] data = data_list result = { 'data': data, '_paging': page_metadata, '_contents': contents, '_sorting': [s for s in reversed(sort)] if sort else sort } # 7. Building response return Response(result, status=status.HTTP_200_OK)