def sorting(self): """Return fields to sort by including sort name for SQLAlchemy and row sort parameter for other ORMs :return list: a list of sorting information Example of return value:: [ {'field': 'created_at', 'order': 'desc'}, ] """ if self.qs.get("sort"): sorting_results = [] for sort_field in self.qs["sort"].split(","): field = sort_field.replace("-", "") if field not in self.schema._declared_fields: raise InvalidSort("{} has no attribute {}".format( self.schema.__name__, field)) if field in get_relationships(self.schema): raise InvalidSort( "You can't sort on {} because it is a relationship field" .format(field)) field = get_model_field(self.schema, field) order = "desc" if sort_field.startswith("-") else "asc" sorting_results.append({"field": field, "order": order}) return sorting_results return []
def eagerload_includes(self, query, qs): """Use eagerload feature of sqlalchemy to optimize data retrieval for include querystring parameter :param Query query: sqlalchemy queryset :param QueryStringManager qs: a querystring manager to retrieve information from url :return Query: the query with includes eagerloaded """ for include in qs.include: joinload_object = None if "." in include: current_schema = self.resource.schema for obj in include.split("."): try: field = get_model_field(current_schema, obj) except Exception as e: raise InvalidInclude(str(e)) if joinload_object is None: joinload_object = joinedload(field) else: joinload_object = joinload_object.joinedload(field) related_schema_cls = get_related_schema(current_schema, obj) if isinstance(related_schema_cls, SchemaABC): related_schema_cls = related_schema_cls.__class__ else: related_schema_cls = class_registry.get_class( related_schema_cls ) current_schema = related_schema_cls else: try: field = get_model_field(self.resource.schema, include) except Exception as e: raise InvalidInclude(str(e)) joinload_object = joinedload(field) query = query.options(joinload_object) return query
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 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 _get_relationship_data(self): """Get useful data for relationship management""" relationship_field = request.path.split("/")[-1].replace("-", "_") if relationship_field not in get_relationships(self.schema): raise RelationNotFound( "{} has no attribute {}".format( self.schema.__name__, relationship_field ) ) related_type_ = self.schema._declared_fields[relationship_field].type_ related_id_field = self.schema._declared_fields[relationship_field].id_field model_relationship_field = get_model_field(self.schema, relationship_field) return ( relationship_field, model_relationship_field, related_type_, related_id_field, )