1 import cherrypy
2
3 try:
4 import sqlobject
5 except ImportError:
6 sqlobject = None
7 else:
8 from sqlobject.sqlbuilder import Select, func, AND, IN
9
10 import turbogears
11 from turbogears import expose, controllers
12
13
14 -class Browse(controllers.Controller):
15
17 """Delegate basic methods to CatWalk."""
18 return getattr(self.catwalk, attrib)
19
20 @expose(template='turbogears.toolbox.catwalk.browse_grid', allow_json=True)
21 - def index(self, object_name, start=0, page_size=10,
22 context='', filters=''):
23 try:
24 start, page_size = int(start), int(page_size)
25 except ValueError:
26 start, page_size = 0, 10
27 if not context:
28 context = object_name
29 headers = [header for header in self.column_headers(
30 object_name, context) if header['visible']]
31 total, rows = self.rows_for_model(
32 object_name, start, page_size, filters)
33 return dict(object_name=object_name, start=start, page_size=page_size,
34 total=total, headers= headers, rows = rows)
35
36 @expose(template='turbogears.toolbox.catwalk.columns', allow_json=True)
37 - def columns(self, object_name, context=''):
42
43 @expose(allow_json=True)
44 - def save_columns(self, object_name, context, order, hidden_columns,
45 updated_fk_labels):
46 self.save_column_order(context, order)
47 self.hide_columns(context, hidden_columns)
48 if updated_fk_labels:
49 for updated_fk_label in updated_fk_labels.split('|'):
50 obj, column_name = updated_fk_label.split(':')
51 self.column_label_for_object(obj, column_name)
52 return ("<script>parent.cat_browse.columns_saved('%s','%s');"
53 "</script>" % (object_name, context))
54
61
68
90
92 for column in obj.sqlmeta.columns.values():
93 if column.origName == filter[0]:
94 return getattr(obj.q, column.name) == filter[1]
95
96 msg = ('filter_column_error.'
97 ' Could not find the column for filter: %s' % filter[0])
98 raise cherrypy.HTTPRedirect(turbogears.url('/error', msg=msg))
99
110
133
135 joins = {}
136 ids = rows.keys()
137 if not ids:
138 return joins
139
140 obj = self.load_object(object_name)
141 conn = obj._connection
142 for column in obj.sqlmeta.joins:
143 query = None
144 coltype = self.get_column_type(column)
145 if coltype in ('SOMultipleJoin', 'SOSQLMultipleJoin'):
146 query = conn.sqlrepr(Select([
147 column.soClass.q.id,
148 func.Count(column.otherClass.q.id)],
149 where=AND(
150 column.soClass.q.id==self.join_foreign_key(column),
151 IN(column.soClass.q.id, ids)),
152 groupBy=column.soClass.q.id))
153
154 elif coltype in ('SORelatedJoin', 'SOSQLRelatedJoin'):
155 d = (column.intermediateTable,
156 column.joinColumn,
157 column.intermediateTable,
158 column.otherColumn,
159 column.intermediateTable,
160 column.intermediateTable,
161 column.joinColumn,
162 ','.join(['%s' % x for x in ids]),
163 column.intermediateTable,
164 column.joinColumn)
165
166 query = ("SELECT %s.%s, Count(%s.%s) FROM %s"
167 " WHERE %s.%s IN(%s) GROUP BY %s.%s" % d)
168
169 elif coltype == 'SOSingleJoin':
170 alias = self.load_label_column_for_object(column.otherClassName)
171 query = conn.sqlrepr(Select([
172 column.soClass.q.id, getattr(column.otherClass.q, alias)],
173 where=AND(
174 column.soClass.q.id==self.join_foreign_key(column),
175 IN(column.soClass.q.id,ids))))
176
177 if not query:
178 continue
179 joins[column.joinMethodName] = conn.queryAll(query)
180 return joins
181
193
195 if not ids:
196 return {}
197 sql_object = self.load_object(column.foreignKey)
198 conn = sql_object._connection
199 query = conn.sqlrepr(Select(
200 [sql_object.q.id, getattr(sql_object.q, alias)],
201 where=IN(sql_object.q.id, ids)))
202 fk_values = {}
203 for id, alias in conn.queryAll(query):
204 fk_values[str(id)] = self.encode_label(alias)
205 return fk_values
206
208 try:
209 foreign_key = '%sID' % column.joinColumn.rsplit('_', 1)[0]
210 return getattr(column.otherClass.q, foreign_key)
211 except AttributeError:
212 raise AttributeError("Key %r in %s pointing to %s not found.\n"
213 "You may need to rename it or use the joinColumn argument."
214 % (foreign_key,
215 column.otherClass.__name__, column.soClass.__name__,))
216
218 foreign_key_labels = [{'name': 'id', 'title': '#'}]
219 foreign_key_labels.extend(self.column_labels(column.foreignKey))
220 return foreign_key_labels
221
223 cols = []
224 sql_object = self.load_object(object_name)
225 for column_name in sql_object.sqlmeta.columns:
226 column = sql_object.sqlmeta.columns[column_name]
227 if sql_object._inheritable and column_name == 'childName':
228 continue
229 cols.append({'name': column.name,
230 'title': self.column_title(column)})
231 col = cols[-1]
232 if isinstance(column, sqlobject.col.SOForeignKey):
233 col['name'] = col['name'].replace('ID', '')
234 if extended:
235 col['type'] = self.get_column_type(column)
236 if isinstance(column, sqlobject.col.SOForeignKey):
237 col['column_label'] = self.load_label_column_for_object(
238 column.foreignKey)
239 col['label_options'] = self.column_label_options(column)
240 col['other_class_name'] = column.foreignKey
241 return cols
242
244 cols = []
245 sql_object = self.load_object(object_name)
246 for col in sql_object.sqlmeta.joins:
247 cols.append({'name': col.joinMethodName, 'title': ''})
248 if extended:
249 cols[-1]['type'] = self.get_column_type(col)
250 cols[-1]['other_class_name'] = col.otherClassName
251 return cols
252
262
264 foreign_keys = []
265 sql_object = self.load_object(object_name)
266 for column_name in sql_object.sqlmeta.columns:
267 column = sql_object.sqlmeta.columns[column_name]
268 if sql_object._inheritable and column_name == 'childName':
269 continue
270 if isinstance(column, sqlobject.col.SOForeignKey):
271 foreign_keys.append(column)
272 return foreign_keys
273
279
280 - def fields(self, object_name, result):
281 obj = self.load_object(object_name)
282 props = {}
283 props['id'] = result.id
284 for column_name in obj.sqlmeta.columns:
285 column = obj.sqlmeta.columns[column_name]
286 if obj._inheritable and column_name == 'childName':
287 continue
288 column_name = column.name
289 if isinstance(column, sqlobject.col.SOForeignKey):
290 column_name = column_name.replace('ID', '')
291 props[column_name] = self.field_value(result, column)
292 return props.copy()
293