示例#1
0
        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)
示例#2
0
        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)