Example #1
0
    def apply_sorting(self, obj_list, options=None):
        if options is None:
            options = {}

        if 'order_by' not in options:
            return obj_list

        order_by = options.getlist('order_by')
        order_by_args = []
        for field in order_by:
            if field.startswith('-'):
                order = '-'
                field_name = field[1:]
            else:
                order = ''
                field_name = field

            # Map the field back to the actual attribute
            if not field_name in self.fields:
                raise InvalidSortError(
                    "No matching '%s' field for ordering on." % field_name)

            if not field_name in self._meta.ordering:
                raise InvalidSortError(
                    "The '%s' field does not allow ordering." % field_name)

            if self.fields[field_name].attribute is None:
                raise InvalidSortError(
                    "The '%s' field has no 'attribute' for ordering with." %
                    field_name)

            order_by_args.append("%s%s" %
                                 (order, self.fields[field_name].attribute))

        return obj_list.order_by(*order_by_args)
Example #2
0
    def apply_sorting(self, obj_list, options=None):
        if options is None:
            options = {}

        field_name = options.get('order_by', '-date')

        reverse = False
        if field_name[0] == '-':
            reverse = True
            field_name = field_name[1:]

        if field_name not in self.fields:
            raise InvalidSortError("No matching '%s' field for ordering on." %
                                   field_name)

        if field_name not in self._meta.ordering:
            raise InvalidSortError("The '%s' field does not allow ordering." %
                                   field_name)

        if self.fields[field_name].attribute is None:
            raise InvalidSortError(
                "The '%s' field has no 'attribute' for ordering with." %
                field_name)

        return sorted(obj_list,
                      key=lambda k: k[self.fields[field_name].attribute],
                      reverse=reverse)
Example #3
0
    def apply_sort(self, obj_list, sort_expr):
        field_name = sort_expr[1:] if sort_expr.startswith('-') else sort_expr

        if not field_name in self.fields:
            raise InvalidSortError("No matching '%s' field for ordering on." %
                                   field_name)

        if not field_name in self._meta.ordering:
            InvalidSortError("The '%s' field does not allow ordering." %
                             field_name)

        return obj_list.order_by(sort_expr)
Example #4
0
    def apply_sorting(self, obj_list, options=None):
        if options is None:
            options = {}

        if not 'order_by' in options:
            return obj_list

        order_by_args = []

        parameter_name = 'order_by'

        if hasattr(options, 'getlist'):
            order_bits = options.getlist(parameter_name)
        else:
            order_bits = options.get(parameter_name)

            if not isinstance(order_bits, (list, tuple)):
                order_bits = [order_bits]

        for order_by in order_bits:
            order_by_bits = order_by.split(LOOKUP_SEP)

            field_name = order_by_bits[0]
            order = '%s'
            order_by_name = order_by

            if order_by_bits[0].startswith('-'):
                field_name = order_by_bits[0][1:]
                order = 'orm.desc(%s)'
                order_by_name = order_by_name[1:]

            if not field_name in self.fields:
                # It's not a field we know about. Move along citizen.
                raise InvalidSortError("No matching '%s' field for ordering on." % field_name)

            if not order_by_name in self._meta.ordering:
                raise InvalidSortError("The resourse doesn't allow ordering by '%s'." % order_by_name)

            if self.fields[field_name].attribute is None:
                raise InvalidSortError("The '%s' field has no 'attribute' for ordering with." % field_name)

            order_by_args.append(order % ('.'.join(['o',self.fields[field_name].attribute] + order_by_bits[1:])))

        return obj_list.order_by(', '.join(order_by_args))
Example #5
0
    def get_order_by(self, **kwargs):
        size = int(kwargs.get('size', settings.ES_MAX_RESULTS))
        if ("search" in kwargs) or (size == 0):
            return []

        order_by_request = kwargs.get('order_by', [])
        if isinstance(order_by_request, str):
            order_by_request = [order_by_request]

        order_by = []
        for fieldname in order_by_request:
            if not isinstance(fieldname, str):
                continue

            order_by_bits = fieldname.split(LOOKUP_SEP)
            name = order_by_bits[0]
            order = {"order": "asc"}
            if order_by_bits[0].startswith('-'):
                name = order_by_bits[0][1:]
                order = {"order": "desc"}

            if name not in self._meta.ordering:
                raise InvalidSortError(
                    "The '%s' field does not allow ordering." % name
                    )

            # Add .keyword to string fields.
            if name in ES_KEYWORDS:
                name = '{}.keyword'.format(name)
            order_by.append({name: order})

        # `search` param defines sorting order:
        # - if search term is present, sort only by _score (relevant
        #   tweets at the top)
        # - otherwise add timestamp to the end of list (will be default
        #   if sort isn't specified)
        order_keys = flatten_list([x.keys() for x in order_by])
        if settings.ES_TIMESTAMP_FIELD not in order_keys:
            order_by.append({
                settings.ES_TIMESTAMP_FIELD: {"order": "desc"}
                })
        return order_by
Example #6
0
    def apply_sorting(self, obj_list, options=None):
        try:
            if not 'order_by' in options:
                return obj_list
            if hasattr(options, 'getlist'):
                order_bits = options.getlist('order_by')
            else:
                order_bits = options.get('order_by')
                if not isinstance(order_bits, (list, tuple)):
                    order_bits = [order_bits]

            order_bits = [b for o in order_bits for b in o.split(',')]

            order_by_args = []
            for order_by in order_bits:
                order = ''
                if order_by.startswith('-'):
                    order = '-'
                    order_by = order_by[1:]
                order_by = self.check_field_access(order_by.replace('.', '__'))
                order_by_args.append("%s%s" % (order, order_by))
            return obj_list.order_by(*order_by_args).distinct()
        except Exception, ex:
            raise InvalidSortError('%s' % ex)
    def apply_sorting(self, obj_list, similarity_map, options=None):
        """
        Given a dictionary of options, apply some ORM-level sorting to the
        provided ``QuerySet``.

        Looks for the ``order_by`` key and handles either ascending (just the
        field name) or descending (the field name with a ``-`` in front).

        The field name should be the resource field, **NOT** model field.
        """
        if options is None:
            options = {}

        parameter_name = 'order_by'

        if 'order_by' not in options:
            if 'sort_by' not in options:
                # Nothing to alter the order. Return what we've got.
                options['order_by'] = '-similarity'
            else:
                warnings.warn(
                    "'sort_by' is a deprecated parameter. Please use 'order_by' instead."
                )
                parameter_name = 'sort_by'

        order_by_args = []

        if hasattr(options, 'getlist'):
            order_bits = options.getlist(parameter_name)
        else:
            order_bits = options.get(parameter_name)

            if not isinstance(order_bits, (list, tuple)):
                order_bits = [order_bits]

        if (order_bits.index('similarity') == 0 if 'similarity' in order_bits else False) or \
                (order_bits.index('-similarity') == 0 if '-similarity' in order_bits else False):
            obj_list = self.prefetch_related(obj_list, **options)
            for obj in obj_list:
                sim = similarity_map[obj.molregno]
                obj.similarity = sim
                similarity_map[obj.molregno] = obj
            vals = [
                sim for sim in similarity_map.values()
                if type(sim) == MoleculeDictionary
            ]
            return list(
                reversed(vals)) if '-similarity' in order_bits else vals

        else:

            for order_by in order_bits:
                order_by_bits = order_by.split(LOOKUP_SEP)

                field_name = order_by_bits[0]
                order = ''

                if order_by_bits[0].startswith('-'):
                    field_name = order_by_bits[0][1:]
                    order = '-'

                if field_name not in self.fields:
                    # It's not a field we know about. Move along citizen.
                    raise InvalidSortError(
                        "No matching '%s' field for ordering on." % field_name)

                if field_name not in self._meta.ordering:
                    raise InvalidSortError(
                        "The '%s' field does not allow ordering." % field_name)

                if self.fields[field_name].attribute is None:
                    raise InvalidSortError(
                        "The '%s' field has no 'attribute' for ordering with."
                        % field_name)

                order_by_args.append(
                    "%s%s" %
                    (order,
                     LOOKUP_SEP.join([self.fields[field_name].attribute] +
                                     order_by_bits[1:])))

            obj_list = self.prefetch_related(obj_list.order_by(*order_by_args),
                                             **options)
            for obj in obj_list:
                obj.similarity = similarity_map[obj.molregno]
            return obj_list