def on_get(self, req, res): query_params = req.params.get('query') try: # get pagination limits start = int(query_params.pop('start', 0)) limit = int(query_params.pop('limit', constants.PAGE_LIMIT)) end = start + limit except ValueError as e: raise HTTPBadRequest(title='Invalid Value', description='Invalid arguments in URL query:\n{}'.format(e.message)) # custom filters # temp dict for updating query filters updated_params = {} for item in ['name', 'description']: if item in query_params: item_val = query_params.pop(item) updated_params['{}__icontains'.format(item)] = item_val try: if 'geolocation' in query_params: geolocation_val = query_params.pop('geolocation') geolocation_val = map(float, geolocation_val.split(',')[:2]) max_distance = int(query_params.pop('maxDistance', constants.MAX_DISTANCE_SEARCH)) # we deal with geolocation query in raw instead due to mongoengine bugs # see https://github.com/MongoEngine/mongoengine/issues/795 # dated: 3/1/2015 updated_params['__raw__'] = { 'geolocation': { '$near': { '$geometry': { 'type': 'Point', 'coordinates': geolocation_val }, '$maxDistance': max_distance }, } } except Exception: raise HTTPBadRequest('Invalid Value', 'geolocation supplied is invalid: {}'.format(geolocation_val)) query_params.update(updated_params) # update modified params for filtering restaurants = Restaurant.objects(**query_params)[start:end] for r in restaurants: reformat_geolocations_point_field_to_map(r, 'geolocation') res.body = {'items': restaurants, 'count': len(restaurants)}
def test_remove(self): Restaurant.objects(name__in=['a', 'b']).delete() self.assertEquals(len(Restaurant.objects), 0)
def tearDown(self): Restaurant.objects(id__in=[r.id for r in self.restaurants]).delete()
def on_get(self, req, res): query_params = req.params.get('query') try: # get pagination limits start = int(query_params.pop('start', 0)) limit = int(query_params.pop('limit', constants.PAGE_LIMIT)) end = start + limit except ValueError as e: raise HTTPBadRequest( title='Invalid Value', description='Invalid arguments in URL query:\n{}'.format( e.message)) # custom filters # temp dict for updating query filters updated_params = {} for item in ['name']: if item in query_params: item_val = query_params.pop(item) updated_params['{}__icontains'.format(item)] = item_val # skip updating query_params for filters on list fields like tags, # since mongoengine filters directly by finding any Menu that has tags of that value # e.g., GET /menu?tags=chicken returns all restaurants having 'chicken' tag for item in ['price', 'rating']: if item in query_params: range = query_params.pop(item) r_min, r_max = min_max(range, type='float') updated_params['{}__gte'.format(item)] = r_min updated_params['{}__lte'.format(item)] = r_max # for convenience, we allow users to search for menus by their restaurant's geolocation too if 'geolocation' in query_params: try: geolocation_val = query_params.pop('geolocation') geolocation_val = map(float, geolocation_val.split(',')[:2]) max_distance = int( query_params.pop('maxDistance', constants.MAX_DISTANCE_SEARCH)) # we deal with geolocation query in raw instead due to mongoengine bugs # see https://github.com/MongoEngine/mongoengine/issues/795 # dated: 3/1/2015 restaurant_query_params = { '__raw__': { 'geolocation': { '$near': { '$geometry': { 'type': 'Point', 'coordinates': geolocation_val }, '$maxDistance': max_distance }, } } } # return list of restaurants satisfying geolocation requirements restaurants = Restaurant.objects(**restaurant_query_params) # we found nearby restaurants, filter menus further to menus from these restaurants only updated_params['__raw__'] = { "restaurant.$id": { "$in": [r.id for r in restaurants] } } except Exception: raise HTTPBadRequest( 'Invalid Value', 'geolocation supplied is invalid: {}'.format( geolocation_val)) query_params.update( updated_params) # update modified params for filtering menus = Menu.objects(**query_params)[start:end] res.body = {'items': menus, 'count': len(menus)}
def tearDown(self): Restaurant.objects(id__in=[self.restaurant.id]).delete() Menu.objects().delete()
def on_get(self, req, res): query_params = req.params.get('query') try: # get pagination limits start = int(query_params.pop('start', 0)) limit = int(query_params.pop('limit', constants.PAGE_LIMIT)) end = start + limit except ValueError as e: raise HTTPBadRequest(title='Invalid Value', description='Invalid arguments in URL query:\n{}'.format(e.message)) # custom filters # temp dict for updating query filters updated_params = {} for item in ['name']: if item in query_params: item_val = query_params.pop(item) updated_params['{}__icontains'.format(item)] = item_val # skip updating query_params for filters on list fields like tags, # since mongoengine filters directly by finding any Menu that has tags of that value # e.g., GET /menu?tags=chicken returns all restaurants having 'chicken' tag for item in ['price', 'rating']: if item in query_params: range = query_params.pop(item) r_min, r_max = min_max(range, type='float') updated_params['{}__gte'.format(item)] = r_min updated_params['{}__lte'.format(item)] = r_max # for convenience, we allow users to search for menus by their restaurant's geolocation too if 'geolocation' in query_params: try: geolocation_val = query_params.pop('geolocation') geolocation_val = map(float, geolocation_val.split(',')[:2]) max_distance = int(query_params.pop('maxDistance', constants.MAX_DISTANCE_SEARCH)) # we deal with geolocation query in raw instead due to mongoengine bugs # see https://github.com/MongoEngine/mongoengine/issues/795 # dated: 3/1/2015 restaurant_query_params = { '__raw__': { 'geolocation': { '$near': { '$geometry': { 'type': 'Point', 'coordinates': geolocation_val }, '$maxDistance': max_distance }, } } } # return list of restaurants satisfying geolocation requirements restaurants = Restaurant.objects(**restaurant_query_params) # we found nearby restaurants, filter menus further to menus from these restaurants only updated_params['__raw__'] = { "restaurant.$id": { "$in": [r.id for r in restaurants] } } except Exception: raise HTTPBadRequest('Invalid Value', 'geolocation supplied is invalid: {}'.format(geolocation_val)) query_params.update(updated_params) # update modified params for filtering menus = Menu.objects(**query_params)[start:end] res.body = {'items': menus, 'count': len(menus)}