The filter form is a form that is used to filter the data to be used in the report.
Behind the scene, The view calls slick_reporting.form_factory.report_form_factory
in get_form_class
method. report_form_factory
is a helper method which generates a form containing start date and end date, as well as all foreign keys on the report_model.
Changing the generated form API is still private, however, you can use your own form easily.
The system expect that the form used with the ReportView
to implement the slick_reporting.forms.BaseReportForm
interface.
The interface is simple, only 3 mandatory methods to implement, The rest are mandatory only if you are working with a crosstab report or a time series report.
get_filters
: Mandatory, return a tuple (Q_filters , kwargs filter) to be used in filtering. q_filter: can be none or a series of Django's Q queries kwargs_filter: None or a dictionary of filtersget_start_date
: Mandatory, return the start date of the report.get_end_date
: Mandatory, return the end date of the report.get_crispy_helper
: Optional, return a crispy form helper to be used in rendering the form.
In case you are working with a crosstab report, you need to implement the following methods:
get_crosstab_compute_remainder
: return a boolean indicating if the remainder should be computed or not.get_crosstab_ids
: return a list of ids to be used in the crosstab report.
And in case you are working with a time series report, with a selector on, you need to implement the following method:
get_time_series_pattern
: return a string representing the time series pattern. ie:ie: daily, monthly, yearly
Example a full example of a custom form:
# forms.py
from slick_reporting.forms import BaseReportForm
# A Normal form , Inheriting from BaseReportForm
class RequestLogForm(BaseReportForm, forms.Form):
SECURE_CHOICES = (
("all", "All"),
("secure", "Secure"),
("non-secure", "Not Secure"),
)
start_date = forms.DateField(
required=False,
label="Start Date",
widget=forms.DateInput(attrs={"type": "date"}),
)
end_date = forms.DateField(
required=False, label="End Date", widget=forms.DateInput(attrs={"type": "date"})
)
secure = forms.ChoiceField(
choices=SECURE_CHOICES, required=False, label="Secure", initial="all"
)
method = forms.CharField(required=False, label="Method")
response = forms.ChoiceField(
choices=HTTP_STATUS_CODES,
required=False,
label="Response",
initial="200",
)
other_people_only = forms.BooleanField(
required=False, label="Show requests from other People Only"
)
def __init__(self, *args, **kwargs):
super(RequestLogForm, self).__init__(*args, **kwargs)
# provide initial values and ay needed customization
self.fields["start_date"].initial = datetime.date.today()
self.fields["end_date"].initial = datetime.date.today()
def get_filters(self):
# return the filters to be used in the report
# Note: the use of Q filters and kwargs filters
filters = {}
q_filters = []
if self.cleaned_data["secure"] == "secure":
filters["is_secure"] = True
elif self.cleaned_data["secure"] == "non-secure":
filters["is_secure"] = False
if self.cleaned_data["method"]:
filters["method"] = self.cleaned_data["method"]
if self.cleaned_data["response"]:
filters["response"] = self.cleaned_data["response"]
if self.cleaned_data["other_people_only"]:
q_filters.append(~Q(user=self.request.user))
return q_filters, filters
def get_start_date(self):
return self.cleaned_data["start_date"]
def get_end_date(self):
return self.cleaned_data["end_date"]
# ----
# in views.py
from .forms import RequestLogForm
class RequestCountByPath(ReportView):
form_class = RequestLogForm
You can view this code snippet in action on the demo project https://django-slick-reporting.com/total-product-sales-with-custom-form/