flask-rest-jsonapi icon indicating copy to clipboard operation
flask-rest-jsonapi copied to clipboard

Could simple filters support lists of values?

Open tadams42 opened this issue 6 years ago • 0 comments
trafficstars

For example, we could have query strings looking like this:

?filter[foobar_id]=[1,2,3]

I'd implemented it in my app, but was thinking of maybe adding it to flask-rest-jsonapi? It looks like this:

class ResourceListMixin:
    _RE_IS_SIMPLE_FILTER = re.compile(r"^filter\[([A-Za-z_]+)\]$")
    _RE_IS_LIST_VALUE = re.compile(r"^\[(.+)\]$")

    def _transform_simple_filter(self, k, v):
        key_match = self._RE_IS_SIMPLE_FILTER.match(k)
        value_match = self._RE_IS_LIST_VALUE.match(v)

        if key_match and value_match:
            k = "filter"

            try:
                values = [int(_) for _ in value_match.groups()[0].split(",")]

            except ValueError:
                values = value_match.groups()[0].split(",")

            v = json.dumps([{"name": key_match.groups()[0], "op": "in", "val": values}])

        return k, v

    def get_collection(self, qs, kwargs):
        """
        Implements override for flask_rest_jsonapi.ResourceList that allows lists as
        values for simple filters, ie. following query strings are supported:
        ?filter[foobar_id]=[1,2,3]
        """

        request_args = ImmutableMultiDict(
            self._transform_simple_filter(k, v) for k, v in qs.qs.items(multi=True)
        )

        qs = QSManager(request_args, self.schema)

        return super().get_collection(qs, kwargs)

And I can use it like this:

def FoobarList(ResourceListMixin, ResourceList):
    # ...

Anyway, I can implement it directly in ResourceList and issue PR if you're interested...

tadams42 avatar May 22 '19 08:05 tadams42