def column(self): """Get the column object :param DeclarativeMeta model: the model :param str field: the field :return InstrumentedAttribute: the column to filter on """ field = self.name model_field = get_model_field(self.schema, field) try: attr = getattr(self.model, model_field) except AttributeError: raise InvalidFilters("{} has no attribute {}".format( self.model.__name__, model_field)) name = self.filter_.get('name') if '[' in name: if not isinstance(attr.type, Indexable): raise InvalidFilters( "{} is not an indexable column".format(model_field)) name = name[name.index('['):] while name.startswith('['): item, name = name[1:].split(']', 1) try: item = json.loads(item) except json.decoder.JSONDecodeError: raise InvalidFilters( "{} is not a valid index".format(item)) try: attr = attr[item] except Exception: raise InvalidFilters( "{} is not a valid indexing expression".format( self.filter_.get('name'))) if name == ".as_string()": attr = attr.as_string() elif name == ".as_integer()": attr = attr.as_integer() elif name == ".as_float()": attr = attr.as_float() elif name == ".as_boolean()": attr = attr.as_boolean() elif len(name) > 0: raise InvalidFilters( "{} is not a valid indexing expression".format( self.filter_.get('name'))) return attr
def resolve(self): if 'or' not in self.filter_ and 'and' not in self.filter_: if self.val is None and self.field is None: raise InvalidFilters("Can't find value or field in a filter") value = self.value if isinstance(self.val, dict): value = Node(self.related_model, self.val, self.opts, self.related_schema).resolve() if '__' in self.filter_.get('name', ''): value = self.value value = {self.filter_['name'].split('__')[1]: value} if isinstance(value, dict): return getattr(self.column, self.operator)(**value) else: return getattr(self.column, self.operator)(value) if 'or' in self.filter_: return or_(Node(self.model, filt, self.opts, self.schema).resolve() for filt in self.filter_['or']) if 'and' in self.filter_: return and_(Node(self.model, filt, self.opts, self.schema).resolve() for filt in self.filter_['and']) if 'not' in self.filter_: return not_(Node(self.model, self.filter_['not'], self.opts, self.schema).resolve())
def name(self): """Return the name of the node or raise a BadRequest exception :return str: the name of the field to filter on """ name = self.filter_.get('name') if name is None: raise InvalidFilters("Can't find name of a filter") if '__' in name: name = name.split('__')[0] if name not in self.schema._declared_fields: raise InvalidFilters("{} has no attribut {}".format(self.schema.__name__, name)) return name
def op(self): """Return the operator of the node :return str: the operator to use in the filter """ try: return self.filter_['op'] except KeyError: raise InvalidFilters("Can't find op of a filter")
def value(self): """Get the value to filter on :return: the value to filter on """ if self.filter_.get('field') is not None: try: result = getattr(self.model, self.filter_['field']) except AttributeError: raise InvalidFilters("{} has no attribute {}".format( self.model.__name__, self.filter_['field'])) else: return result else: if 'val' not in self.filter_: raise InvalidFilters("Can't find value or field in a filter") return self.filter_['val']
def related_schema(self): """Get the related schema of a relationship field :return Schema: the related schema """ relationship_field = self.name if relationship_field not in get_relationships(self.schema): raise InvalidFilters("{} has no relationship attribut {}".format(self.schema.__name__, relationship_field)) return self.schema._declared_fields[relationship_field].schema.__class__
def value(self): """Get the value to filter on :return: the value to filter on """ if self.field is not None: try: return getattr(self.model, self.field) except AttributeError: raise InvalidFilters("{} has no attribute {} in a filter".format(self.model.__name__, self.field)) return self.val
def operator(self): """Get the function operator from his name :return callable: a callable to make operation on a column """ operators = (self.op, self.op + '_', '__' + self.op + '__') for op in operators: if hasattr(self.column, op): return op raise InvalidFilters("{} has no operator {} in a filter".format(self.column.key, self.op))
def filters(self): """Return filters from query string. :return list: filter information """ filters = self.qs.get('filter') if filters is not None: try: filters = json.loads(filters) except (ValueError, TypeError): raise InvalidFilters("Parse error") return filters
def related_model(self): """Get the related model of a relationship field :return DeclarativeMeta: the related model """ relationship_field = self.name if relationship_field not in get_relationships(self.schema): raise InvalidFilters("{} has no relationship attribut {}".format(self.schema.__name__, relationship_field)) if hasattr(self.opts, 'schema_to_model') and self.opts.schema_to_model.get(relationship_field) is not None: relationship_field = self.opts.schema_to_model[relationship_field] return getattr(self.model, relationship_field).property.mapper.class_
def filters(self): """Return filters from query string. :return list: filter information """ results = [] filters = self.qs.get('filter') if filters is not None: try: results.extend(json.loads(filters)) except (ValueError, TypeError): raise InvalidFilters("Parse error") if self._get_key_values('filter['): results.extend(self._simple_filters(self._get_key_values('filter['))) return results
def related_model(self): """Get the related model of a relationship field :return DeclarativeMeta: the related model """ relationship_field = self.name if relationship_field not in get_relationships(self.schema): raise InvalidFilters("{} has no relationship attribute {}".format( self.schema.__name__, relationship_field)) return getattr(self.model, get_model_field( self.schema, relationship_field)).property.mapper.class_
def related_schema(self): """Get the related schema of a related (relationship or nested) field :return Schema: the related schema """ related_field_name = self.name related_fields = get_relationships(self.schema) + get_nested_fields( self.schema) if related_field_name not in related_fields: raise InvalidFilters( "{} has no relationship or nested attribute {}".format( self.schema.__name__, related_field_name)) return self.schema._declared_fields[ related_field_name].schema.__class__
def column(self): """Get the column object :param DeclarativeMeta model: the model :param str field: the field :return InstrumentedAttribute: the column to filter on """ field = self.name model_field = get_model_field(self.schema, field) try: return getattr(self.model, model_field) except AttributeError: raise InvalidFilters("{} has no attribute {}".format( self.model.__name__, model_field))
def column(self): """Get the column object :param DeclarativeMeta model: the model :param str field: the field :return InstrumentedAttribute: the column to filter on """ field = self.name if self.schema._declared_fields[field].attribute is not None: field = self.schema._declared_fields[field].attribute try: return getattr(self.model, field) except AttributeError: raise InvalidFilters("{} has no attribute {} in a filter".format(self.model.__name__, field))
def related_model(self): """Get the related model of a related (relationship or nested) field :return DeclarativeMeta: the related model """ related_field_name = self.name related_fields = get_relationships(self.schema) + get_nested_fields( self.schema) if related_field_name not in related_fields: raise InvalidFilters( "{} has no relationship or nested attribute {}".format( self.schema.__name__, related_field_name)) return getattr(self.model, get_model_field( self.schema, related_field_name)).property.mapper.class_