.. index:: pair: Python ; dataclass .. _django_dataclass: ============================================ Use of **dataclass** ============================================ .. seealso:: - :ref:`python_typing` - :ref:`dataclasses` .. code-block:: python :linenos: """Calcul des statistiques journalière d'utilisation des programmes. Exemples d'appel ================= :: python manage_dev.py update_stats_day [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:59] update_stats_day() [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:85] stat_product_name.product_name='XXXXXXXXXXXXXXXXXX' stat_product_name.nb_total_logs=7 [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:88] - version.version='2.9.7' version.nb_logs=3 (42.86%) [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:88] - version.version='2.7.0' version.nb_logs=2 (28.57%) [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:88] - version.version='2.6.1' version.nb_logs=2 (28.57%) [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:85] stat_product_name.product_name='YYYYYYYYYYYYYYYYYY' stat_product_name.nb_total_logs=2 [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:88] - version.version='2.9.7' version.nb_logs=1 (50.00%) [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:88] - version.version='2.7.0' version.nb_logs=1 (50.00%) [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:85] stat_product_name.product_name='ZZZZZZZZZZZZZZZZ' stat_product_name.nb_total_logs=1 [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:88] - version.version='2.7.2' version.nb_logs=1 (100.00%) [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:85] stat_product_name.product_name='AAAAAAAAAAAAAAAAa' stat_product_name.nb_total_logs=1 [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:88] - version.version='2.0.0' version.nb_logs=1 (100.00%) [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:85] stat_product_name.product_name='BBBBBBBBBBBBBBBBBBB' stat_product_name.nb_total_logs=1 [10/Feb/2020 14:14:23] INFO [logs.management.commands.update_stats_day:88] - version.version='1.3.38' version.nb_logs=1 (100.00%) """ import logging import pendulum from typing import List, Dict from django.core.management.base import BaseCommand from programs.models import Program from logs.models import LogHardwareId logger = logging.getLogger(__name__) from dataclasses import dataclass, field @dataclass class StatsProductNameVersion: product_name: str version: str = "" nb_logs: int = 0 stats_product_name: "StatsProductName" = None @property def percent_logs(self): percent = "" p = self.nb_logs / self.stats_product_name.nb_total_logs percent = f"({p:.2%})" return percent @dataclass class StatsProductName: product_name: str nb_total_logs: int = 0 versions: List[StatsProductNameVersion] = field(default_factory=list) logger = logging.getLogger(__name__) class Command(BaseCommand): """Calcul des statistiques journalières d'utilisation des programmes.""" def add_arguments(self, parser): """ - https://docs.python.org/3/library/argparse.html """ def handle(self, *args, **options): logger.info("update_stats_day()") now = pendulum.now() list_stats_product_name = [] for product_name in Program.objects.filter(version_is_ready=True).values_list("product_name", flat=True).distinct(): stats_product_name = StatsProductName(product_name=product_name) logs_hardware = LogHardwareId.objects.filter( date_connexion__year=now.year, date_connexion__month=now.month, date_connexion__day=now.day, product_name=product_name, ).order_by("product_name", "-version") if logs_hardware.exists(): # il existe des logs hardware pour ce programme (product_name) list_stats_product_name.append(stats_product_name) stats_product_name.nb_total_logs = len(logs_hardware) current_version = None for log in logs_hardware: if current_version is None or current_version != log.version: # nouvelle version ou changement de version product_name_version = StatsProductNameVersion(product_name=product_name, version=log.version, stats_product_name=stats_product_name) current_version = log.version stats_product_name.versions.append(product_name_version) product_name_version.nb_logs = product_name_version.nb_logs + 1 for stat_product_name in list_stats_product_name: logger.info(f"{stat_product_name.product_name=} {stat_product_name.nb_total_logs=}") for version in stat_product_name.versions: logger.info(f" - {version.version=} {version.nb_logs=} {version.percent_logs}")