Changes between Initial Version and Version 1 of S3XRC/ResourceReport


Ignore:
Timestamp:
08/28/10 10:07:43 (14 years ago)
Author:
Dominic König
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • S3XRC/ResourceReport

    v1 v1  
     1= S3XRC Mini-Tutorial =
     2
     3== Report Function for your Resource ==
     4
     5=== The Idea ===
     6
     7You have a module {{{xxx}}} and within it a resource {{{yyy}}}, which has a number of components. You're providing CRUD functions for the resource and its components using {{{shn_rest_controller()}}}.
     8
     9Now you want to provide a reporting function for this resource, where the user can select records using a search form and then generate a summary report that can be exported in various formats, among others XLS, PDF and SVG.
     10
     11This tutorial shows you how this can be integrated in the REST interface of your resource.
     12
     13=== Creating a Custom Method Handler ===
     14
     15First of all, implement your reporting function as a custom method handler. Add this function to your model file and add it as a method to your resource, like:
     16
     17{{{
     18def shn_xxx_yyy_report(r, **attr):
     19
     20    # Report generating code goes here
     21
     22s3xrc.model.set_method("xxx", "yyy", method="report", action=shn_xxx_yyy_report)
     23}}}
     24
     25A custom method handler has to take two arguments:
     26
     27  - {{{r}}} is the respective S3Request object, which represents the current request
     28  - {{{attr}}} is the same dict of named arguments that have been passed to shn_rest_controller
     29
     30Once you have done this, you can invoke your method handler from the URL:
     31
     32{{{
     33http://localhost:8000/eden/xxx/yyy/report
     34}}}
     35
     36The advantage of this is that this even understands URLs like:
     37
     38{{{
     39http://localhost:8000/eden/xxx/yyy/1/report
     40http://localhost:8000/eden/xxx/yyy/report?yyy.id=1,2,3
     41http://localhost:8000/eden/xxx/yyy/report?yyy.field1__like=abc
     42}}}
     43
     44meaning, it already implements a RESTful API for your reporting function, e.g. does the parsing/validating of the URL for you, implements the full range of URL queries for your resource and so forth. Nothing you need to care about now.
     45
     46=== Providing different Report Formats ===
     47
     48As mentioned before, you want to provide the report in various formats. To know which format has been requested, use r.representation:
     49
     50{{{
     51def shn_xxx_yyy_report(r, **attr):
     52
     53    if r.representation == "html":
     54        # HTML report generating code goes here
     55
     56    elif r.representation == "xls":
     57        # XLS report generating code goes here
     58
     59    elif r.representation == "pdf":
     60        # PDF report generating code goes here
     61
     62    elif r.representation == "svg":
     63        # SVG report generating code goes here
     64
     65    else:
     66        # Unsupported format
     67        raise HTTP(501, body=s3xrc.ERROR.BAD_FORMAT)
     68
     69s3xrc.model.set_method("xxx", "yyy", method="report", action=shn_xxx_yyy_report)
     70}}}
     71
     72Now your method handler recognises the requested format as specified in the URL by either a filename extension or the {{{format}}} variable:
     73
     74{{{
     75http://localhost:8000/eden/xxx/yyy/4/report.xls
     76http://localhost:8000/eden/xxx/yyy.pdf/6
     77http://localhost:8000/eden/xxx/yyy/report?format=svg
     78}}}
     79
     80=== How to get at the data ===
     81
     82Now, how can you which data have to be processed by your reporting function and how can you get at them?
     83
     84{{{r}}} (the {{{S3Request}}} object) contains the interface to the resource as an {{{S3Resource}}} object. And this is what you can use to access your data. Some examples:
     85
     86{{{
     87def shn_xxx_yyy_report(r, **attr):
     88
     89    resource = r.resource
     90
     91    if r.representation == "html":
     92
     93        # Get all records
     94        rows = resource.records()
     95
     96    elif r.representation == "xls":
     97
     98        # Access components record-wise:
     99        for record in resource:
     100            component_set = resource(record, component="component_name")
     101            for component_record in component_set:
     102                ...
     103
     104    elif r.representation == "pdf":
     105
     106        # Iterate through the records:
     107        for record in resource:
     108            ...
     109
     110    elif r.representation == "svg":
     111
     112        # Modifying the resource query before accessing records
     113        filter = resource.get_query()
     114        filter = filter & (db.xxx_yyy.field5 == "value")
     115        resource.build_query(filter = filter)
     116
     117        # Iterate through the records:
     118        for record in resource:
     119            ...
     120
     121    else:
     122        # Unsupported format
     123        raise HTTP(501, body=s3xrc.ERROR.BAD_FORMAT)
     124
     125s3xrc.model.set_method("xxx", "yyy", method="report", action=shn_xxx_yyy_report)
     126}}}
     127
     128...to be continued...