la catégorisation automatique fonctionne par somme des poids

Fix #169
This commit is contained in:
Jean-Marie Favreau 2024-10-30 16:16:16 +01:00
parent 17bc54685d
commit d267642268
4 changed files with 29 additions and 7 deletions

View File

@ -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'),
),
]

View File

@ -1561,7 +1561,7 @@ class CategorisationRule(models.Model):
weight = models.IntegerField( weight = models.IntegerField(
verbose_name=_("Weight"), verbose_name=_("Weight"),
help_text=_("The lower is the weight, the earlier the filter is applied"), help_text=_("The lower is the weight, the earlier the filter is applied"),
default=0, default=1,
) )
category = models.ForeignKey( category = models.ForeignKey(
@ -1643,14 +1643,18 @@ class CategorisationRule(models.Model):
return 1 return 1
def get_category_from_rules(event): def get_category_from_rules(event):
cats = defaultdict(lambda: 0)
if CategorisationRule.rules is None: 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: for rule in CategorisationRule.rules:
if rule.match(event): if rule.match(event):
return rule.category cats[rule.category] += rule.weight
if len(cats) == 0:
return None return None
else:
return max(cats, key=cats.get)
def match(self, event): def match(self, event):
if self.description_contains and self.description_contains != "": if self.description_contains and self.description_contains != "":

View File

@ -22,9 +22,9 @@
<a href="{% url 'add_catrule'%}" role="button">Ajouter {% picto_from_name "plus-circle" %}</a> <a href="{% url 'add_catrule'%}" role="button">Ajouter {% picto_from_name "plus-circle" %}</a>
</div> </div>
<h1>Règles de catégorisation</h1> <h1>Règles de catégorisation</h1>
<p>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.</p>
<p>Une règle est satisfaite si toutes ses conditions sont satisfaites.</p> <p>Une règle est satisfaite si toutes ses conditions sont satisfaites.</p>
<p>Les règles sont appliquées à l'import sur tous les événements, et à la demande sur les événements sans catégorie.</p> <p>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.</p>
<p>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.</p>
</header> </header>
<table role="grid"> <table role="grid">

View File

@ -1638,7 +1638,7 @@ def set_duplicate(request, year, month, day, pk):
@login_required(login_url="/accounts/login/") @login_required(login_url="/accounts/login/")
@permission_required("agenda_culturel.view_categorisationrule") @permission_required("agenda_culturel.view_categorisationrule")
def categorisation_rules(request): 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") page = request.GET.get("page")
try: try: