|
1 | 1 | #coding=utf-8
|
2 |
| -fromuliwebimportexpose,functions,models |
| 2 | +fromuliwebimportexpose,functions,models,UliwebError |
3 | 3 | fromuliweb.ormimportModelNotFound
|
| 4 | +fromsqlalchemy.sqlimportand_,or_,not_ |
4 | 5 | fromjsonimportloads
|
5 | 6 | importlogging
|
6 | 7 | importtraceback
|
@@ -202,21 +203,16 @@ def _get_array(self,key):
|
202 | 203 | ifnotowner_filtered:
|
203 | 204 | returnjson({"code":400,"msg":"'%s' cannot filter with owner"%(model_name)})
|
204 | 205 |
|
205 |
| -forninmodel_param: |
206 |
| -ifn[0]!="@": |
207 |
| -ifn[-1]=="$": |
208 |
| -name=n[:-1] |
209 |
| -ifhasattr(model,name): |
210 |
| -q=q.filter(getattr(model.c,name).like(model_param[n])) |
211 |
| -else: |
212 |
| -returnjson({"code":400,"msg":"'%s' does not have '%s'"%(model_name,name)}) |
213 |
| -elifn[-1]=="}"andn[-2]=="{": |
214 |
| -name=n[:-2] |
215 |
| -ifhasattr(model,name): |
216 |
| -# TODO |
217 |
| -pass |
218 |
| -elifhasattr(model,n): |
219 |
| -q=q.filter(getattr(model.c,n)==model_param[n]) |
| 206 | +model_expr=model_param.get("@expr") |
| 207 | + |
| 208 | +ifmodel_expr: |
| 209 | +c=self._expr(model,model_param,model_expr) |
| 210 | +q=q.filter(c) |
| 211 | +else: |
| 212 | +forninmodel_param: |
| 213 | +ifn[0]!="@": |
| 214 | +c=self._get_filter_condition(model,model_param,n) |
| 215 | +q=q.filter(c) |
220 | 216 |
|
221 | 217 | ifquery_typein [1,2]:
|
222 | 218 | self.vars["/%s/total"%(key)]=q.count()
|
@@ -266,6 +262,60 @@ def _filter_owner(self,model,model_setting,q):
|
266 | 262 | owner_filtered=True
|
267 | 263 | returnowner_filtered,q
|
268 | 264 |
|
| 265 | +def_expr(self,model,model_param,model_expr): |
| 266 | +ifnotisinstance(model_expr,list): |
| 267 | +raiseUliwebError("only accept array in @expr: '%s'"%(model_expr)) |
| 268 | +num=len(model_expr) |
| 269 | +if (num<2ornum>3): |
| 270 | +raiseUliwebError("only accept 2 or 3 items in @expr: '%s'"%(model_expr)) |
| 271 | +op=model_expr[-2] |
| 272 | +ifop=='&': |
| 273 | +ifnum!=3: |
| 274 | +raiseUliwebError("'&'(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 | +returnand_(c1,c2) |
| 278 | +elifop=='|': |
| 279 | +ifnum!=3: |
| 280 | +raiseUliwebError("'|'(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 | +returnor_(c1,c2) |
| 284 | +elifop=='!': |
| 285 | +ifnum!=2: |
| 286 | +raiseUliwebError("'!'(not) expression need 2 items: '%s'"%(model_expr)) |
| 287 | +returnnot_(self._get_filter_condition(model,model_param,model_expr[1],expr=True)) |
| 288 | +else: |
| 289 | +raiseUliwebError("unknown operator: '%s'"%(op)) |
| 290 | + |
| 291 | +def_get_filter_condition(self,model,model_param,item,expr=False): |
| 292 | +ifisinstance(item,list): |
| 293 | +ifexpr: |
| 294 | +returnself._expr(model,model_param,model_expr=item) |
| 295 | +else: |
| 296 | +raiseUliwebError("item can be array only in @expr: '%s'"%(item)) |
| 297 | +ifnotisinstance(item,str): |
| 298 | +raiseUliwebError("item should be array or string: '%s'"%(item)) |
| 299 | +n=item |
| 300 | +ifn[0]=="@": |
| 301 | +raiseUliwebError("param key should not begin with @: '%s'"%(n)) |
| 302 | +ifn[-1]=="$": |
| 303 | +name=n[:-1] |
| 304 | +ifhasattr(model,name): |
| 305 | +returngetattr(model.c,name).like(model_param[n]) |
| 306 | +else: |
| 307 | +raiseUliwebError("'%s' does not have '%s'"%(model_name,name)) |
| 308 | +elifn[-1]=="}"andn[-2]=="{": |
| 309 | +name=n[:-2] |
| 310 | +ifhasattr(model,name): |
| 311 | +# TODO |
| 312 | +pass |
| 313 | +raiseUliwebError("still not support '%s'"%(name)) |
| 314 | +elifhasattr(model,n): |
| 315 | +returngetattr(model.c,n)==model_param[n] |
| 316 | +else: |
| 317 | +raiseUliwebError("not support item: '%s'"%(item)) |
| 318 | + |
269 | 319 | defhead(self):
|
270 | 320 | try:
|
271 | 321 | forkeyinself.request_data:
|
|