Skip to content

Commit 0185205

Browse files
committed
add @expr support in apijson_get array
1 parent 4a5e758 commit 0185205

File tree

1 file changed

+66
-16
lines changed

1 file changed

+66
-16
lines changed

uliweb_apijson/apijson/views.py

Lines changed: 66 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#coding=utf-8
2-
from uliweb import expose, functions, models
2+
from uliweb import expose, functions, models, UliwebError
33
from uliweb.orm import ModelNotFound
4+
from sqlalchemy.sql import and_, or_, not_
45
from json import loads
56
import logging
67
import traceback
@@ -202,21 +203,16 @@ def _get_array(self,key):
202203
if not owner_filtered:
203204
return json({"code":400,"msg":"'%s' cannot filter with owner"%(model_name)})
204205

205-
for n in model_param:
206-
if n[0]!="@":
207-
if n[-1]=="$":
208-
name = n[:-1]
209-
if hasattr(model,name):
210-
q = q.filter(getattr(model.c,name).like(model_param[n]))
211-
else:
212-
return json({"code":400,"msg":"'%s' does not have '%s'"%(model_name,name)})
213-
elif n[-1]=="}" and n[-2]=="{":
214-
name = n[:-2]
215-
if hasattr(model,name):
216-
# TODO
217-
pass
218-
elif hasattr(model,n):
219-
q = q.filter(getattr(model.c,n)==model_param[n])
206+
model_expr = model_param.get("@expr")
207+
208+
if model_expr:
209+
c = self._expr(model,model_param,model_expr)
210+
q = q.filter(c)
211+
else:
212+
for n in model_param:
213+
if n[0]!="@":
214+
c = self._get_filter_condition(model,model_param,n)
215+
q = q.filter(c)
220216

221217
if query_type in [1,2]:
222218
self.vars["/%s/total"%(key)] = q.count()
@@ -266,6 +262,60 @@ def _filter_owner(self,model,model_setting,q):
266262
owner_filtered = True
267263
return owner_filtered,q
268264

265+
def _expr(self,model,model_param,model_expr):
266+
if not isinstance(model_expr,list):
267+
raise UliwebError("only accept array in @expr: '%s'"%(model_expr))
268+
num = len(model_expr)
269+
if (num<2 or num>3):
270+
raise UliwebError("only accept 2 or 3 items in @expr: '%s'"%(model_expr))
271+
op = model_expr[-2]
272+
if op=='&':
273+
if num!=3:
274+
raise UliwebError("'&'(and) expression need 3 items: '%s'"%(model_expr))
275+
c1 = self._get_filter_condition(model,model_param,model_expr[0],expr=True)
276+
c2 = self._get_filter_condition(model,model_param,model_expr[2],expr=True)
277+
return and_(c1,c2)
278+
elif op=='|':
279+
if num!=3:
280+
raise UliwebError("'|'(or) expression need 3 items: '%s'"%(model_expr))
281+
c1 = self._get_filter_condition(model,model_param,model_expr[0],expr=True)
282+
c2 = self._get_filter_condition(model,model_param,model_expr[2],expr=True)
283+
return or_(c1,c2)
284+
elif op=='!':
285+
if num!=2:
286+
raise UliwebError("'!'(not) expression need 2 items: '%s'"%(model_expr))
287+
return not_(self._get_filter_condition(model,model_param,model_expr[1],expr=True))
288+
else:
289+
raise UliwebError("unknown operator: '%s'"%(op))
290+
291+
def _get_filter_condition(self,model,model_param,item,expr=False):
292+
if isinstance(item,list):
293+
if expr:
294+
return self._expr(model,model_param,model_expr=item)
295+
else:
296+
raise UliwebError("item can be array only in @expr: '%s'"%(item))
297+
if not isinstance(item,str):
298+
raise UliwebError("item should be array or string: '%s'"%(item))
299+
n = item
300+
if n[0]=="@":
301+
raise UliwebError("param key should not begin with @: '%s'"%(n))
302+
if n[-1]=="$":
303+
name = n[:-1]
304+
if hasattr(model,name):
305+
return getattr(model.c,name).like(model_param[n])
306+
else:
307+
raise UliwebError("'%s' does not have '%s'"%(model_name,name))
308+
elif n[-1]=="}" and n[-2]=="{":
309+
name = n[:-2]
310+
if hasattr(model,name):
311+
# TODO
312+
pass
313+
raise UliwebError("still not support '%s'"%(name))
314+
elif hasattr(model,n):
315+
return getattr(model.c,n)==model_param[n]
316+
else:
317+
raise UliwebError("not support item: '%s'"%(item))
318+
269319
def head(self):
270320
try:
271321
for key in self.request_data:

0 commit comments

Comments
 (0)