philipn / django-rest-framework-filters

Better filtering for Django REST Framework

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to encode complex query string

rpkilby opened this issue · comments

Moving #312 (comment) to a new issue:

Hey, sorry if this is a little off topic but I am looking at using the complex backend and I am a little confused. So do i need to write the code to parse the query string and encode it or is there a library you are using to do that? Also where do I do that at? Is there some example code I can look at?

So do i need to write the code to parse the query string and encode it

Hi @patrickcash. The encoding/decoding process is something I made up - I'm not working off of an existing standard or anything. So, as far as I'm aware there's no library to help you with this. You will need to write the query encoder yourself.

Is there some example code I can look at?

I don't have a tested example, but I threw together the example below. It could definitely be cleaned up and made more robust, but should get you most of the way there.

// represent: (a=1&b=2) & (c=3) | ~(d=4)
const query = [
    {params: {a: 1, b: 2}, op: '&', negate: false},
    {params: {c: 3}, op: '|', negate: false},
    {params: {d: 4}, op: null, negate: true},  // only last query should have no op
]


let qs = '';
for (const inner of query) {
    // todo: could assert that op most only be null for last element

    // convert inner params to URL-encoded query string
    const innerqs = (new URLSearchParams(inner.params)).toString();
    const op = inner.op ? ` ${inner.op} ` : ''; // spacing is for readability
    const neg = inner.negate ? '~' : '';

    // append inner. e.g., '~(foo=bar) & '
    qs = `${qs}${neg}(${innerqs})${op}`;
}

// final URL encoding
qs = (new URLSearchParams({filters: qs})).toString();

Which results in:

"filters=%28a%3D1%26b%3D2%29+%26+%28c%3D3%29+%7C+%7E%28d%3D4%29"