def get_skip_and_limit(self, params=None):
        if params is None:
            params = self.params
        if self.paginate:
            # _limit and _skip validation
            if not isint(params.get("_limit", 1)):
                raise ValidationError({"error": '_limit must be an integer (got "%s" instead).' % params["_limit"]})
            if not isint(params.get("_skip", 1)):
                raise ValidationError({"error": '_skip must be an integer (got "%s" instead).' % params["_skip"]})
            if params.get("_limit") and int(params["_limit"]) > self.max_limit:
                raise ValidationError(
                    {
                        "error": "The limit you set is larger than the maximum limit for this resource (max_limit = %d)."
                        % self.max_limit
                    }
                )
            if params.get("_skip") and int(params["_skip"]) < 0:
                raise ValidationError(
                    {"error": '_skip must be a non-negative integer (got "%s" instead).' % params["_skip"]}
                )

            limit = min(int(params.get("_limit", self.default_limit)), self.max_limit)
            # Fetch one more so we know if there are more results.
            return int(params.get("_skip", 0)), limit
        else:
            return 0, self.max_limit
Example #2
0
    def get_skip_and_limit(self, params=None):
        if params is None:
            params = request.args
        if self.paginate:
            # _limit and _skip validation
            if not isint(params.get('_limit', 1)):
                raise ValidationError({
                    'error':
                    '_limit must be an integer (got "%s" instead).' %
                    params['_limit']
                })
            if not isint(params.get('_skip', 1)):
                raise ValidationError({
                    'error':
                    '_skip must be an integer (got "%s" instead).' %
                    params['_skip']
                })
            if params.get('_limit') and int(params['_limit']) > self.max_limit:
                raise ValidationError({
                    'error':
                    "The limit you set is larger than the maximum limit for this resource (max_limit = %d)."
                    % self.max_limit
                })

            limit = min(int(params.get('_limit', self.default_limit)),
                        self.max_limit)
            # Fetch one more so we know if there are more results.
            return int(params.get('_skip', 0)), limit
        else:
            return 0, self.max_limit
Example #3
0
    def get_skip_and_limit(self, params=None):
        if params is None:
            params = request.args
        if self.paginate:
            # _limit and _skip validation
            if not isint(params.get('_limit', 1)):
                raise ValidationError({'error': '_limit must be an integer (got "%s" instead).' % params['_limit']})
            if not isint(params.get('_skip', 1)):
                raise ValidationError({'error': '_skip must be an integer (got "%s" instead).' % params['_skip']})
            if params.get('_limit') and int(params['_limit']) > self.max_limit:
                raise ValidationError({'error': "The limit you set is larger than the maximum limit for this resource (max_limit = %d)." % self.max_limit})

            limit = min(int(params.get('_limit', self.default_limit)), self.max_limit)
            # Fetch one more so we know if there are more results.
            return int(params.get('_skip', 0)), limit
        else:
            return 0, self.max_limit
Example #4
0
    def get_skip_and_limit(self, params=None):
        """
        Perform validation and return sanitized values for _skip and _limit
        params of the request that's currently being processed.
        """
        max_limit = self.get_max_limit()
        if params is None:
            params = self.params
        if self.paginate:
            # _limit and _skip validation
            if not isint(params.get('_limit', 1)):
                raise ValidationError({'error': '_limit must be an integer (got "%s" instead).' % params['_limit']})
            if not isint(params.get('_skip', 1)):
                raise ValidationError({'error': '_skip must be an integer (got "%s" instead).' % params['_skip']})
            if params.get('_limit') and int(params['_limit']) > max_limit:
                raise ValidationError({'error': "The limit you set is larger than the maximum limit for this resource (max_limit = %d)." % max_limit})
            if params.get('_skip') and int(params['_skip']) < 0:
                raise ValidationError({'error': '_skip must be a non-negative integer (got "%s" instead).' % params['_skip']})

            limit = min(int(params.get('_limit', self.default_limit)), max_limit)
            # Fetch one more so we know if there are more results.
            return int(params.get('_skip', 0)), limit
        else:
            return 0, max_limit
Example #5
0
    def get_objects(self, all=False, qs=None, qfilter=None):
        params = request.args
        custom_qs = True
        if qs is None:
            custom_qs = False
            qs = self.get_queryset()
        # If a queryset filter was provided, pass our current
        # queryset in and get a new one out
        if qfilter:
            qs = qfilter(qs)
        for key, value in params.iteritems():
            # If this is a resource identified by a URI, we need
            # to extract the object id at this point since
            # MongoEngine only understands the object id
            if self.uri_prefix:
                url = urlparse(value)
                uri = url.path
                value = uri.lstrip(self.uri_prefix)
            negate = False
            op_name = ''
            parts = key.split('__')
            for i in range(len(parts) + 1, 0, -1):
                field = '__'.join(parts[:i])
                allowed_operators = self._filters.get(field)
                if allowed_operators:
                    parts = parts[i:]
                    break
            if allowed_operators is None:
                continue

            if parts:
                # either an operator or a query lookup!  See what's allowed.
                op_name = parts[-1]
                if op_name in allowed_operators:
                    # operator; drop it
                    parts.pop()
                else:
                    # assume it's part of a lookup
                    op_name = ''
                if parts and parts[-1] == 'not':
                    negate = True
                    parts.pop()

            operator = allowed_operators.get(op_name, None)
            if operator is None:
                continue
            if parts:
                field = '%s__%s' % (field, '__'.join(parts))
            field = self._reverse_rename_fields.get(field, field)
            qs = operator().apply(qs, field, value, negate)
        limit = None
        if self.allowed_ordering and params.get('_order_by') in self.allowed_ordering:
            qs = qs.order_by(*params['_order_by'].split(','))

        if not custom_qs and not all:
            if self.paginate:

                # _limit and _skip validation
                if not isint(params.get('_limit', 1)):
                    raise ValidationError({'error': '_limit must be an integer (got "%s" instead).' % params['_limit']})
                if not isint(params.get('_skip', 1)):
                    raise ValidationError({'error': '_skip must be an integer (got "%s" instead).' % params['_skip']})
                if params.get('_limit') and int(params['_limit']) > self.max_limit:
                    raise ValidationError({'error': "The limit you set is larger than the maximum limit for this resource (max_limit = %d)." % self.max_limit})

                limit = min(int(params.get('_limit', 100)), self.max_limit)+1
                # Fetch one more so we know if there are more results.
                qs = qs.skip(int(params.get('_skip', 0))).limit(limit)
            else:
                qs = qs.limit(self.max_limit+1)

        # Needs to be at the end as it returns a list.
        if self.select_related:
            qs = qs.select_related()

        if limit:
            # It is OK to evaluate the queryset as we will do so anyway.
            qs = [o for o in qs] # don't use list() because mongoengine will do a count query
            has_more = len(qs) == limit
            if has_more:
                qs = qs[:-1]
        else:
            has_more = None

        # bulk-fetch related resources for moar speed
        if self.related_resources_hints:
            if params and '_fields' in params:
                only_fields = set(params['_fields'].split(','))
            else:
                only_fields = None
            self.fetch_related_resources(qs, only_fields)

        return qs, has_more
Example #6
0
    def get_objects(self, all=False, qs=None, qfilter=None):
        params = request.args
        custom_qs = True
        if qs is None:
            custom_qs = False
            qs = self.get_queryset()
        # If a queryset filter was provided, pass our current
        # queryset in and get a new one out
        if qfilter:
            qs = qfilter(qs)
        for key, value in params.iteritems():
            # If this is a resource identified by a URI, we need
            # to extract the object id at this point since
            # MongoEngine only understands the object id
            if self.uri_prefix:
                url = urlparse(value)
                uri = url.path
                value = uri.lstrip(self.uri_prefix)
            negate = False
            op_name = ''
            parts = key.split('__')
            for i in range(len(parts) + 1, 0, -1):
                field = '__'.join(parts[:i])
                allowed_operators = self._filters.get(field)
                if allowed_operators:
                    parts = parts[i:]
                    break
            if allowed_operators is None:
                continue

            if parts:
                # either an operator or a query lookup!  See what's allowed.
                op_name = parts[-1]
                if op_name in allowed_operators:
                    # operator; drop it
                    parts.pop()
                else:
                    # assume it's part of a lookup
                    op_name = ''
                if parts and parts[-1] == 'not':
                    negate = True
                    parts.pop()

            operator = allowed_operators.get(op_name, None)
            if operator is None:
                continue
            if parts:
                field = '%s__%s' % (field, '__'.join(parts))
            field = self._reverse_rename_fields.get(field, field)
            qs = operator().apply(qs, field, value, negate)
        limit = None
        if self.allowed_ordering and params.get(
                '_order_by', '').strip('-') in self.allowed_ordering:
            qs = qs.order_by(*params['_order_by'].split(','))

        if not custom_qs and not all:
            if self.paginate:

                # _limit and _skip validation
                if not isint(params.get('_limit', 1)):
                    raise ValidationError({
                        'error':
                        '_limit must be an integer (got "%s" instead).' %
                        params['_limit']
                    })
                if not isint(params.get('_skip', 1)):
                    raise ValidationError({
                        'error':
                        '_skip must be an integer (got "%s" instead).' %
                        params['_skip']
                    })
                if params.get('_limit') and int(
                        params['_limit']) > self.max_limit:
                    raise ValidationError({
                        'error':
                        "The limit you set is larger than the maximum limit for this resource (max_limit = %d)."
                        % self.max_limit
                    })

                limit = min(int(params.get('_limit', 100)), self.max_limit) + 1
                # Fetch one more so we know if there are more results.
                qs = qs.skip(int(params.get('_skip', 0))).limit(limit)
            else:
                qs = qs.limit(self.max_limit + 1)

        # Needs to be at the end as it returns a list.
        if self.select_related:
            qs = qs.select_related()

        if limit:
            # It is OK to evaluate the queryset as we will do so anyway.
            qs = [
                o for o in qs
            ]  # don't use list() because mongoengine will do a count query
            has_more = len(qs) == limit
            if has_more:
                qs = qs[:-1]
        else:
            has_more = None

        # bulk-fetch related resources for moar speed
        if self.related_resources_hints:
            if params and '_fields' in params:
                only_fields = set(params['_fields'].split(','))
            else:
                only_fields = None
            self.fetch_related_resources(qs, only_fields)

        return qs, has_more