Filtering

Flask-jsonapi supports resource filtering. [specification]

Note:

All results of examples are filters parameter passed to read_many method of ResourceList or get_list method of ResourceRepositoryViewSet.

Simple Usage

Let’d define a simple filter schema with one filter:

class ExampleFiltersSchema(filters_schema.FilterSchema):
    title = filters_schema.FilterField()

Now use it in ResourceList or ResourceRepositoryViewSet:

class ExampleListView(resources.ResourceList):
    schema = ExampleSchema()
    filter_schema = ExampleFiltersSchema()

Request:

/example-resource?filter[title]=something

Will result in:

{'title': 'something'}

List of filter values

To parse many values fo single filter use ListFilterField:

class ExampleFiltersSchema(filters_schema.FilterSchema):
    title = filters_schema.ListFilterField()

Request:

/example-resource?filter[title]=something,other

Will result in:

{'title': ['something', 'other']}

Parsing filter values

By default filter values are parsed as strings. To change it, pass a desired subclass of marshmallow.fields.Field as type_ argument to field constructor:

[reference]

class ExampleFiltersSchema(filters_schema.FilterSchema):
    title = filters_schema.FilterField(type_=fields.Float)

Request:

/example-resource?filter[score]=4.5

Will result in:

{'score': 4.5}

Overriding filter attribute

You can override the key with witch the filter will be parsed with attribute parameter:

class ExampleFiltersSchema(filters_schema.FilterSchema):
    title = filters_schema.FilterField(attribute='renamed')

Request:

/example-resource?filter[title]=something

Will result in:

{'renamed': 'something}

Using Operators

The base JSONAPI specification is agnostic about filtering strategies supported by a server, Flask-JsonApi added a support for operators.

Note:

List of supported operators is available [here]

Note:

Filters with operators can be automatically applied to query using sqlalchemy_repositories.SqlAlchemyModelRepository. This is achieved using [sqlalchemy-django-query]

Defining a set of allowed operators:

class ExampleFiltersSchema(filters_schema.FilterSchema):
    title = filters_schema.FilterField(operators=['eq', 'ne'])

Request:

/example-resource?filter[title][ne]=something

Will result in:

{'title__ne': 'something}

Note:

You can also specify a default operator (when none are provided in query string) with default_operator parameter.

Marshmallow-Jsonapi Schema integration

Filters can be autogenerated using supplied schema.

Let’s define a schema:

class ExampleSchema(marshmallow_jsonapi.Schema):
    id = fields.UUID(required=True)
    body = fields.Str()
    is_active = fields.Boolean()

    class Meta:
        type_ = 'example'

Let’s define a filters schema that uses this schema:

class ExampleFiltersSchema(filters_schema.FilterSchema):
    class Meta:
        schema = ExampleSchema
        fields = ['id', 'body', 'is_active']

Now you can filter by the fields specified in class Meta:

Request:

/example-resource?filter[is-active]=True

Will result in:

{'is_active': True}

Relationship filtering

Relationships within resources can be also used in filtering.

Let’s define two related filter schemas:

class FirstFiltersSchema(filters_schema.FilterSchema):
    attribute = filters_schema.FilterField()

class SecondFiltersSchema(filters_schema.FilterSchema):
    relationship = filters_schema.RelationshipFilterField(SecondFiltersSchema)

Request:

/second-resource?filter[relationship][attribute]=something

Will result in:

{'relationship__attribute': 'something}

Relationship filters can be automatically applied to query using sqlalchemy_repositories.SqlAlchemyModelRepository. This is achieved using [sqlalchemy-django-query]