Exemple #1
0
    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 []
Exemple #2
0
    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
Exemple #3
0
    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_
Exemple #4
0
    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)
            )
Exemple #5
0
    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,
        )