agateblue / lifter

A generic query engine, inspired by Django ORM
ISC License
449 stars 16 forks source link

Any plans to support querystrings / Allow queries to be serialized from other formats #36

Open Hellowlol opened 8 years ago

Hellowlol commented 8 years ago

I was thinking about using with a webservice, it would be nice to do ?key=title, product, qty&orderby=title and simple pass this lifter ^^

agateblue commented 8 years ago

Indeed, there is no built-in way to achieve this at the moment. It's achievable though, with a little plumbering.

Let's say you have the following querystring:

# We want to get blog entries from a querystring where author == John and title == something, 
# ordered by publication_date DESC
querystring = 'author=John&title=something&order_by=-publication_date'

# We parse the querystring to get a proper dictionary
# such as {'author': ['John'], 'title': ['something'], 'order_by': ['-publication_date']}

import urllib.parse # python3
query_dict =  urllib.parse.parse_qs(querystring)

# We remove ordering from the dict
ordering = query_dict.pop('order_by')

# since urllib.parse group values in a list, we, flatten that
filters = {key: values[0] for key, values in query_dict.items()}

# We pass the whole thing to lifter thanks to unpacking
results = manager.filter(**filters).order_by(*ordering)

This is one of the use case where the keyword-engine works nice ;)

However, even if my previous address your issue, there is probably some work to do here

Basically, we need some way to parse queries (from querystring, SQL or whatever) and load them directly into lifter.

The API could look like:

from lifter.parsers import QueryStringParser

full_query = QueryStringParser().parse(querystring)
results = manager.load_query(full_query)

Under the hood, a parser would return proper data to feed the lifter manager and return results. It would translate filter, exclude, ordering, values, limit and all other Queryset statements to something lifter can interpret.

This is definitely on my todo list !

Hellowlol commented 8 years ago

Awesome, I started on making a parser to support the many ways to get multiple values. I'll stick to that until a proper parser is added to lifter. Thanks!

agateblue commented 8 years ago

Glad it helped, I'll keep this issue updated as soon as I start working on this.

Hellowlol commented 8 years ago

Dunno if order matter by my idea is to

"filter=cake<=1&orderby=price&exlude=chocolate"

The key would be a call to the method and the value is the stuff you do placed in a ordereddict (is order matters)

agateblue commented 8 years ago

Hm if you want to do both exclude and filter using the querystring, it will probably be more difficult to implement than my example, and a real parser should be written instead. Unfortunately, I cannot promise a deliver date for this, sorry ;)