Computation Field API¶
Responsible for preforming the calculation.
ReportField Basic Structure:¶
Earlier in he docs you saw the computation fields
Let’s see how it’s written in slick_reporting.fields
from slick_reporting.fields import ComputationField from slick_reporting.decorators import report_field_register @report_field_register class TotalQTYReportField(ComputationField): # 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(ComputationField): 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
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
Two side calculation¶
# todo: # Document how a single field can be computed like a debit and credit.
ComputationField(plus_side_q=None, minus_side_q=None, report_model=None, queryset=None, calculation_field=None, calculation_method=None, date_field='', group_by=None, group_by_custom_querysets=None)¶
Computation field responsible for making the calculation unit
The name to be used in the ReportGenerator
the Field to compute on
calculation_method= <class 'django.db.models.aggregates.Sum'>¶
The computation Method
Verbose name to be used in front end when needed
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]
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
The model on which the computation would occur
You can customize those methods for maximum control where you can do pretty much whatever you want.
prepare(q_filters=None, kwargs_filters=None, queryset=None, **kwargs)¶
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
- q_filters –
- kwargs_filters –
- kwargs –
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 the values of the ReportFields specified in requires
- current_obj – the current object which we want the calculation for
- name – Optional, the name of the specific dependency you want.
a dict containing dependencies names as keys and their calculation as values or a specific value if name is specified.