|
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