Example #1
0
    def paginate_queryset(self, queryset, request, view=None):
        """Paginate a queryset if required, either returning a page object, or
        `None` if pagination is not configured for this view."""

        page_size = self.get_page_size(request)
        if not page_size:
            return None

        paginator = DjangoPaginator(queryset, page_size)
        page_number = request.query_params.get(self.page_query_param, 1)
        if page_number in self.last_page_strings:
            page_number = paginator.num_pages

        try:
            self.page = paginator.page(page_number)
            # we need to execute the query to resolve the page of objects
            self.page.object_list = self.page.object_list.execute()
        except InvalidPage as exc:
            msg = self.invalid_page_message.format(page_number=page_number,
                                                   message=six.text_type(exc))
            raise NotFound(msg)
        except Exception as exc:
            # This probably came from ES, so let's log it, and return and
            # empty response to the client.  This can happen when the indices
            # have not been created, or generally on any ES exception.
            logger.exception(exc)
            self.page.object_list = ESResponse({"hits": {"hits": []}})

        if paginator.count > 1 and self.template is not None:
            # The browsable API should display pagination controls.
            self.display_page_controls = True

        self.request = request
        return self.page.object_list
    def paginate_queryset(self, queryset, request, view=None):
        """
        Paginate a queryset if required, either returning a
        page object, or `None` if pagination is not configured for this view.
        """
        self._handle_backwards_compat(view)

        page_size = self.get_page_size(request)
        if not page_size:
            return None

        paginator = DjangoPaginator(queryset, page_size)
        page_number = request.query_params.get(self.page_query_param, 1)
        if page_number in self.last_page_strings:
            page_number = paginator.num_pages

        try:
            self.page = paginator.page(page_number)
        except InvalidPage as exc:
            msg = self.invalid_page_message.format(page_number=page_number,
                                                   message=six.text_type(exc))
            raise NotFound(msg)

        if paginator.count > 1 and self.template is not None:
            # The browsable API should display pagination controls.
            self.display_page_controls = True

        self.request = request
        return list(self.page)
Example #3
0
    def paginate_queryset(self, queryset, request, view=None):
        """
        Custom pagination of queryset. Returns page object or `None` if not configured for view.

        If this is an embedded resource, returns first page, ignoring query params.
        """
        if request.parser_context['kwargs'].get('is_embedded'):
            paginator = DjangoPaginator(queryset, self.page_size)
            page_number = 1
            try:
                self.page = paginator.page(page_number)
            except InvalidPage as exc:
                msg = self.invalid_page_message.format(
                    page_number=page_number, message=six.text_type(exc))
                raise NotFound(msg)

            if paginator.count > 1 and self.template is not None:
                # The browsable API should display pagination controls.
                self.display_page_controls = True

            self.request = request
            return list(self.page)

        else:
            return super(JSONAPIPagination, self).paginate_queryset(queryset,
                                                                    request,
                                                                    view=None)
Example #4
0
def paginate(request, queryset, per_page=20, count=None):
    """
    Get a Paginator, abstracting some common paging actions.

    If you pass ``count``, that value will be used instead of calling
    ``.count()`` on the queryset.  This can be good if the queryset would
    produce an expensive count query.
    """
    if isinstance(queryset, search.ES):
        paginator = ESPaginator(
            queryset, per_page, use_elasticsearch_dsl=False)
    else:
        paginator = DjangoPaginator(queryset, per_page)

    if count is not None:
        paginator.count = count

    # Get the page from the request, make sure it's an int.
    try:
        page = int(request.GET.get('page', 1))
    except ValueError:
        page = 1

    # Get a page of results, or the first page if there's a problem.
    try:
        paginated = paginator.page(page)
    except (EmptyPage, InvalidPage):
        paginated = paginator.page(1)

    paginated.url = u'%s?%s' % (request.path, request.GET.urlencode())
    return paginated
Example #5
0
    def paginate_queryset(self, queryset, request, view=None):
        """
        Paginate a queryset using unix timestamp query params.
        """
        self.page_size = self.get_page_size(request)

        before_query_param = request.query_params.get(self.before_field)
        after_query_param = request.query_params.get(self.after_field)
        if before_query_param and after_query_param:
            msg = _(
                "Using '%(before)s' and '%(after)s' query params together is not allowed"
            ) % {
                'before': self.before_field,
                'after': self.after_field
            }
            raise InvalidParameter('', msg)

        if before_query_param:
            try:
                filters = {
                    self.datetime_attribute + '__lt':
                    utcfromtimestamp(int(before_query_param) - 1)
                }
                queryset = queryset.filter(
                    **filters).order_by('-' + self.datetime_attribute)

            except (TypeError, ValueError):
                raise InvalidParameter(self.before_field,
                                       _("Should be a valid timestamp"))
        elif after_query_param:
            try:
                filters = {
                    self.datetime_attribute + '__gt':
                    utcfromtimestamp(int(after_query_param) + 1)
                }
                queryset = queryset.filter(**filters).order_by(
                    self.datetime_attribute)
            except (TypeError, ValueError):
                raise InvalidParameter(self.after_field,
                                       _("Should be a valid timestamp"))
        else:
            queryset = queryset.order_by('-' + self.datetime_attribute)

        paginator = DjangoPaginator(queryset, self.page_size)
        page_number = 1
        page = paginator.page(page_number)
        # reverse the messages order inside the page itself if needed, so the results are always sorted from oldest to newest.
        # in both cases the object_list queryset should be converted to a list to maintain consistency.
        if not after_query_param:
            page.object_list = list(page.object_list)[::-1]
        else:
            page.object_list = list(page.object_list)

        # explicitly reverse the order if required
        if self.recent_on_top:
            page.object_list = list(page.object_list)[::-1]

        self.page = page
        self.request = request
        return self.page
Example #6
0
    def paginate_queryset(self, queryset, request, view=None):
        """
        Custom pagination of queryset. Returns page object or `None` if not configured for view.

        If this is an embedded resource, returns first page, ignoring query params.
        """
        if request.parser_context['kwargs'].get('is_embedded'):
            # Pagination requires an order by clause, especially when using Postgres.
            # see: https://docs.djangoproject.com/en/1.10/topics/pagination/#required-arguments
            if isinstance(queryset, QuerySet) and not queryset.ordered:
                queryset = queryset.order_by(queryset.model._meta.pk.name)

            paginator = DjangoPaginator(queryset, self.page_size)
            page_number = 1
            try:
                self.page = paginator.page(page_number)
            except InvalidPage as exc:
                msg = self.invalid_page_message.format(
                    page_number=page_number, message=six.text_type(exc))
                raise NotFound(msg)

            if paginator.count > 1 and self.template is not None:
                # The browsable API should display pagination controls.
                self.display_page_controls = True

            self.request = request
            return list(self.page)

        else:
            return super(JSONAPIPagination, self).paginate_queryset(queryset,
                                                                    request,
                                                                    view=None)
Example #7
0
 def __init__(self, request, qs,  max_res):
     self.query_dict = dict(request.GET.items())
     self.paginator = DjangoPaginator(qs, int(self.query_dict.get('max') or max_res))
     self.path = request.path
     self.name = qs.model._meta.module_name
     page_num = int(request.REQUEST.get('page', 1))
     try:
         self.page = self.paginator.page(page_num)
     except InvalidPage:
         raise HttpError("Invalid page", status=http_status.HTTP_400_BAD_REQUEST)
Example #8
0
    def get_results(self, request, data, user=None, filters=None):
        """
        Please refer to the interface documentation.
        """
        # Check if items per page value was provided (default is 30)
        try:
            per_page = int(request.GET.get('per_page', 30))

            # Has to be bigger than 0!
            # TODO: Should raise exception?
            if per_page <= 0:
                per_page = 30
        # If invalid value, fallback to 30.
        # TODO: Should raise exception?
        except ValueError:
            per_page = 30

        # Fetch X items and paginate.
        paginator = DjangoPaginator(data, per_page)
        try:
            page = request.GET.get('page')
            result_page = paginator.page(page)
            page = int(page)
        # If page is not an integer, deliver first page.
        except PageNotAnInteger:
            page = 1
            result_page = paginator.page(page)
        # If page is out of range (e.g. 9999), deliver last page of results.
        except EmptyPage:
            page = paginator.num_pages
            result_page = paginator.page(page)

        # Build response.
        results = {
            'collection': self.serializer.serialize(result_page, user),
            'filters': {},
            'pagination': {
                'page': page,
                'per_page': per_page,
                'total_pages': paginator.num_pages,
                'total_items': len(data)
            }
        }

        # If the QuerySet was filtered and respective filters are provided, append them to response.
        if filters:
            results['filters'] = filters

        # Return.
        return results
Example #9
0
    def __init__(self, request, resource, response):
        self.query_dict = dict(request.GET.items())
        self.path = request.path

        try:
            per_page = resource._meta.dyn_prefix + 'max'
            self.paginator = DjangoPaginator(
                response,
                self.query_dict.get(per_page) or resource._meta.limit_per_page)

            if not self.paginator.per_page:
                self.paginator = None

        except (ValueError, AssertionError):
            self.paginator = None

        self._page = None
Example #10
0
def resolve_products(_parent, _info, page, per_page, sorters=None, filters=None):
    # type: (Any, Any, int, int, [Sorter], [Filter]) -> ProductsPage
    if not sorters:
        sorters = []

    if not filters:
        filters = []

    order_by_args = sorters_into_order_by_args(sorters)
    filter_args = filters_into_filter_args(filters)
    queryset = ProductModel.objects.order_by(*order_by_args).filter(filter_args)
    paginator = DjangoPaginator(queryset, per_page)

    try:
        return paginator.page(page)
    except PageNotAnInteger:
        return paginator.page(1)
    except EmptyPage:
        return paginator.page(paginator.num_pages)
Example #11
0
    def paginate_queryset(self, queryset):
        pnp = PageNumberPagination
        page_size = self.request.GET.get('page_size')
        if page_size is None:
            page_size = pnp.page_size
        page_size = int(page_size)
        if page_size < 0 or page_size == 0:
            page_size = pnp.page_size
        if page_size > 1000:
            page_size = 1000

        pnp.request = self.request
        paginator = DjangoPaginator(queryset, page_size)
        page_number = self.request.GET.get('page')
        if page_number is None:
            page_number = 1

        try:
            pnp.page = paginator.page(page_number)
        except InvalidPage:
            return list()

        return list(pnp.page)