From d26764226881d2d89960da3433df1dec17e92a4f Mon Sep 17 00:00:00 2001 From: Jean-Marie Favreau Date: Wed, 30 Oct 2024 16:16:16 +0100 Subject: [PATCH] =?UTF-8?q?la=20cat=C3=A9gorisation=20automatique=20foncti?= =?UTF-8?q?onne=20par=20somme=20des=20poids?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix #169 --- .../0092_alter_categorisationrule_weight.py | 18 ++++++++++++++++++ src/agenda_culturel/models.py | 12 ++++++++---- .../agenda_culturel/categorisation_rules.html | 4 ++-- src/agenda_culturel/views.py | 2 +- 4 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 src/agenda_culturel/migrations/0092_alter_categorisationrule_weight.py diff --git a/src/agenda_culturel/migrations/0092_alter_categorisationrule_weight.py b/src/agenda_culturel/migrations/0092_alter_categorisationrule_weight.py new file mode 100644 index 0000000..845a59e --- /dev/null +++ b/src/agenda_culturel/migrations/0092_alter_categorisationrule_weight.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.9 on 2024-10-30 14:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('agenda_culturel', '0091_duplicatedevents_fixed_event_masked'), + ] + + operations = [ + migrations.AlterField( + model_name='categorisationrule', + name='weight', + field=models.IntegerField(default=1, help_text='The lower is the weight, the earlier the filter is applied', verbose_name='Weight'), + ), + ] diff --git a/src/agenda_culturel/models.py b/src/agenda_culturel/models.py index 1bac81d..85894e2 100644 --- a/src/agenda_culturel/models.py +++ b/src/agenda_culturel/models.py @@ -1561,7 +1561,7 @@ class CategorisationRule(models.Model): weight = models.IntegerField( verbose_name=_("Weight"), help_text=_("The lower is the weight, the earlier the filter is applied"), - default=0, + default=1, ) category = models.ForeignKey( @@ -1643,14 +1643,18 @@ class CategorisationRule(models.Model): return 1 def get_category_from_rules(event): + cats = defaultdict(lambda: 0) if CategorisationRule.rules is None: - CategorisationRule.rules = CategorisationRule.objects.all().order_by("weight", "pk").prefetch_related("category").prefetch_related("place") + CategorisationRule.rules = CategorisationRule.objects.all().prefetch_related("category").prefetch_related("place") for rule in CategorisationRule.rules: if rule.match(event): - return rule.category + cats[rule.category] += rule.weight - return None + if len(cats) == 0: + return None + else: + return max(cats, key=cats.get) def match(self, event): if self.description_contains and self.description_contains != "": diff --git a/src/agenda_culturel/templates/agenda_culturel/categorisation_rules.html b/src/agenda_culturel/templates/agenda_culturel/categorisation_rules.html index ffa9321..f2f5863 100644 --- a/src/agenda_culturel/templates/agenda_culturel/categorisation_rules.html +++ b/src/agenda_culturel/templates/agenda_culturel/categorisation_rules.html @@ -22,9 +22,9 @@ Ajouter {% picto_from_name "plus-circle" %}

Règles de catégorisation

-

Chaque règle est considérée dans l'ordre croissant des poids. La première règle satisfaite est appliquée par un changement de catégorie, et on les suivantes ne sont pas appliquées.

Une règle est satisfaite si toutes ses conditions sont satisfaites.

-

Les règles sont appliquées à l'import sur tous les événements, et à la demande sur les événements sans catégorie.

+

Pour chaque catégorie, on calcule la somme des poids de chaque règle satisfaite sur un événement. La catégorie retenue pour un événement correspond à la somme la plus grande.

+

Les règles sont appliquées à l'import sur tous les événements, et à la demande sur tous les événements, avec confirmation dans le cas d'événements déjà catégorisés.

diff --git a/src/agenda_culturel/views.py b/src/agenda_culturel/views.py index bd16a2a..0ed28f8 100644 --- a/src/agenda_culturel/views.py +++ b/src/agenda_culturel/views.py @@ -1638,7 +1638,7 @@ def set_duplicate(request, year, month, day, pk): @login_required(login_url="/accounts/login/") @permission_required("agenda_culturel.view_categorisationrule") def categorisation_rules(request): - paginator = Paginator(CategorisationRule.objects.all().order_by("weight", "pk"), 10) + paginator = Paginator(CategorisationRule.objects.all().order_by("pk").prefetch_related("category").prefetch_related("place"), 100) page = request.GET.get("page") try: