Amit P
Amit P

Reputation: 944

Passing the JSON params as kwargs in Python

I have some post data of the format

d = {
    "filters": [
        {
            "type": "range",
            "question__created_at": "2014-11-10T11:11:55.027Z",
            "exclude_filter": False,

        },
        {
            "type": "terms",
            "question_name": ["AB","CD"]
            "exclude_filter": False,

        }
    ],
    "count": True
}

What I am trying to achieve here is the I pick the value of the every filter type from the key "type" of each filter dictionary. And I send the rest of all the fields as kwargs and that will directly be passed to the query that I am appending these filters.

So here is the query that will be appended based on the the number of filters I pass:

s = Search(using=es).index(settings.ES_INDEX).doc_type(model)

This is the default elasticsearch that is like a match all query on my db.

When I pass the above filter(JSON) and in this case when I have 2 filters passed , below is what my modified query should look like:

s = Search(using=es).index(settings.ES_INDEX).doc_type(model)

s = s.filter(
    F('range', question__created_at="2014-11-10T11:11:55.027Z", exclude_filter=True) &
    F('terms', question_name=["AB","CD"], exclude_filter=True))

So, depending on any number of filters passed it should dynamically go on to append them with the "s" object

Can anyone help on how I can write a function in python that picks up the filter type separate and rest of it as kwargs so that I can unpack everything directly to the query?

Upvotes: 1

Views: 5378

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1123400

You can dynamically build multiple filters by extracting the type key from the dictionary, and applying the remainder to the F() filter object. S.filter() returns an updated search, so just keep applying the next filter to the object in a loop:

for filter in d['filters']:
    type_ = filter.pop('type')
    s = s.filter(type_, **filter)

Upvotes: 2

Related Questions