Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit75272b5

Browse files
committed
add {} support(example: "id{}": [1, 2]); update tests and demo; bump version number to 0.2.2
1 parentb0ec28f commit75272b5

File tree

4 files changed

+301
-12
lines changed

4 files changed

+301
-12
lines changed

‎demo/apps/apijson_demo/views.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,28 @@ def index():
8585
}''',
8686
},
8787

88+
{
89+
"label":"Array query: {} with list",
90+
"value":'''{
91+
"[]":{
92+
"moment":{
93+
"id{}":[2,3]
94+
}
95+
}
96+
}''',
97+
},
98+
99+
{
100+
"label":"Array query: {} with conditions",
101+
"value":'''{
102+
"[]":{
103+
"user":{
104+
"id&{}":">2,<=4"
105+
}
106+
}
107+
}''',
108+
},
109+
88110
{
89111
"label":"Array query: simple @expr",
90112
"value":'''{

‎tests/test.py

Lines changed: 219 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,6 @@ def setup():
1111
manage.call('uliweb reset -v -y')
1212
manage.call('uliweb dbinit -v')
1313

14-
defteardown():
15-
pass
16-
1714
defpre_call_as(username):
1815
fromuliwebimportmodels
1916
User=models.user
@@ -22,7 +19,6 @@ def pre_call(request):
2219
request.user=user
2320
returnpre_call
2421

25-
@with_setup(setup,teardown)
2622
deftest_apijson_get():
2723
"""
2824
>>> application = make_simple_application(project_dir='.')
@@ -747,7 +743,7 @@ def test_apijson_get():
747743
>>> r = handler.post('/apijson/get', data=data, pre_call=pre_call_as("admin"), middlewares=[])
748744
>>> d = json_loads(r.data)
749745
>>> print(d)
750-
{'code': 400, 'msg': "model does not havethiscolumn: 'nonexist'"}
746+
{'code': 400, 'msg': "model does not have column: 'nonexist'"}
751747
752748
>>> #query array with a nonexist column
753749
>>> data ='''{
@@ -767,6 +763,224 @@ def test_apijson_get():
767763
>>> print(d)
768764
{'code': 400, 'msg': "non-existent column or not support item: 'nonexist'"}
769765
766+
>>> #query array, {} with list
767+
>>> data ='''{
768+
... "[]":{
769+
... "moment": {
770+
... "id{}": [1, 2]
771+
... }
772+
... }
773+
... }'''
774+
>>> r = handler.post('/apijson/get', data=data, pre_call=pre_call_as("admin"), middlewares=[])
775+
>>> d = json_loads(r.data)
776+
>>> print(d)
777+
{'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}}]}
778+
779+
>>> #query array, !{} with list
780+
>>> data ='''{
781+
... "[]":{
782+
... "moment": {
783+
... "id!{}": [1, 2]
784+
... }
785+
... }
786+
... }'''
787+
>>> r = handler.post('/apijson/get', data=data, pre_call=pre_call_as("admin"), middlewares=[])
788+
>>> d = json_loads(r.data)
789+
>>> print(d)
790+
{'code': 200, 'msg': 'success', '[]': [{'moment': {'user_id': 4, 'date': '2018-11-06 00:00:00', 'content': 'test moment from c', 'picture_list': '[]', 'id': 3}}]}
791+
792+
>>> #query array, {} with a non-exist column name
793+
>>> data ='''{
794+
... "[]":{
795+
... "moment": {
796+
... "nonexist{}": [1, 2]
797+
... }
798+
... }
799+
... }'''
800+
>>> r = handler.post('/apijson/get', data=data, pre_call=pre_call_as("admin"), middlewares=[])
801+
>>> d = json_loads(r.data)
802+
>>> print(d)
803+
{'code': 400, 'msg': "model does not have column: 'nonexist'"}
804+
805+
>>> #query array, {} >=
806+
>>> data ='''{
807+
... "[]":{
808+
... "moment": {
809+
... "id{}": ">=2"
810+
... }
811+
... }
812+
... }'''
813+
>>> r = handler.post('/apijson/get', data=data, pre_call=pre_call_as("admin"), middlewares=[])
814+
>>> d = json_loads(r.data)
815+
>>> print(d)
816+
{'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}}]}
817+
818+
>>> #query array, {} =
819+
>>> data ='''{
820+
... "[]":{
821+
... "moment": {
822+
... "id{}": "=2"
823+
... }
824+
... }
825+
... }'''
826+
>>> r = handler.post('/apijson/get', data=data, pre_call=pre_call_as("admin"), middlewares=[])
827+
>>> d = json_loads(r.data)
828+
>>> print(d)
829+
{'code': 200, 'msg': 'success', '[]': [{'moment': {'user_id': 3, 'date': '2018-11-02 00:00:00', 'content': 'test moment from b', 'picture_list': '[]', 'id': 2}}]}
830+
831+
>>> #query array, {} >
832+
>>> data ='''{
833+
... "[]":{
834+
... "moment": {
835+
... "id{}": ">2"
836+
... }
837+
... }
838+
... }'''
839+
>>> r = handler.post('/apijson/get', data=data, pre_call=pre_call_as("admin"), middlewares=[])
840+
>>> d = json_loads(r.data)
841+
>>> print(d)
842+
{'code': 200, 'msg': 'success', '[]': [{'moment': {'user_id': 4, 'date': '2018-11-06 00:00:00', 'content': 'test moment from c', 'picture_list': '[]', 'id': 3}}]}
843+
844+
>>> #query array, {} <=
845+
>>> data ='''{
846+
... "[]":{
847+
... "moment": {
848+
... "id{}": "<=2"
849+
... }
850+
... }
851+
... }'''
852+
>>> r = handler.post('/apijson/get', data=data, pre_call=pre_call_as("admin"), middlewares=[])
853+
>>> d = json_loads(r.data)
854+
>>> print(d)
855+
{'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}}]}
856+
857+
>>> #query array, {} <
858+
>>> data ='''{
859+
... "[]":{
860+
... "moment": {
861+
... "id{}": "<2"
862+
... }
863+
... }
864+
... }'''
865+
>>> r = handler.post('/apijson/get', data=data, pre_call=pre_call_as("admin"), middlewares=[])
866+
>>> d = json_loads(r.data)
867+
>>> print(d)
868+
{'code': 200, 'msg': 'success', '[]': [{'moment': {'user_id': 2, 'date': '2018-11-01 00:00:00', 'content': 'test moment', 'picture_list': '[]', 'id': 1}}]}
869+
870+
>>> #query array, !{} <
871+
>>> data ='''{
872+
... "[]":{
873+
... "moment": {
874+
... "id!{}": "<2"
875+
... }
876+
... }
877+
... }'''
878+
>>> r = handler.post('/apijson/get', data=data, pre_call=pre_call_as("admin"), middlewares=[])
879+
>>> d = json_loads(r.data)
880+
>>> print(d)
881+
{'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}}]}
882+
883+
>>> #query array, {} !=
884+
>>> data ='''{
885+
... "[]":{
886+
... "moment": {
887+
... "id{}": "!=2"
888+
... }
889+
... }
890+
... }'''
891+
>>> r = handler.post('/apijson/get', data=data, pre_call=pre_call_as("admin"), middlewares=[])
892+
>>> d = json_loads(r.data)
893+
>>> print(d)
894+
{'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': 4, 'date': '2018-11-06 00:00:00', 'content': 'test moment from c', 'picture_list': '[]', 'id': 3}}]}
895+
896+
>>> #query array, {} with wrong operator
897+
>>> data ='''{
898+
... "[]":{
899+
... "moment": {
900+
... "id{}": "%=2"
901+
... }
902+
... }
903+
... }'''
904+
>>> r = handler.post('/apijson/get', data=data, pre_call=pre_call_as("admin"), middlewares=[])
905+
>>> d = json_loads(r.data)
906+
>>> print(d)
907+
{'code': 400, 'msg': "not support '%=2'"}
908+
909+
>>> #query array, {} condition list
910+
>>> data ='''{
911+
... "[]":{
912+
... "user": {
913+
... "@role": "ADMIN",
914+
... "id{}": "<=2,>3",
915+
... "@column": "username,nickname,id"
916+
... }
917+
... }
918+
... }'''
919+
>>> r = handler.post('/apijson/get', data=data, pre_call=pre_call_as("admin"), middlewares=[])
920+
>>> d = json_loads(r.data)
921+
>>> print(d)
922+
{'code': 200, 'msg': 'success', '[]': [{'user': {'username': 'admin', 'nickname': 'Administrator', 'id': 1}}, {'user': {'username': 'usera', 'nickname': 'User A', 'id': 2}}, {'user': {'username': 'userc', 'nickname': 'User C', 'id': 4}}]}
923+
924+
>>> #query array, |{} condition list
925+
>>> data ='''{
926+
... "[]":{
927+
... "user": {
928+
... "@role": "ADMIN",
929+
... "id|{}": "<=2,>3",
930+
... "@column": "username,nickname,id"
931+
... }
932+
... }
933+
... }'''
934+
>>> r = handler.post('/apijson/get', data=data, pre_call=pre_call_as("admin"), middlewares=[])
935+
>>> d = json_loads(r.data)
936+
>>> print(d)
937+
{'code': 200, 'msg': 'success', '[]': [{'user': {'username': 'admin', 'nickname': 'Administrator', 'id': 1}}, {'user': {'username': 'usera', 'nickname': 'User A', 'id': 2}}, {'user': {'username': 'userc', 'nickname': 'User C', 'id': 4}}]}
938+
939+
>>> #query array, &{} condition list
940+
>>> data ='''{
941+
... "[]":{
942+
... "user": {
943+
... "@role": "ADMIN",
944+
... "id&{}": ">2,<=4",
945+
... "@column": "username,nickname,id"
946+
... }
947+
... }
948+
... }'''
949+
>>> r = handler.post('/apijson/get', data=data, pre_call=pre_call_as("admin"), middlewares=[])
950+
>>> d = json_loads(r.data)
951+
>>> print(d)
952+
{'code': 200, 'msg': 'success', '[]': [{'user': {'username': 'userb', 'nickname': 'User B', 'id': 3}}, {'user': {'username': 'userc', 'nickname': 'User C', 'id': 4}}]}
953+
954+
>>> #query array, !{} condition list
955+
>>> data ='''{
956+
... "[]":{
957+
... "user": {
958+
... "@role": "ADMIN",
959+
... "id!{}": ">2,<=4",
960+
... "@column": "username,nickname,id"
961+
... }
962+
... }
963+
... }'''
964+
>>> r = handler.post('/apijson/get', data=data, pre_call=pre_call_as("admin"), middlewares=[])
965+
>>> d = json_loads(r.data)
966+
>>> print(d)
967+
{'code': 400, 'msg': "'!' not supported in condition list"}
968+
969+
>>> #query array, |{} condition list, item more than 2
970+
>>> data ='''{
971+
... "[]":{
972+
... "user": {
973+
... "@role": "ADMIN",
974+
... "id|{}": "=1,=2,>=4",
975+
... "@column": "username,id"
976+
... }
977+
... }
978+
... }'''
979+
>>> r = handler.post('/apijson/get', data=data, pre_call=pre_call_as("admin"), middlewares=[])
980+
>>> d = json_loads(r.data)
981+
>>> print(d)
982+
{'code': 200, 'msg': 'success', '[]': [{'user': {'username': 'admin', 'id': 1}}, {'user': {'username': 'usera', 'id': 2}}, {'user': {'username': 'userc', 'id': 4}}]}
983+
770984
>>> #Association query: Two tables, one to one,ref path is absolute path
771985
>>> data ='''{
772986
... "moment":{},

‎uliweb_apijson/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
__version__='0.2.1'
1+
__version__='0.2.2'
22
__url__='https://github.com/zhangchunlin/uliweb-apijson'
33
__author__='Chunlin Zhang'
44
__email__='zhangchunlin@gmail.com'

‎uliweb_apijson/apijson/views.py

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -244,18 +244,71 @@ def _get_filter_condition(self,model,model_param,item,expr=False):
244244
ifhasattr(model,name):
245245
returngetattr(model.c,name).like(model_param[n])
246246
else:
247-
raiseUliwebError("model does not havethiscolumn: '%s'"%(name))
247+
raiseUliwebError("model does not have column: '%s'"%(name))
248248
elifn[-1]=="}"andn[-2]=="{":
249-
name=n[:-2]
250-
ifhasattr(model,name):
251-
# TODO: https://github.com/APIJSON/APIJSON/blob/master/Document.md#32-%E5%8A%9F%E8%83%BD%E7%AC%A6
252-
pass
253-
raiseUliwebError("still not support '%s'"%(name))
249+
ifn[-3]in ["&","|","!"]:
250+
operator=n[-3]
251+
name=n[:-3]
252+
else:
253+
operator=None
254+
name=n[:-2]
255+
256+
ifnothasattr(model,name):
257+
raiseUliwebError("model does not have column: '%s'"%(name))
258+
259+
# https://github.com/APIJSON/APIJSON/blob/master/Document.md#32-%E5%8A%9F%E8%83%BD%E7%AC%A6
260+
# https://vincentcheng.github.io/apijson-doc/zh/grammar.html#%E9%80%BB%E8%BE%91%E8%BF%90%E7%AE%97-%E7%AD%9B%E9%80%89
261+
col=getattr(model.c,name)
262+
cond=model_param[n]
263+
ifisinstance(cond,list):
264+
fcond=col.in_(cond)
265+
ifoperator=="!":
266+
fcond=not_(fcond)
267+
returnfcond
268+
elifisinstance(cond,str):
269+
cond_list=cond.strip().split(",")
270+
iflen(cond_list)==1:
271+
fcond=self._get_filter_condition_from_str(col,cond_list[0])
272+
ifoperator=="!":
273+
fcond=not_(fcond)
274+
returnfcond
275+
eliflen(cond_list)>1:
276+
fcond=self._get_filter_condition_from_str(col,cond_list[0])
277+
forcincond_list:
278+
fc=self._get_filter_condition_from_str(col,c)
279+
ifoperator=="&":
280+
fcond=and_(fcond,fc)
281+
elifoperator=="|"oroperator==None:
282+
fcond=or_(fcond,fc)
283+
else:
284+
raiseUliwebError("'%s' not supported in condition list"%(operator))
285+
returnfcond
286+
287+
raiseUliwebError("not support '%s':'%s'"%(n,cond))
254288
elifhasattr(model,n):
255289
returngetattr(model.c,n)==model_param[n]
256290
else:
257291
raiseUliwebError("non-existent column or not support item: '%s'"%(item))
258292

293+
def_get_filter_condition_from_str(self,col,cond_str):
294+
cond_str=cond_str.strip()
295+
c1,c2=cond_str[0],cond_str[1]
296+
ifc1=='>':
297+
ifc2=="=":
298+
returncol>=cond_str[2:]
299+
else:
300+
returncol>cond_str[1:]
301+
elifc1=='<':
302+
ifc2=="=":
303+
returncol<=cond_str[2:]
304+
else:
305+
returncol<cond_str[1:]
306+
elifc1=="=":
307+
returncol==cond_str[1:]
308+
elifc1=="!"andc2=="=":
309+
returncol!=cond_str[2:]
310+
raiseUliwebError("not support '%s'"%(cond_str))
311+
259312
defhead(self):
260313
try:
261314
forkeyinself.request_data:

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp