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

Commit872eeeb

Browse files
committed
add associated query feature with multi-table in a array
1 parent9b5d0e1 commit872eeeb

File tree

3 files changed

+272
-170
lines changed

3 files changed

+272
-170
lines changed

‎demo/apps/apijson_demo/views.py

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,41 +11,34 @@ def index():
1111

1212
request_get= [
1313
{
14-
"label":"Singlerecordquery: self user",
14+
"label":"Single query: self user",
1515
"value":'''{
1616
"user":{
1717
"@role":"OWNER"
1818
}
1919
}''',
2020
},
21+
2122
{
22-
"label":"Singlerecordquery: with id as parameter",
23+
"label":"Single query: with id as parameter",
2324
"value":'''{
2425
"user":{
2526
"id":2,
2627
"@role":"ADMIN"
2728
}
2829
}''',
2930
},
31+
3032
{
31-
"label":"Singlerecordquery: @column",
33+
"label":"Single query: @column",
3234
"value":'''{
3335
"user":{
3436
"@column": "id,username,email",
3537
"@role":"OWNER"
3638
}
3739
}''',
3840
},
39-
{
40-
"label":"Single record query: association query",
41-
"value":'''{
42-
"moment":{},
43-
"user":{
44-
"@column": "id,username,email",
45-
"id@": "moment/user_id"
46-
}
47-
}''',
48-
},
41+
4942
{
5043
"label":"Array query: user",
5144
"value":'''{
@@ -60,6 +53,7 @@ def index():
6053
}
6154
}''',
6255
},
56+
6357
{
6458
"label":"Array query: moment",
6559
"value":'''{
@@ -74,6 +68,7 @@ def index():
7468
"total@":"/moment[]/total"
7569
}''',
7670
},
71+
7772
{
7873
"label":"Array query: like",
7974
"value":'''{
@@ -89,6 +84,7 @@ def index():
8984
}
9085
}''',
9186
},
87+
9288
{
9389
"label":"Array query: simple @expr",
9490
"value":'''{
@@ -106,6 +102,7 @@ def index():
106102
}
107103
}''',
108104
},
105+
109106
{
110107
"label":"Array query: complex @expr",
111108
"value":'''{
@@ -124,24 +121,37 @@ def index():
124121
}
125122
}''',
126123
},
124+
125+
{
126+
"label":"Association query: Two tables, one to one",
127+
"value":'''{
128+
"moment":{},
129+
"user":{
130+
"@column": "id,username,email",
131+
"id@": "moment/user_id"
132+
}
133+
}''',
134+
},
135+
127136
{
128-
"label":"Array query:association query one to many",
137+
"label":"Association query:Two tables, one to many",
129138
"value":'''{
130139
"moment": {},
131140
"[]": {
132141
"comment": {
133-
"moment_id@": "moment/id"
142+
"moment_id@": "moment/id",
143+
"@order":"date-"
134144
}
135145
}
136146
}''',
137147
},
148+
138149
{
139-
"label":"Array query:association query",
150+
"label":"Association query:Two tables in array",
140151
"value":'''{
141152
"[]": {
142153
"moment": {
143-
"@column": "id,date,user_id",
144-
"id": 3
154+
"@column": "id,date,user_id"
145155
},
146156
"user": {
147157
"id@": "/moment/user_id",

‎uliweb_apijson/apijson/__init__.py

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
#coding=utf-8
22

3+
fromuliwebimportsettings,models,request,functions
4+
fromuliweb.ormimportModelNotFound
5+
6+
37
defget_apijson_tables(role="UNKNOWN"):
48
fromuliwebimportsettings
59

@@ -47,3 +51,204 @@ def get_apijson_table(role="UNKNOWN",name=None):
4751
editable=roleinroles
4852
c["editable"]=editable
4953
returnc
54+
55+
classApiJsonModelQuery(object):
56+
def__init__(self,name,params,parent,key):
57+
self.name=name
58+
self.params=params
59+
self.parent=parent
60+
self.key=key
61+
self.query_params=self.parent.request_data[key]
62+
63+
try:
64+
self.model=getattr(models,name)
65+
exceptModelNotFoundase:
66+
log.error("try to find model '%s' but not found: '%s'"%(name,e))
67+
raiseUliwebError("model '%s' not found"%(name))
68+
69+
self.setting=settings.APIJSON_MODELS.get(name,{})
70+
self.secret_fields=self.setting.get("secret_fields")
71+
self.column=params.get("@column")
72+
ifself.column:
73+
self.column_set=set(self.column.split(","))
74+
ifself.secret_fields:
75+
self.column_set-=set(self.secret_fields)
76+
self.column_set&=set(self.model.columns.keys())
77+
else:
78+
self.column_set=None
79+
80+
self.permission_check_ok=False
81+
82+
def_check_GET_permission(self):
83+
GET=self.setting.get("GET")
84+
ifnotGET:
85+
raiseUliwebError("'%s' not accessible by apijson"%(name))
86+
87+
roles=GET.get("roles")
88+
params_role=self.params.get("@role")
89+
90+
ifnotparams_role:
91+
ifrequest.user:
92+
params_role="LOGIN"
93+
else:
94+
params_role="UNKNOWN"
95+
ifparams_rolenotinroles:
96+
raiseUliwebError("'%s' not accessible by role '%s'"%(model_name,params_role))
97+
ifparams_role=="UNKNOWN":
98+
self.permission_check_ok=True
99+
eliffunctions.has_role(request.user,params_role):
100+
self.permission_check_ok=True
101+
else:
102+
raiseUliwebError("user doesn't have role '%s'"%(params_role))
103+
104+
ifnotself.permission_check_ok:
105+
raiseUliwebError("no permission")
106+
107+
self.params_role=params_role
108+
109+
def_get_array_params(self):
110+
query_count=self.query_params.get("@count")
111+
ifquery_count:
112+
try:
113+
query_count=int(query_count)
114+
exceptValueErrorase:
115+
log.error("bad param in '%s': '%s'"%(n,self.query_params))
116+
raiseUliwebError("@count should be an int, now '%s'"%(query_count))
117+
self.query_count=query_count
118+
119+
query_page=self.query_params.get("@page")
120+
ifquery_page:
121+
#@page begin from 0
122+
try:
123+
query_page=int(query_page)
124+
exceptValueErrorase:
125+
log.error("bad param in '%s': '%s'"%(n,self.query_params))
126+
raiseUliwebError("@page should be an int, now '%s'"%(query_page))
127+
ifquery_page<0:
128+
raiseUliwebError("page should >0, now is '%s'"%(query_page))
129+
self.query_page=query_page
130+
131+
#https://github.com/TommyLemon/APIJSON/blob/master/Document.md#32-%E5%8A%9F%E8%83%BD%E7%AC%A6
132+
query_type=self.query_params.get("@query",0)
133+
ifquery_typenotin [0,1,2]:
134+
raiseUliwebError("bad param 'query': %s"%(query_type))
135+
self.query_type=query_type
136+
137+
#order not in query params but in model params
138+
self.order=self.params.get("@order")
139+
140+
def_filter_owner(self,q):
141+
owner_filtered=False
142+
ifhasattr(self.model,"owner_condition"):
143+
q=q.filter(model.owner_condition())
144+
owner_filtered=True
145+
ifnotowner_filtered:
146+
user_id_field=self.setting.get("user_id_field")
147+
ifuser_id_field:
148+
q=q.filter(getattr(model.c,user_id_field)==request.user.id)
149+
owner_filtered=True
150+
ifnotowner_filtered:
151+
raiseUliwebError("'%s' cannot filter with owner"%(model_name))
152+
returnq
153+
154+
def_get_array_q(self,params):
155+
q=self.model.all()
156+
ifself.params_role=="OWNER":
157+
q=self._filter_owner(q)
158+
159+
#@expr
160+
model_expr=params.get("@expr")
161+
ifmodel_expr:
162+
c=self.parent._expr(self.model,params,model_expr)
163+
q=q.filter(c)
164+
else:
165+
forninparams:
166+
ifn[0]!="@":
167+
c=self.parent._get_filter_condition(self.model,params,n)
168+
q=q.filter(c)
169+
returnq
170+
171+
def_get_info(self,i,as_dict_child=False):
172+
173+
d=i.to_dict()
174+
ifself.secret_fields:
175+
forkinself.secret_fields:
176+
deld[k]
177+
ifself.column_set:
178+
keys=list(d.keys())
179+
forkinkeys:
180+
ifknotinself.column_set:
181+
deld[k]
182+
ifas_dict_child:
183+
resultd= {}
184+
resultd[self.name]=d
185+
returnresultd
186+
else:
187+
returnd
188+
189+
defquery_array(self):
190+
self._check_GET_permission()
191+
self._get_array_params()
192+
params=self.params.copy()
193+
194+
#update reference
195+
ref_fields= []
196+
refs= {}
197+
forninparams:
198+
ifn[-1]=="@":
199+
ref_fields.append(n)
200+
col_name=n[:-1]
201+
path=params[n]
202+
refs[col_name]=self.parent._ref_get(path)
203+
ifref_fields:
204+
foriinref_fields:
205+
delparams[i]
206+
params.update(refs)
207+
208+
q=self._get_array_q(params)
209+
210+
ifself.query_typein [1,2]:
211+
self.parent.vars["/%s/total"%(self.key)]=q.count()
212+
213+
ifself.query_typein [0,2]:
214+
ifself.query_count:
215+
ifself.query_page:
216+
q=q.offset(self.query_page*self.query_count)
217+
q=q.limit(self.query_count)
218+
ifself.order:
219+
forkinself.order.split(","):
220+
ifk[-1]=="+":
221+
sort_key=k[:-1]
222+
sort_order="asc"
223+
elifk[-1]=="-":
224+
sort_key=k[:-1]
225+
sort_order="desc"
226+
else:
227+
sort_key=k
228+
sort_order="asc"
229+
column=getattr(self.model.c,sort_key)
230+
q=q.order_by(getattr(column,sort_order)())
231+
l= [self._get_info(i,True)foriinq]
232+
self.parent.rdict[self.key]=l
233+
234+
defassociated_query_array(self):
235+
self._check_GET_permission()
236+
self._get_array_params()
237+
foriteminself.parent.rdict[self.key]:
238+
params=self.params.copy()
239+
#update reference
240+
ref_fields= []
241+
refs= {}
242+
forninparams:
243+
ifn[-1]=="@":
244+
ref_fields.append(n)
245+
col_name=n[:-1]
246+
path=params[n]
247+
refs[col_name]=self.parent._ref_get(path,context=item)
248+
ifref_fields:
249+
foriinref_fields:
250+
delparams[i]
251+
params.update(refs)
252+
q=self._get_array_q(params)
253+
q=q.limit(1)
254+
item[self.name]=self._get_info(q.one())

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp