Browse Source

Fix duplicate normas/matérias in author reports and prevent unfiltered queries

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 <noreply@anthropic.com>
3.1.x
Edward Ribeiro 2 days ago
parent
commit
3b5e3747b7
  1. 6
      sapl/relatorios/forms.py
  2. 9
      sapl/relatorios/views.py
  3. 14
      sapl/templates/relatorios/RelatorioMateriasPorAutor_filter.html
  4. 8
      sapl/templates/relatorios/RelatorioNormasPorAutor_filter.html

6
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):

9
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'])

14
sapl/templates/relatorios/RelatorioMateriasPorAutor_filter.html

@ -17,7 +17,7 @@
&emsp;Tipo de matéria: {{ tipo }}<br />
&emsp;Data de apresentação: {{ periodo }}<br /><br /><br/>
{% if materias_resultado %}
{% if object_list %}
<table class="table table-bordered table-hover">
<thead class="thead-default" >
<tr class="active">
@ -43,10 +43,10 @@
<tr class="active">
<th width="10%">Matéria</th>
<th>Ementa</th>
<th width="20%">Autor(es)</th>
<th width="20%">Coautor(es)</th>
</tr>
</thead>
{% for materia in materias_resultado %}
{% for materia in object_list %}
<tbody>
<tr>
<td>
@ -56,11 +56,9 @@
</td>
<td>{% autoescape off %}{{materia.ementa}}<br>{{materia.observacao}}{% endautoescape %}</td>
<td>
{% for autor in materia.autoria_set.all %}
{% if not autor.primeiro_autor %}
{{ autor.autor }}<br />
{% else %}
<u><b><i>{{ autor.autor }}</i></b></u><br />
{% for autoria in materia.autoria_set.all %}
{% if autoria.autor != autor %}
{{ autoria.autor }}<br />
{% endif %}
{% endfor %}
</td>

8
sapl/templates/relatorios/RelatorioNormasPorAutor_filter.html

@ -54,13 +54,11 @@
</a></td>
<td>{% autoescape off %}{{norma.ementa}}<br>{{norma.observacao}}{% endautoescape %}</td>
<td>
{% if norma.autorianorma_set.first != norma.autorianorma_set.last %}
{% for autor in norma.autorianorma_set.all %}
{% if not autor.primeiro_autor %}
{{ autor.autor }}<br />
{% for autoria in norma.autorianorma_set.all %}
{% if autoria.autor != autor %}
{{ autoria.autor }}<br />
{% endif %}
{% endfor %}
{% endif %}
</td>
</tr>
</tbody>

Loading…
Cancel
Save