Source code for ferrosoft.apps.reporting.models
import pickle
from django.db import models
from django.urls import reverse
from django.utils.translation import gettext_lazy as _
from ferrosoft.apps.ferrobase.models import UUIDModel, StoredFile
from ferrosoft.importutils import import_object
[docs]
class ReportStatus(models.IntegerChoices):
NEW = 1, _("New")
CREATED = 2, _("Created")
FAILED = 3, _("Failed")
[docs]
class ReportManager(models.Manager):
[docs]
def get_queryset(self):
return super().get_queryset().select_related("document__owner")
[docs]
class Report(UUIDModel):
class Meta:
verbose_name = _("Report")
verbose_name_plural = _("Reports")
objects = ReportManager()
creation_time = models.DateTimeField(
verbose_name=_("Creation Time"),
auto_now_add=True,
)
status = models.IntegerField(
verbose_name=_("Status"),
choices=ReportStatus.choices,
default=ReportStatus.NEW,
)
document = models.ForeignKey(
StoredFile,
on_delete=models.CASCADE,
related_name="+",
verbose_name=_("File"),
)
func_name = models.CharField(
verbose_name=_("Function Name"),
)
func_args = models.BinaryField(
verbose_name=_("Function Arguments"),
)
func_kwargs = models.BinaryField(
verbose_name=_("Function Keyword Arguments"),
)
return_url = models.URLField(
verbose_name=_("Return URL"),
null=True,
)
[docs]
def get_absolute_url(self):
return reverse("reporting:generator", args=[self.pk])
[docs]
def generate_document(self) -> bytes:
func = import_object(self.func_name)
args = pickle.loads(self.func_args)
kwargs = pickle.loads(self.func_kwargs)
if func is None:
raise RuntimeError("Function not found: %s" % self.func_name)
pdf_blob = func(*args, report=self, **kwargs)
if not isinstance(pdf_blob, bytes):
raise RuntimeError("Function must return PDF bytes object")
return pdf_blob