From 7d151414d727f1aaf728f7c4a5f123737e4251e2 Mon Sep 17 00:00:00 2001 From: Raphael Odini Date: Fri, 20 Oct 2023 12:26:29 +0200 Subject: [PATCH] SiaeGroup: update annotated count --- lemarche/siaes/admin.py | 17 +++++------ lemarche/siaes/factories.py | 5 ++++ lemarche/siaes/models.py | 14 +++++++-- lemarche/siaes/tests.py | 14 +++++++++ .../templates/tenders/_card_list_item.html | 2 +- .../templates/tenders/_list_item_buyer.html | 2 +- .../templates/tenders/_list_item_network.html | 2 +- .../templates/tenders/_list_item_siae.html | 2 +- lemarche/tenders/models.py | 6 ++-- lemarche/tenders/tests.py | 30 +++++++++---------- 10 files changed, 61 insertions(+), 33 deletions(-) diff --git a/lemarche/siaes/admin.py b/lemarche/siaes/admin.py index 2c13c9863..9c8673d88 100644 --- a/lemarche/siaes/admin.py +++ b/lemarche/siaes/admin.py @@ -4,7 +4,6 @@ from django.contrib.contenttypes.admin import GenericTabularInline from django.contrib.gis import admin as gis_admin from django.db import models -from django.db.models import Count from django.urls import reverse from django.utils.html import format_html, mark_safe from fieldsets_with_inlines import FieldsetsInlineMixin @@ -717,14 +716,14 @@ def image_url_display(self, siae_image): @admin.register(SiaeGroup, site=admin_site) class SiaeGroupAdmin(admin.ModelAdmin): - list_display = ["id", "name", "nb_siaes", "created_at"] + list_display = ["id", "name", "siae_live_count_annotated_with_link", "created_at"] search_fields = ["id", "name"] search_help_text = "Cherche sur les champs : ID, Nom" prepopulated_fields = {"slug": ("name",)} autocomplete_fields = ["sectors"] readonly_fields = [f"{field}_last_updated" for field in SiaeGroup.TRACK_UPDATE_FIELDS] + [ - "nb_siaes", + "siae_live_count_annotated_with_link", "logo_url_display", "created_at", "updated_at", @@ -745,7 +744,7 @@ class SiaeGroupAdmin(admin.ModelAdmin): "year_constitution", "siae_count", "siae_count_last_updated", - "nb_siaes", + "siae_live_count_annotated_with_link", "employees_insertion_count", "employees_insertion_count_last_updated", "employees_permanent_count", @@ -782,15 +781,15 @@ class SiaeGroupAdmin(admin.ModelAdmin): def get_queryset(self, request): qs = super().get_queryset(request) - qs = qs.annotate(siae_count_live=Count("siaes", distinct=True)) + qs = qs.with_siae_stats() return qs - def nb_siaes(self, siae_group): + def siae_live_count_annotated_with_link(self, siae_group): url = reverse("admin:siaes_siae_changelist") + f"?groups__in={siae_group.id}" - return format_html(f'{siae_group.siae_count_live}') + return format_html(f'{siae_group.siae_live_count_annotated}') - nb_siaes.short_description = "Nombre de structures (live)" - nb_siaes.admin_order_field = "siae_count_live" + siae_live_count_annotated_with_link.short_description = "Nombre de structures (live)" + siae_live_count_annotated_with_link.admin_order_field = "siae_live_count_annotated" def logo_url_display(self, siae_group): if siae_group.logo_url: diff --git a/lemarche/siaes/factories.py b/lemarche/siaes/factories.py index 0a30ac020..f77bd586e 100644 --- a/lemarche/siaes/factories.py +++ b/lemarche/siaes/factories.py @@ -14,6 +14,11 @@ class Meta: name = factory.Faker("company", locale="fr_FR") # slug auto-generated + @factory.post_generation + def siaes(self, create, extracted, **kwargs): + if extracted: + self.siaes.add(*extracted) + class SiaeFactory(DjangoModelFactory): class Meta: diff --git a/lemarche/siaes/models.py b/lemarche/siaes/models.py index 945a97b45..06e0ea87e 100644 --- a/lemarche/siaes/models.py +++ b/lemarche/siaes/models.py @@ -64,6 +64,11 @@ def get_city_filter(perimeter, with_country=False): return filters +class SiaeGroupQuerySet(models.QuerySet): + def with_siae_stats(self): + return self.annotate(siae_live_count_annotated=Count("siaes", distinct=True)) + + class SiaeGroup(models.Model): TRACK_UPDATE_FIELDS = [ # set last_updated fields @@ -119,6 +124,8 @@ class SiaeGroup(models.Model): created_at = models.DateTimeField("Date de création", default=timezone.now) updated_at = models.DateTimeField("Date de modification", auto_now=True) + objects = models.Manager.from_queryset(SiaeGroupQuerySet)() + class Meta: verbose_name = "Groupement" verbose_name_plural = "Groupements" @@ -1124,9 +1131,10 @@ def siae_networks_changed(sender, instance, action, **kwargs): @receiver(m2m_changed, sender=Siae.groups.through) def siae_groups_changed(sender, instance, action, **kwargs): - if action in ("post_add", "post_remove", "post_clear"): - instance.group_count = instance.groups.count() - instance.save() + if isinstance(instance, Siae): + if action in ("post_add", "post_remove", "post_clear"): + instance.group_count = instance.groups.count() + instance.save() class SiaeUser(models.Model): diff --git a/lemarche/siaes/tests.py b/lemarche/siaes/tests.py index f1c2194e2..e80de8ec1 100644 --- a/lemarche/siaes/tests.py +++ b/lemarche/siaes/tests.py @@ -49,6 +49,20 @@ def test_update_last_updated_fields(self): self.assertNotEqual(siae_group.employees_insertion_count_last_updated, employees_insertion_count_last_updated) +class SiaeGroupQuerySetTest(TestCase): + @classmethod + def setUpTestData(cls): + cls.siae_1 = SiaeFactory() + cls.siae_2 = SiaeFactory(is_active=False) + cls.siae_group = SiaeGroupFactory() + cls.siae_group_with_siaes = SiaeGroupFactory(siaes=[cls.siae_1, cls.siae_2]) + + def test_with_siae_stats(self): + siae_group_queryset = SiaeGroup.objects.with_siae_stats() + self.assertEqual(siae_group_queryset.get(id=self.siae_group.id).siae_live_count_annotated, 0) + self.assertEqual(siae_group_queryset.get(id=self.siae_group_with_siaes.id).siae_live_count_annotated, 1) + + class SiaeModelTest(TestCase): def setUp(self): pass diff --git a/lemarche/templates/tenders/_card_list_item.html b/lemarche/templates/tenders/_card_list_item.html index 42ba2d889..0ce087f80 100644 --- a/lemarche/templates/tenders/_card_list_item.html +++ b/lemarche/templates/tenders/_card_list_item.html @@ -1,7 +1,7 @@