def query_objects(cls, filter_data, valid_only=True, initial_query=None): """\ Returns a QuerySet object for querying the given model_class with the given filter_data. Optional special arguments in filter_data include: -query_start: index of first return to return -query_limit: maximum number of results to return -sort_by: list of fields to sort on. prefixing a '-' onto a field name changes the sort to descending order. -extra_args: keyword args to pass to query.extra() (see Django DB layer documentation) -extra_where: extra WHERE clause to append """ filter_data = dict(filter_data) # copy so we don't mutate the original query_start = filter_data.pop("query_start", None) query_limit = filter_data.pop("query_limit", None) if query_start and not query_limit: raise ValueError("Cannot pass query_start without " "query_limit") sort_by = filter_data.pop("sort_by", None) extra_args = filter_data.pop("extra_args", {}) extra_where = filter_data.pop("extra_where", None) if extra_where: # escape %'s extra_where = cls.objects.escape_user_sql(extra_where) extra_args.setdefault("where", []).append(extra_where) use_distinct = not filter_data.pop("no_distinct", False) if initial_query is None: if valid_only: initial_query = cls.get_valid_manager() else: initial_query = cls.objects query = initial_query.filter(**filter_data) if use_distinct: query = query.distinct() # other arguments if extra_args: query = query.extra(**extra_args) query = query._clone(klass=ReadonlyQuerySet) # sorting + paging if sort_by: assert isinstance(sort_by, list) or isinstance(sort_by, tuple) query = query.order_by(*sort_by) if query_start is not None and query_limit is not None: query_limit += query_start return query[query_start:query_limit]
def query_objects(cls, filter_data, valid_only=True, initial_query=None, apply_presentation=True): """ Returns a QuerySet object for querying the given model_class with the given filter_data. Optional special arguments in filter_data include: -query_start: index of first return to return -query_limit: maximum number of results to return -sort_by: list of fields to sort on. prefixing a '-' onto a field name changes the sort to descending order. -extra_args: keyword args to pass to query.extra() (see Django DB layer documentation) -extra_where: extra WHERE clause to append -no_distinct: if True, a DISTINCT will not be added to the SELECT """ special_params, regular_filters = cls._extract_special_params( filter_data) if initial_query is None: if valid_only: initial_query = cls.get_valid_manager() else: initial_query = cls.objects query = initial_query.filter(**regular_filters) use_distinct = not special_params.get('no_distinct', False) if use_distinct: query = query.distinct() extra_args = special_params.get('extra_args', {}) extra_where = special_params.get('extra_where', None) if extra_where: # escape %'s extra_where = cls.objects.escape_user_sql(extra_where) extra_args.setdefault('where', []).append(extra_where) if extra_args: query = query.extra(**extra_args) query = query._clone(klass=ReadonlyQuerySet) if apply_presentation: query = cls.apply_presentation(query, filter_data) return query
def apply_presentation(cls, query, filter_data): """ Apply presentation parameters -- sorting and paging -- to the given query. :return: new query with presentation applied """ special_params, _ = cls._extract_special_params(filter_data) sort_by = special_params.get('sort_by', None) if sort_by: assert isinstance(sort_by, list) or isinstance(sort_by, tuple) query = query.extra(order_by=sort_by) query_start = special_params.get('query_start', None) query_limit = special_params.get('query_limit', None) if query_start is not None: if query_limit is None: raise ValueError('Cannot pass query_start without query_limit') # query_limit is passed as a page size query_limit += query_start return query[query_start:query_limit]