Skip to content
Snippets Groups Projects
Commit d6d3387c authored by LE GAC Renaud's avatar LE GAC Renaud
Browse files

Add a the class Selector to help building reports.

parent dabff8d0
No related branches found
No related tags found
No related merge requests found
""" Collection of controllers to build reports
"""
from plugin_dbui import Selector
def index():
"""Main Controller handling report.
......@@ -20,29 +22,12 @@ def report_2():
"""Return the url arguments
"""
vars = request.vars
fmt = vars.Foo1My_format
selector = Selector(db, extfield='my_format')
# user request a file with a specific format (latex,...)
# return to the browser na iframe balise with a new URL
# the browser will request the file locate at the url
# The iframe occupy all the space in the receiving container
# it is usefull for embeded application like acroread.
if fmt and fmt != 'html':
del vars.Foo1My_format
s = IFRAME(_id='MyId',
_frameborder=0,
_width="100%",
_height="100%",
_src=URL('reports', 'report_2.%s' % fmt, vars=vars)).xml()
# remove the field use to select the file format
# in order to avoid circular loop
del fmt
return s
# standart reponse
return dict(test=vars)
\ No newline at end of file
iframe = selector.download()
if iframe:
return iframe
# standart response with the selected values
return dict(test=selector.as_dict())
\ No newline at end of file
......@@ -68,6 +68,7 @@ from helper import (as_list,
rows_serializer)
from mapper import map_default, map_tabpanel
from navtree import Node
from report import Selector
from viewportmodifier import ViewportModifier
UNDEF = 'undefined'
......
""" Base tools to build report
A database report relies on four main components:
- A selector form allowing the user to defined conditions.
It can be build using a virtual database,
- The Selector class to decode the selected values and to build query.
- A controller to extract value from the selector and
to interrogate the database.
- A view to render the selected records.
A powerful mechanism is also in place to render the report in different format
like HTML, CSV, .... It relies on the Selector class, on the IFRAME and
on the view.
"""
from gluon import current
from gluon.html import IFRAME, URL
from gluon.storage import Storage
from helper import (decode_field,
get_foreign_field,
is_foreign_field,
is_table_with_foreign_fields)
class Selector(Storage):
"""Basic tool to build a report.
Decode the data send by the selector widget.
Build the query for a given table of the database.
All fields of the selector are attributes of this class.
They can be accessed via myselector.myfield or myselector['myfield'].
A mechanism is provide to download the report in different format
which can be selected by the user. It relies on the extfield and
on the method download. Inside a controller:
selector = Selector(db, extfield='format')
iframe = selector.download()
if iframe:
return iframe
"""
def __init__(self, db, extfield='format'):
self._db = db
self._ext_field = extfield
self._extension = None
# Decode the current request
for key in current.request.vars:
t = decode_field(key)
if len(t) != 2 :
continue
field = t[1]
if field == self._ext_field:
self._extension = current.request.vars[key]
elif field != 'id':
self[field] = current.request.vars[key]
def as_dict(self):
"""Return the selector fields and their values as a dictionary.
"""
di = {}
for field in self.fields():
di[field] = self[field]
return di
def download(self):
"""The report can be download and receive as a file with a given format.
this method initiate this process by return and IFRAME.
The IFRAME is used by the browser to download the file.
The file format is defined by one of the field of the list selector.
By default is it 'format'. It can be changed via the argument extfield
of the constructor.
The IFRAME contain and URL. it it the same as the one defined in the
current request (application/controller/function) but the extension
is defined by the format field.
In this process all data conversion are performed by the view.
"""
if self._extension and self._extension != 'html':
# remove the field use to select the file format
# in order to avoid circular loop
for key in current.request.vars:
t = decode_field(key)
if self._ext_field in t:
del current.request.vars[key]
break
# The new URL is equal to the one defined in the current
# request but with the proper extension
url = URL(current.request.function, extension=self._extension,
vars=current.request.vars)
# Return the IFRAME
# the browser will request the file locate at the URL of the IFRAME
# The IFRAME occupy all the space in the receiving container
# Useful for embedded pdf application.
return IFRAME(_frameborder=0,
_width="100%",
_height="100%",
_src=url)
return None
def fields(self):
"""Lists of fields defined in the selector.
"""
li = []
for k in self:
if not k.startswith('_'):
li.append(k)
return li
def query(self, tablename, exclude_fields=()):
"""Build the database query for the table tablename
including inner join for foreign keys and selector constraints.
The extfield and fields in the exclude_fields tuple are
not take into account.
"""
db = self._db
query = None
table = self._db[tablename]
# inner join for foreign keys
if is_table_with_foreign_fields(table):
for field in table:
if is_foreign_field(field):
k_table, k_field, k_id = get_foreign_field(field)
q = field == db[k_table][k_id]
if query:
query = (query) & (q)
else:
query = q
# constraint from the selector
for fieldname in self.fields():
if not self[fieldname] or \
fieldname in exclude_fields or \
fieldname == self._ext_field:
continue
q = db[tablename][fieldname] == self[fieldname]
if query:
query = (query) & (q)
else:
query = q
return query
\ No newline at end of file
--------------------------------- CHANGE LOG ----------------------------------
HEAD
0.4.9 (Oct 2012)
- New syntax for grid filter via the method GridModifier.append_filter.
- Improve the files organization for the model and javascript code.
- Enable tab scrolling in viewport.
......@@ -10,6 +8,7 @@ HEAD
- Add a new widget LinkedComboBox.
- Add a plugin pRegExp and remove custom widget app.form.TextField
and app.form.TextArea.
- Add a new python class Selector to help building reports
0.4.8.2 (Jul 2012)
- Consolidation version
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment