diff --git a/tests/test.py b/tests/test.py index 3b71f16..dd246b6 100644 --- a/tests/test.py +++ b/tests/test.py @@ -867,6 +867,45 @@ def test_apijson_get(): >>> print(d) {'code': 200, 'msg': 'success', '[]': [{'moment': {'user_id': 2, 'date': '2018-11-01 00:00:00', 'content': 'test moment', 'picture_list': '[]', 'id': 1}}]} + >>> #query array, {} <= with datetime + >>> data ='''{ + ... "[]":{ + ... "moment": { + ... "date{}": "<='2018-11-02 00:00'" + ... } + ... } + ... }''' + >>> r = handler.post('/apijson/get', data=data, pre_call=pre_call_as("admin"), middlewares=[]) + >>> d = json_loads(r.data) + >>> print(d) + {'code': 200, 'msg': 'success', '[]': [{'moment': {'user_id': 2, 'date': '2018-11-01 00:00:00', 'content': 'test moment', 'picture_list': '[]', 'id': 1}}, {'moment': {'user_id': 3, 'date': '2018-11-02 00:00:00', 'content': 'test moment from b', 'picture_list': '[]', 'id': 2}}]} + + >>> #query array, {} >= with datetime + >>> data ='''{ + ... "[]":{ + ... "moment": { + ... "date{}": ">='2018-11-02 00:00'" + ... } + ... } + ... }''' + >>> r = handler.post('/apijson/get', data=data, pre_call=pre_call_as("admin"), middlewares=[]) + >>> d = json_loads(r.data) + >>> print(d) + {'code': 200, 'msg': 'success', '[]': [{'moment': {'user_id': 3, 'date': '2018-11-02 00:00:00', 'content': 'test moment from b', 'picture_list': '[]', 'id': 2}}, {'moment': {'user_id': 4, 'date': '2018-11-06 00:00:00', 'content': 'test moment from c', 'picture_list': '[]', 'id': 3}}]} + + >>> #query array, {} >= with a invalid datetime + >>> data ='''{ + ... "[]":{ + ... "moment": { + ... "date{}": ">='2018-11-42 00:00'" + ... } + ... } + ... }''' + >>> r = handler.post('/apijson/get', data=data, pre_call=pre_call_as("admin"), middlewares=[]) + >>> d = json_loads(r.data) + >>> print(d) + {'code': 400, 'msg': "''2018-11-42 00:00'' cannot convert to datetime"} + >>> #query array, !{} < >>> data ='''{ ... "[]":{ @@ -951,6 +990,21 @@ def test_apijson_get(): >>> print(d) {'code': 200, 'msg': 'success', '[]': [{'user': {'username': 'userb', 'nickname': 'User B', 'id': 3}}, {'user': {'username': 'userc', 'nickname': 'User C', 'id': 4}}]} + >>> #query array, &{} condition list + >>> data ='''{ + ... "[]":{ + ... "user": { + ... "@role": "ADMIN", + ... "date_join&{}": ">='2018-1-1 00:00',<='2018-2-2 00:00'", + ... "@column": "username,nickname,id,date_join" + ... } + ... } + ... }''' + >>> r = handler.post('/apijson/get', data=data, pre_call=pre_call_as("admin"), middlewares=[]) + >>> d = json_loads(r.data) + >>> print(d) + {'code': 200, 'msg': 'success', '[]': [{'user': {'username': 'admin', 'nickname': 'Administrator', 'date_join': '2018-01-01 00:00:00', 'id': 1}}, {'user': {'username': 'usera', 'nickname': 'User A', 'date_join': '2018-02-02 00:00:00', 'id': 2}}]} + >>> #query array, {} multiple condition to a same field >>> data ='''{ ... "[]":{ diff --git a/uliweb_apijson/apijson/views.py b/uliweb_apijson/apijson/views.py index 3ec61e2..5dc8a7e 100644 --- a/uliweb_apijson/apijson/views.py +++ b/uliweb_apijson/apijson/views.py @@ -1,12 +1,14 @@ #coding=utf-8 -from uliweb import expose, functions, models, UliwebError +from uliweb import expose, functions, models, UliwebError, request from uliweb.orm import ModelNotFound from uliweb.utils._compat import string_types +from uliweb.utils.date import to_datetime from sqlalchemy.sql import and_, or_, not_ from json import loads from collections import OrderedDict import logging import traceback +from datetime import datetime from . import ApiJsonModelQuery log = logging.getLogger('apijson') @@ -274,7 +276,7 @@ def _get_filter_condition(self,model,model_param,item,expr=False): return fcond elif len(cond_list)>1: fcond = self._get_filter_condition_from_str(col,cond_list[0]) - for c in cond_list: + for c in cond_list[1:]: fc = self._get_filter_condition_from_str(col,c) if operator=="&": fcond = and_(fcond,fc) @@ -293,20 +295,40 @@ def _get_filter_condition(self,model,model_param,item,expr=False): def _get_filter_condition_from_str(self,col,cond_str): cond_str = cond_str.strip() c1,c2 = cond_str[0],cond_str[1] + v = None + def _conver(): + nonlocal v + if v and col.type.python_type==datetime: + _v = v + v = to_datetime(v,tzinfo=getattr(request,"tzinfo",None)) + if v==None: + raise UliwebError("'%s' cannot convert to datetime"%(_v)) if c1=='>': if c2=="=": - return col >= cond_str[2:] + v = cond_str[2:] + _conver() + return col >= v else: + v = cond_str[1:] + _conver() return col > cond_str[1:] elif c1=='<': if c2=="=": - return col <= cond_str[2:] + v = cond_str[2:] + _conver() + return col <= v else: - return col < cond_str[1:] + v = cond_str[1:] + _conver() + return col < v elif c1=="=": - return col == cond_str[1:] + v = cond_str[1:] + _conver() + return col == v elif c1=="!" and c2=="=": - return col != cond_str[2:] + v = cond_str[2:] + _conver() + return col != v raise UliwebError("not support '%s'"%(cond_str)) def head(self):