From 3b5e3747b7d7b5223e03f2fde2fa0fb2bdb91d10 Mon Sep 17 00:00:00 2001 From: Edward Oliveira Date: Fri, 10 Jul 2026 23:28:27 -0300 Subject: [PATCH] =?UTF-8?q?Fix=20duplicate=20normas/mat=C3=A9rias=20in=20a?= =?UTF-8?q?uthor=20reports=20and=20prevent=20unfiltered=20queries?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RelatorioNormasPorAutorFilterSet: chaining .filter(autorianorma__primeiro_autor=True) after the filterset's own autorianorma__autor filter created a second JOIN, causing each norma to appear once per Autoria with primeiro_autor=True. Removing that filter leaves a single JOIN so DISTINCT works correctly. Both filtersets now return none() when no author is selected, preventing a full-table scan with an unguarded ORDER BY on a related field. Both views pass the Autor object (not str) into context so the templates can compare autoria.autor != autor by PK. Both templates now show only co-authors (those different from the filtered author) in the Coautor(es) column, mirroring each other. RelatorioMateriasPorAutorView: removed the OrderedDict.fromkeys() deduplication workaround that was masking the same underlying JOIN issue. Co-Authored-By: Claude Sonnet 4.6 --- sapl/relatorios/forms.py | 6 +++++- sapl/relatorios/views.py | 9 ++++----- .../RelatorioMateriasPorAutor_filter.html | 14 ++++++-------- .../relatorios/RelatorioNormasPorAutor_filter.html | 8 +++----- 4 files changed, 18 insertions(+), 19 deletions(-) diff --git a/sapl/relatorios/forms.py b/sapl/relatorios/forms.py index 23145f899..f659c254c 100644 --- a/sapl/relatorios/forms.py +++ b/sapl/relatorios/forms.py @@ -633,6 +633,8 @@ class RelatorioMateriasPorAutorFilterSet(django_filters.FilterSet): @property def qs(self): parent = super().qs + if not self.data.get('autoria__autor'): + return parent.none() return parent.distinct().order_by('-ano', '-numero', 'tipo', 'autoria__autor', '-autoria__primeiro_autor') class Meta(FilterOverridesMetaMixin): @@ -744,7 +746,9 @@ class RelatorioNormasPorAutorFilterSet(django_filters.FilterSet): @property def qs(self): parent = super().qs - return parent.distinct().filter(autorianorma__primeiro_autor=True) \ + if not self.data.get('autorianorma__autor'): + return parent.none() + return parent.distinct() \ .order_by('autorianorma__autor', '-autorianorma__primeiro_autor', 'tipo', '-ano', '-numero') class Meta(FilterOverridesMetaMixin): diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py index bc28b3ffc..60ba1635e 100755 --- a/sapl/relatorios/views.py +++ b/sapl/relatorios/views.py @@ -2660,7 +2660,6 @@ class RelatorioMateriasPorAutorView(RelatorioMixin, FilterView): return context qs = context['object_list'] - context['materias_resultado'] = list(collections.OrderedDict.fromkeys(qs)) context['qtdes'] = num_materias_por_tipo(qs) qr = self.request.GET.copy() @@ -2675,9 +2674,9 @@ class RelatorioMateriasPorAutorView(RelatorioMixin, FilterView): context['tipo'] = '' if self.request.GET['autoria__autor']: autor = int(self.request.GET['autoria__autor']) - context['autor'] = (str(Autor.objects.get(id=autor))) + context['autor'] = Autor.objects.get(id=autor) else: - context['autor'] = '' + context['autor'] = None context['periodo'] = ( self.request.GET['data_apresentacao_0'] + ' - ' + self.request.GET['data_apresentacao_1']) @@ -2921,9 +2920,9 @@ class RelatorioNormasPorAutorView(RelatorioMixin, FilterView): if self.request.GET['autorianorma__autor']: autor = int(self.request.GET['autorianorma__autor']) - context['autor'] = (str(Autor.objects.get(id=autor))) + context['autor'] = Autor.objects.get(id=autor) else: - context['autor'] = '' + context['autor'] = None context['periodo'] = ( self.request.GET['data_0'] + ' - ' + self.request.GET['data_1']) diff --git a/sapl/templates/relatorios/RelatorioMateriasPorAutor_filter.html b/sapl/templates/relatorios/RelatorioMateriasPorAutor_filter.html index 5acb303c1..dcd7287e0 100644 --- a/sapl/templates/relatorios/RelatorioMateriasPorAutor_filter.html +++ b/sapl/templates/relatorios/RelatorioMateriasPorAutor_filter.html @@ -17,7 +17,7 @@  Tipo de matéria: {{ tipo }}
 Data de apresentação: {{ periodo }}


- {% if materias_resultado %} + {% if object_list %} @@ -43,10 +43,10 @@ - + - {% for materia in materias_resultado %} + {% for materia in object_list %} diff --git a/sapl/templates/relatorios/RelatorioNormasPorAutor_filter.html b/sapl/templates/relatorios/RelatorioNormasPorAutor_filter.html index c3f045301..51c987c34 100644 --- a/sapl/templates/relatorios/RelatorioNormasPorAutor_filter.html +++ b/sapl/templates/relatorios/RelatorioNormasPorAutor_filter.html @@ -54,13 +54,11 @@
Matéria EmentaAutor(es)Coautor(es)
@@ -56,11 +56,9 @@ {% autoescape off %}{{materia.ementa}}
{{materia.observacao}}{% endautoescape %}
- {% for autor in materia.autoria_set.all %} - {% if not autor.primeiro_autor %} - {{ autor.autor }}
- {% else %} - {{ autor.autor }}
+ {% for autoria in materia.autoria_set.all %} + {% if autoria.autor != autor %} + {{ autoria.autor }}
{% endif %} {% endfor %}
{% autoescape off %}{{norma.ementa}}
{{norma.observacao}}{% endautoescape %}
- {% if norma.autorianorma_set.first != norma.autorianorma_set.last %} - {% for autor in norma.autorianorma_set.all %} - {% if not autor.primeiro_autor %} - {{ autor.autor }}
+ {% for autoria in norma.autorianorma_set.all %} + {% if autoria.autor != autor %} + {{ autoria.autor }}
{% endif %} {% endfor %} - {% endif %}