Programming
6. models
"""
One model. It is a job record, not a data store — the data lives in parquet.
Why a model at all, when the HTML could just be written to disk: a run takes
minutes, so the browser cannot wait for it. The row is how the page polls for
progress, and how you find last month's report without regenerating it.
"""
from __future__ import annotations
from django.db import models
class ReportRun(models.Model):
PENDING, RUNNING, DONE, FAILED = "pending", "running", "done", "failed"
STATUS = [(PENDING, "в очереди"), (RUNNING, "выполняется"),
(DONE, "готов"), (FAILED, "ошибка")]
# request parameters
period_from = models.IntegerField(null=True, blank=True)
period_to = models.IntegerField(null=True, blank=True)
selected_period = models.IntegerField(null=True, blank=True)
# identity of (parameters + input files) — lets an identical request reuse
# a finished report instead of spending minutes rebuilding it
fingerprint = models.CharField(max_length=32, blank=True, db_index=True)
# progress
status = models.CharField(max_length=10, choices=STATUS, default=PENDING)
step = models.CharField(max_length=120, blank=True)
error = models.TextField(blank=True)
# result
html_path = models.CharField(max_length=500, blank=True)
stats = models.JSONField(default=dict, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
finished_at = models.DateTimeField(null=True, blank=True)
created_by = models.CharField(max_length=150, blank=True)
class Meta:
ordering = ["-created_at"]
indexes = [models.Index(fields=["-created_at"]),
models.Index(fields=["status"])]
def __str__(self):
return f"#{self.pk} {self.selected_period or 'последний'} [{self.status}]"
@property
def seconds(self):
end = self.finished_at or self.created_at
return round((end - self.created_at).total_seconds(), 1)
@property
def is_active(self):
return self.status in (self.PENDING, self.RUNNING)
PO
powerty
Muallif
· Staff
Okt. 8, 2026
Okt. 8, 2026
25
Ko'rishlar
0
Yoqishlar
1m
O'qildi