def apply_fields(cls, query_set, _fields): """ Apply fields' restrictions to `query_set`. First, fields are split to fields that should only be included and fields that should be excluded. Then excluded fields are removed from included fields. """ fields_only, fields_exclude = process_fields(_fields) if not (fields_only or fields_exclude): return query_set try: fields_only = fields_only or cls.native_fields() fields_exclude = fields_exclude or [] if fields_exclude: # Remove fields_exclude from fields_only fields_only = [ f for f in fields_only if f not in fields_exclude ] if fields_only: # Add PK field fields_only.append(cls.pk_field()) fields_only = [ getattr(cls, f) for f in sorted(set(fields_only)) ] query_set = query_set.with_entities(*fields_only) except InvalidRequestError as e: raise JHTTPBadRequest('Bad _fields param: %s ' % e) return query_set
def apply_fields(cls, query_set, _fields): """ Apply fields' restrictions to `query_set`. First, fields are split to fields that should only be included and fields that should be excluded. Then excluded fields are removed from included fields. """ fields_only, fields_exclude = process_fields(_fields) if not (fields_only or fields_exclude): return query_set try: fields_only = fields_only or cls.native_fields() fields_exclude = fields_exclude or [] if fields_exclude: # Remove fields_exclude from fields_only fields_only = [ f for f in fields_only if f not in fields_exclude] if fields_only: # Add PK field fields_only.append(cls.pk_field()) fields_only = [ getattr(cls, f) for f in sorted(set(fields_only))] query_set = query_set.with_entities(*fields_only) except InvalidRequestError as e: raise JHTTPBadRequest('Bad _fields param: %s ' % e) return query_set
def apply_fields(cls, query_set, _fields): fields_only, fields_exclude = process_fields(_fields) try: if fields_only: query_set = query_set.only(*fields_only) if fields_exclude: query_set = query_set.exclude(*fields_exclude) except mongo.InvalidQueryError as e: raise JHTTPBadRequest('Bad _fields param: %s ' % e) return query_set
def get_collection(cls, _count=False, _strict=True, _sort=None, _fields=None, _limit=None, _page=None, _start=None, _query_set=None, _item_request=False, _explain=None, _search_fields=None, q=None, **params): """ Query collection and return results. Notes: * Before validating that only model fields are present in params, reserved params, query params and all params starting with double underscore are dropped. * Params which have value "_all" are dropped. * When ``_count`` param is used, objects count is returned before applying offset and limit. :param bool _strict: If True ``params`` are validated to contain only fields defined on model, exception is raised if invalid fields are present. When False - invalid fields are dropped. Defaults to ``True``. :param list _sort: Field names to sort results by. If field name is prefixed with "-" it is used for "descending" sorting. Otherwise "ascending" sorting is performed by that field. Defaults to an empty list in which case sorting is not performed. :param list _fields: Names of fields which should be included or excluded from results. Fields to excluded should be prefixed with "-". Defaults to an empty list in which case all fields are returned. :param int _limit: Number of results per page. Defaults to None in which case all results are returned. :param int _page: Number of page. In conjunction with ``_limit`` is used to calculate results offset. Defaults to None in which case it is ignored. Params ``_page`` and ``_start` are mutually exclusive. :param int _start: Results offset. If provided ``_limit`` and ``_page`` params are ignored when calculating offset. Defaults to None. Params ``_page`` and ``_start`` are mutually exclusive. If not offset-related params are provided, offset equals to 0. :param Query _query_set: Existing queryset. If provided, all queries are applied to it instead of creating new queryset. Defaults to None. :param bool _item_request: Indicates whether it is a single item request or not. When True and DataError happens on DB request, JHTTPNotFound is raised. JHTTPBadRequest is raised when False. Defaults to ``False``. :param _count: When provided, only results number is returned as integer. :param _explain: When provided, query performed(SQL) is returned as a string instead of query results. :param bool _raise_on_empty: When True JHTTPNotFound is raised if query returned no results. Defaults to False in which case error is just logged and empty query results are returned. :param q: Query string to perform full-text search with. :param _search_fields: Coma-separated list of field names to use with full-text search(q param) to limit fields which are searched. :returns: Query results as ``elasticsearch_dsl.XXX`` instance. May be sorted, offset, limited. :returns: Dict of {'field_name': fieldval}, when ``_fields`` param is provided. :returns: Number of query results as an int when ``_count`` param is provided. :raises JHTTPNotFound: When ``_raise_on_empty=True`` and no results found. :raises JHTTPNotFound: When ``_item_request=True`` and ``sqlalchemy.exc.DataError`` exception is raised during DB query. Latter exception is raised when querying DB with an identifier of a wrong type. E.g. when querying Int field with a string. :raises JHTTPBadRequest: When ``_item_request=False`` and ``sqlalchemy.exc.DataError`` exception is raised during DB query. :raises JHTTPBadRequest: When ``sqlalchemy.exc.InvalidRequestError`` or ``sqlalchemy.exc.IntegrityError`` errors happen during DB query. """ # see if the items are cached pk_field = cls.pk_field() if (list(params.keys()) == [pk_field] and _count==False and _strict==True and _sort==None and _fields==None and _limit==None and _page==None and _start==None and _query_set==None and _item_request==False and _explain==None and _search_fields==None and q==None): ids = params[pk_field] if not isinstance(ids, (list, tuple)): ids = [ids] results = [] for id in ids: if not id in cls._cache: break results.append(cls._cache[id]) else: return results search_obj = cls.search() if _limit is not None: _start, limit = process_limit(_start, _page, _limit) search_obj = search_obj.extra(from_=_start, size=limit) if _fields: include, exclude = process_fields(_fields) if _strict: _validate_fields(cls, include + exclude) # XXX partial fields support isn't yet released. for now # we just use fields, later we'll add support for excluded fields search_obj = search_obj.fields(include) if params: params = _cleaned_query_params(cls, params, _strict) params = _restructure_params(cls, params) if params: search_obj = search_obj.filter('terms', **params) if q is not None: query_kw = {'query': q} if _search_fields is not None: query_kw['fields'] = _search_fields.split(',') search_obj = search_obj.query('query_string', **query_kw) if _count: return search_obj.count() if _explain: return search_obj.to_dict() if _sort: sort_fields = split_strip(_sort) if _strict: _validate_fields( cls, [f[1:] if f.startswith('-') else f for f in sort_fields] ) search_obj = search_obj.sort(*sort_fields) hits = search_obj.execute().hits hits._nefertari_meta = dict( total=hits.total, start=_start, fields=_fields ) return hits