def _build_mapped_item(cls, field, field_orm_route, **kwargs): lookups = kwargs.get('lookups') use_repr = kwargs.get('use_repr') null_values = kwargs.get('null_values') distinct = kwargs.get('distinct') openapi = kwargs.get('openapi') hidden = kwargs.get('hidden') possible_lookups = lookups or FilterTypes.default_field_filter_lookups( field) if not (field.null or cls._is_pk_field(field)): possible_lookups.discard(FilterLookups.NULL) result = { 'field': field, 'orm_route': field_orm_route, 'lookups': possible_lookups, 'null_values': null_values or {RQL_NULL}, 'distinct': distinct or False, 'hidden': hidden or False, } if use_repr is not None: result['use_repr'] = use_repr if openapi is not None: result['openapi'] = openapi return result
def _get_schema_for_field(cls, filter_item, filter_instance): result = {} if filter_item['oa']['type']: result = {'type': filter_item['oa']['type']} if filter_item['oa']['format']: result['format'] = filter_item['oa']['format'] if not result and ('field' not in filter_item): return {'type': 'string'} field = filter_item['field'] if not result: field_type_oa_type_mapper = { FilterTypes.STRING: { 'type': 'string' }, FilterTypes.INT: { 'type': 'integer' }, FilterTypes.DECIMAL: { 'type': 'number', 'format': 'double' }, FilterTypes.FLOAT: { 'type': 'number', 'format': 'float' }, FilterTypes.DATETIME: { 'type': 'string', 'format': 'date-time' }, FilterTypes.DATE: { 'type': 'string', 'format': 'date' }, FilterTypes.BOOLEAN: { 'type': 'boolean' }, } result = field_type_oa_type_mapper[FilterTypes.field_filter_type( field)] choices = getattr(field, 'choices', None) if choices: if type(choices).__name__ == 'Choices' or isinstance( choices[0], tuple): use_repr = filter_item.get('use_repr', False) enum = [choice[int(use_repr)] for choice in choices] else: enum = list(choices) result['enum'] = enum if isinstance(enum[0], Number): result['type'] = 'integer' else: result['type'] = 'string' return result
def _convert_value(cls, django_field, str_value, use_repr=False): val = cls.remove_quotes(str_value) filter_type = FilterTypes.field_filter_type(django_field) if filter_type == FilterTypes.FLOAT: return float(val) elif filter_type == FilterTypes.DECIMAL: return round(float(val), django_field.decimal_places) elif filter_type == FilterTypes.DATE: dt = parse_date(val) if dt is None: raise ValueError return dt elif filter_type == FilterTypes.DATETIME: dt = parse_datetime(val) if dt is None: dt = parse_date(val) if dt is None: raise ValueError return datetime(year=dt.year, month=dt.month, day=dt.day) return dt elif filter_type == FilterTypes.BOOLEAN: if val not in (RQL_FALSE, RQL_TRUE): raise ValueError return val == RQL_TRUE if val == RQL_EMPTY: if (filter_type == FilterTypes.INT) or (not django_field.blank): raise ValueError return '' choices = getattr(django_field, 'choices', None) if not choices: if filter_type == FilterTypes.INT: return int(val) return val return cls._get_choices_field_db_value(val, choices, filter_type, use_repr)
def get_rql_query(cls, filter_instance, request, query_string): filter_value_pairs = [] for filter_name in request.query_params.keys(): if cls._is_select_in_filter(filter_name): filter_value_pairs.append(filter_name) continue one_filter_value_pairs = [] for value in request.query_params.getlist(filter_name): if not value: continue if filter_name in (RQL_LIMIT_PARAM, RQL_OFFSET_PARAM): one_filter_value_pairs.append('{}={}'.format( filter_name, value)) continue if filter_name in cls.RESERVED_ORDERING_WORDS: one_filter_value_pairs.append('{}({})'.format( RQL_ORDERING_OPERATOR, value)) continue f_item = filter_instance.get_filter_base_item(filter_name) if f_item and (not f_item.get('custom', False)): if FilterTypes.field_filter_type( f_item['field']) == FilterTypes.BOOLEAN: value = cls._convert_bool_value(value) if not cls._is_old_style_filter(filter_name): one_filter_value_pairs.append( '{}={}'.format(filter_name, cls._add_quotes_to_value(value)), ) else: one_filter_value_pairs.append( cls._convert_filter_to_rql(filter_name, value), ) if one_filter_value_pairs: filter_value_pairs.append('&'.join(one_filter_value_pairs)) return '&'.join(filter_value_pairs) if filter_value_pairs else ''
def _check_search(filter_item, filter_name, field): is_non_string_field_type = FilterTypes.field_filter_type( field) != FilterTypes.STRING assert not (filter_item.get('search') and is_non_string_field_type), \ "{}: 'search' can be applied only to text filters.".format(filter_name)