|
1 | 1 | #coding=utf-8 |
2 | | -from uliweb import expose, functions, models |
| 2 | +from uliweb import expose, functions, models, UliwebError |
3 | 3 | from uliweb.orm import ModelNotFound |
| 4 | +from sqlalchemy.sql import and_, or_, not_ |
4 | 5 | from json import loads |
5 | 6 | import logging |
6 | 7 | import traceback |
@@ -202,21 +203,16 @@ def _get_array(self,key): |
202 | 203 | if not owner_filtered: |
203 | 204 | return json({"code":400,"msg":"'%s' cannot filter with owner"%(model_name)}) |
204 | 205 |
|
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) |
220 | 216 |
|
221 | 217 | if query_type in [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 | return owner_filtered,q |
268 | 264 |
|
| 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 | + |
269 | 319 | def head(self): |
270 | 320 | try: |
271 | 321 | for key in self.request_data: |
|
0 commit comments