Computation Field API
Responsible for preforming the calculation.
ReportField Basic Structure:
Earlier in he docs you saw the computation fields '__total__quantity__'
Let’s see how it’s written in slick_reporting.fields
from slick_reporting.fields import SlickReportField
from slick_reporting.decorators import report_field_register
@report_field_register
class TotalQTYReportField(SlickReportField):
# The name to use when using this field in the generator
name = '__total_quantity__'
# the field we want to compute on
calculation_field = 'quantity'
# What method we want
calculation_method = Sum # the default
# A verbose name
verbose name = 'Total quantity'
If you want AVG to the field price then the ReportField would look like this
from django.db.models import Avg
@report_field_register
class TotalQTYReportField(SlickReportField):
name = '__avg_price__'
calculation_field = 'price'
calculation_method = Avg
verbose name = 'Avg. Price'
How it works ?
The ReportGenerator is initialized with the needed configuration, it generates a list of the needed fields to be displayed and computed. For each computation field, it’s given the filters needed and asked to get all the results prepared. The preparation is a duty of the ReportField anyway, then for each report_model record, the ReportGenerator again asks each ComputationField to get the data it has for each record and map it where it belongs.
Bundled Report Fields
__total__ : Sum of the field names value
__total_quantity__ :Sum of the field names ‘quantity’
__fb__ : Sum of the field value on the start date (or the start date of the active time series window)
__balance__: Compound some of the field value .
Difference between total and balance is:
The field __total__ will return that client 1 bought 10 in Jan, 12 in Feb , 13 in March. while __balance__ will report client compound buy: 10 in Jan, 22 in Feb and 35 in March
Registering Report Field
To make this ReportField class available to the report, it has to be registered via report_field_register
Say you want to further customize your calculation, maybe you need to run a complex query
You can override both of those method and control the calculation
Calculation Flow:
ReportGenerator call
prepare
resolve
Two side calculation
# todo: # Document how a single field can be computed like a debit and credit.
SlickReportField API
- class slick_reporting.fields.SlickReportField(*args, **kwargs)[source]
Computation field responsible for making the calculation unit
- name = ''
The name to be used in the ReportGenerator
- calculation_field = 'value'
the Field to compute on
- calculation_method = <class 'django.db.models.aggregates.Sum'>
The computation Method
- verbose_name = None
Verbose name to be used in front end when needed
- requires = None
This can be a list of sibling classes, they will be asked to compute and their value would be available to you in the resolve method requires = [BasicCalculationA, BasicCalculationB]
- type = 'number'
Just a string describing what this computation field return, usually passed to frontend
Below are some data passed by the ReportGenerator, for extra manipulation, you can change them
- report_model = None
- group_by = None
- plus_side_q = None
- minus_side_q = None
You can customize those methods for maximum control where you can do pretty much whatever you want.
- prepare(q_filters=None, kwargs_filters=None, **kwargs)[source]
This is the first hook where you can customize the calculation away from the Django Query aggregation method This method et called with all available parameters , so you can prepare the results for the whole set and save it in a local cache (like self._cache) . The flow will later call the method resolve, giving you the id, for you to return it respective calculation
- Parameters
q_filters –
kwargs_filters –
kwargs –
- Returns
- resolve(current_obj, current_row=None)[source]
Reponsible for getting the exact data from the prepared value :param cached: the returned data from prepare :param current_obj: he value of group by id :param current_row: the row in iteration :return: a solid number or value
- get_dependency_value(current_obj, name=None)[source]
Get the values of the ReportFields specified in requires
- Parameters
current_obj – the current object which we want the calculation for
name – Optional, the name of the specific dependency you want.
- Returns
a dict containing dependencies names as keys and their calculation as values or a specific value if name is specified.