Cześć, ponownie przychodzę z pytaniem o Flaska, a może bardziej o to jak rozwiązać filtrowanie wyników z bazy danych na podstawie query string. Chodzi mi o endpointy jak poniżej wraz z operatorami gt, lt, gte, lte (operatorów jeszcze nie mam):
/api/users
zwraca JSON z wszystkimi użytkownikami
/api/users?name=John
zwraca JSON z użytkownikami o imieniu John
/api/users?name=John&age=40
zwraca JSON z użytkownikami o imieniu John i wieku 40
/api/users?age=40&country=Poland&city=Warsaw
zwraca JSON z użytkownikami w wieku 40, kraju Poland, miasta Warsaw
/api/users?age[gt]=40
zwraca JSON z użytkownikami w wieku większym od 40
/api/users?page=1&limit=5
paginacja zwracanych danych
Robię API we flask_restful + mongoengine, które zaproponowano w innym wątku i mam coś w tym stylu:
class UsersApi(Resource):
def get(self):
try:
page = 1
limit = 10
skip = (page - 1) * limit
# query string
name = request.args.get('name')
# more...
if request.args is not None:
filters = {}
if 'page' in request.args and 'limit' in request.args:
page = int(request.args.get('page'))
limit = int(request.args.get('limit'))
skip = (page - 1) * limit
if 'name' in request.args:
filters['name'] = name
# more URL parameters...
users_query = User.objects(**filters).skip(skip).limit(limit)
users = users_query.to_json()
return Response(users, mimetype='application/json', status=200)
except Exception:
raise InternalServerError
Po kolei sprawdzam w request.args
czy istnieje dany klucz, jeśli tak wtedy dodaję wartość parametru URL do słownika. Na końcu słownik filtrów jest przekazywany do metody User.objects()
i robię rozpakowanie słownika. Jako tako wydaje się, że działa lecz nie wiem czy idę w dobrym kierunku :P
Zależy mi na filtrowania jak w endpointach powyżej, nie wiem w sumie jak coś takiego najlepiej osiągnąć, bo jak widać ręcznie muszę ustawiać dozwolone klucze, które przecież mogą się zmienić. Ogólnie to dopiero zaczynam z tworzeniem takich API, a nie ukrywam, że chciałbym zrozumieć jak się np. tworzy takie coś od podstaw.
Operatorów gt, lt, gte, lte jeszcze nie zrobiłem, ale mam podobny przykład z innej technologii i tam jest to zrobione na podstawie wyrażenai regularnego, lecz w Pythonie chyba inaczej trzeba będzie to zrobić.