diff --git a/sapl/materia/migrations/0088_fix_view_materiaemtramitacao.py b/sapl/materia/migrations/0088_fix_view_materiaemtramitacao.py
new file mode 100644
index 000000000..1f3ca52d8
--- /dev/null
+++ b/sapl/materia/migrations/0088_fix_view_materiaemtramitacao.py
@@ -0,0 +1,62 @@
+from django.db import migrations, models
+
+_OLD_VIEW = """
+ create or replace view materia_materiaemtramitacao as
+ select m.id as id,
+ m.id as materia_id,
+ t.id as tramitacao_id,
+ t.unidade_tramitacao_destino_id as unidade_tramitacao_atual_id
+ from materia_materialegislativa m
+ inner join materia_tramitacao t on (m.id = t.materia_id)
+ where t.id = (select max(id) from materia_tramitacao where materia_id = m.id)
+ order by m.id DESC
+"""
+
+_NEW_VIEW = """
+ create or replace view materia_materiaemtramitacao as
+ select distinct on (m.id)
+ m.id as id,
+ m.id as materia_id,
+ t.id as tramitacao_id,
+ t.unidade_tramitacao_destino_id as unidade_tramitacao_atual_id
+ from materia_materialegislativa m
+ inner join materia_tramitacao t on t.materia_id = m.id
+ order by m.id desc, t.id desc
+"""
+
+
+class Migration(migrations.Migration):
+ # CREATE INDEX CONCURRENTLY cannot run inside a transaction.
+ atomic = False
+
+ dependencies = [
+ ('materia', '0087_update_viewdb_materiaemtramitacao'),
+ ]
+
+ operations = [
+ migrations.RunSQL(sql=_NEW_VIEW, reverse_sql=_OLD_VIEW),
+ migrations.SeparateDatabaseAndState(
+ database_operations=[
+ migrations.RunSQL(
+ sql="""
+ CREATE INDEX CONCURRENTLY IF NOT EXISTS
+ tram_materia_id_desc
+ ON materia_tramitacao (materia_id, id DESC)
+ """,
+ reverse_sql="""
+ DROP INDEX CONCURRENTLY IF EXISTS
+ tram_materia_id_desc
+ """,
+ ),
+ ],
+ state_operations=[
+ migrations.AddIndex(
+ model_name='tramitacao',
+ index=models.Index(
+ fields=['materia', '-id'],
+ name='tram_materia_id_desc',
+ ),
+ ),
+ ],
+ ),
+ ]
diff --git a/sapl/materia/models.py b/sapl/materia/models.py
index bdeb402e3..fb0df6ee5 100644
--- a/sapl/materia/models.py
+++ b/sapl/materia/models.py
@@ -1350,6 +1350,9 @@ class Tramitacao(models.Model):
verbose_name = _('Tramitação')
verbose_name_plural = _('Tramitações')
ordering = ('-data_tramitacao', '-id')
+ indexes = [
+ models.Index(fields=['materia', '-id'], name='tram_materia_id_desc'),
+ ]
def __str__(self):
return _('%(materia)s | %(status)s | %(data)s') % {
diff --git a/sapl/relatorios/forms.py b/sapl/relatorios/forms.py
index 23145f899..58868a061 100644
--- a/sapl/relatorios/forms.py
+++ b/sapl/relatorios/forms.py
@@ -543,9 +543,7 @@ class RelatorioMateriasTramitacaoFilterSet(django_filters.FilterSet):
@property
def qs(self):
parent = super(RelatorioMateriasTramitacaoFilterSet, self).qs
- return parent.distinct().order_by(
- '-materia__ano', 'materia__tipo', '-materia__numero'
- )
+ return parent.order_by('-materia__ano', 'materia__tipo', '-materia__numero')
class Meta:
model = MateriaEmTramitacao
diff --git a/sapl/relatorios/views.py b/sapl/relatorios/views.py
index 73c1494f2..25cd9ea21 100755
--- a/sapl/relatorios/views.py
+++ b/sapl/relatorios/views.py
@@ -51,8 +51,7 @@ from sapl.sessao.views import (get_identificacao_basica, get_mesa_diretora,
from sapl.settings import MEDIA_URL
from sapl.settings import STATIC_ROOT
from sapl.utils import LISTA_DE_UFS, TrocaTag, filiacao_data, create_barcode, show_results_filter_set, \
- num_materias_por_tipo, parlamentares_ativos, MultiFormatOutputMixin
-from sapl.middleware.ratelimit import smart_key, smart_rate
+ num_materias_por_tipo, parlamentares_ativos, MultiFormatOutputMixin, is_report_allowed
from .templates import (pdf_capa_processo_gerar,
pdf_documento_administrativo_gerar, pdf_espelho_gerar,
pdf_etiqueta_protocolo_gerar, pdf_materia_gerar,
@@ -60,8 +59,6 @@ from .templates import (pdf_capa_processo_gerar,
pdf_protocolo_gerar, pdf_sessao_plenaria_gerar)
from sapl.crud.base import make_pagination
-from ratelimit.decorators import ratelimit
-from django.utils.decorators import method_decorator
def get_kwargs_params(request, fields):
@@ -1850,26 +1847,18 @@ class RelatoriosListView(TemplateView):
class RelatorioMixin:
# TODO: verificar se todos os relatorios de sistema/relatorios extendem esse Mixin
def get(self, request, *args, **kwargs):
- super(RelatorioMixin, self).get(request)
-
- # TODO: import as global
- from sapl.utils import is_report_allowed
if not is_report_allowed(request):
raise Http404()
- is_relatorio = request.GET.get('relatorio')
- context = self.get_context_data(filter=self.filterset)
-
- if is_relatorio:
+ if request.GET.get('relatorio'):
+ filterset_class = self.get_filterset_class()
+ self.filterset = self.get_filterset(filterset_class)
+ context = self.get_context_data(filter=self.filterset)
return self.relatorio(request, context)
- else:
- return self.render_to_response(context)
+
+ return super(RelatorioMixin, self).get(request, *args, **kwargs)
-@method_decorator(ratelimit(key=smart_key,
- rate=smart_rate,
- block=True),
- name='dispatch')
class RelatorioDocumentosAcessoriosView(RelatorioMixin, FilterView):
model = DocumentoAcessorio
filterset_class = RelatorioDocumentosAcessoriosFilterSet
@@ -1914,10 +1903,6 @@ class RelatorioDocumentosAcessoriosView(RelatorioMixin, FilterView):
return context
-@method_decorator(ratelimit(key=smart_key,
- rate=smart_rate,
- block=True),
- name='dispatch')
class RelatorioVotacoesNominaisView(RelatorioMixin, MultiFormatOutputMixin, FilterView):
model = VotoParlamentar
filterset_class = RelatorioVotacoesNominaisFilterSet
@@ -1987,10 +1972,6 @@ class RelatorioVotacoesNominaisView(RelatorioMixin, MultiFormatOutputMixin, Filt
return context
-@method_decorator(ratelimit(key=smart_key,
- rate=smart_rate,
- block=True),
- name='dispatch')
class RelatorioAtasView(RelatorioMixin, FilterView):
model = SessaoPlenaria
filterset_class = RelatorioAtasFilterSet
@@ -2016,10 +1997,6 @@ class RelatorioAtasView(RelatorioMixin, FilterView):
return context
-@method_decorator(ratelimit(key=smart_key,
- rate=smart_rate,
- block=True),
- name='dispatch')
class RelatorioPresencaSessaoView(RelatorioMixin, FilterView):
logger = logging.getLogger(__name__)
model = SessaoPlenaria
@@ -2254,10 +2231,6 @@ class RelatorioPresencaSessaoView(RelatorioMixin, FilterView):
return context
-@method_decorator(ratelimit(key=smart_key,
- rate=smart_rate,
- block=True),
- name='dispatch')
class RelatorioHistoricoTramitacaoView(RelatorioMixin, FilterView):
model = MateriaLegislativa
filterset_class = RelatorioHistoricoTramitacaoFilterSet
@@ -2315,10 +2288,6 @@ class RelatorioHistoricoTramitacaoView(RelatorioMixin, FilterView):
return context
-@method_decorator(ratelimit(key=smart_key,
- rate=smart_rate,
- block=True),
- name='dispatch')
class RelatorioDataFimPrazoTramitacaoView(RelatorioMixin, FilterView):
model = MateriaEmTramitacao
filterset_class = RelatorioDataFimPrazoTramitacaoFilterSet
@@ -2382,10 +2351,6 @@ class RelatorioDataFimPrazoTramitacaoView(RelatorioMixin, FilterView):
return context
-@method_decorator(ratelimit(key=smart_key,
- rate=smart_rate,
- block=True),
- name='dispatch')
class RelatorioReuniaoView(RelatorioMixin, FilterView):
model = Reuniao
filterset_class = RelatorioReuniaoFilterSet
@@ -2420,10 +2385,6 @@ class RelatorioReuniaoView(RelatorioMixin, FilterView):
return context
-@method_decorator(ratelimit(key=smart_key,
- rate=smart_rate,
- block=True),
- name='dispatch')
class RelatorioAudienciaView(RelatorioMixin, FilterView):
model = AudienciaPublica
filterset_class = RelatorioAudienciaFilterSet
@@ -2458,10 +2419,6 @@ class RelatorioAudienciaView(RelatorioMixin, FilterView):
return context
-@method_decorator(ratelimit(key=smart_key,
- rate=smart_rate,
- block=True),
- name='dispatch')
class RelatorioMateriasTramitacaoView(RelatorioMixin, FilterView):
model = MateriaEmTramitacao
filterset_class = RelatorioMateriasTramitacaoFilterSet
@@ -2576,10 +2533,6 @@ class RelatorioMateriasTramitacaoView(RelatorioMixin, FilterView):
return context
-@method_decorator(ratelimit(key=smart_key,
- rate=smart_rate,
- block=True),
- name='dispatch')
class RelatorioMateriasPorAnoAutorTipoView(RelatorioMixin, FilterView):
model = MateriaLegislativa
filterset_class = RelatorioMateriasPorAnoAutorTipoFilterSet
@@ -2659,10 +2612,6 @@ class RelatorioMateriasPorAnoAutorTipoView(RelatorioMixin, FilterView):
return context
-@method_decorator(ratelimit(key=smart_key,
- rate=smart_rate,
- block=True),
- name='dispatch')
class RelatorioMateriasPorAutorView(RelatorioMixin, FilterView):
model = MateriaLegislativa
filterset_class = RelatorioMateriasPorAutorFilterSet
@@ -2734,10 +2683,6 @@ class RelatorioMateriaAnoAssuntoView(ListView):
return context
-@method_decorator(ratelimit(key=smart_key,
- rate=smart_rate,
- block=True),
- name='dispatch')
class RelatorioNormasPublicadasMesView(RelatorioMixin, FilterView):
model = NormaJuridica
filterset_class = RelatorioNormasMesFilterSet
@@ -2778,10 +2723,6 @@ class RelatorioNormasPublicadasMesView(RelatorioMixin, FilterView):
return context
-@method_decorator(ratelimit(key=smart_key,
- rate=smart_rate,
- block=True),
- name='dispatch')
class RelatorioNormasVigenciaView(RelatorioMixin, FilterView):
model = NormaJuridica
filterset_class = RelatorioNormasVigenciaFilterSet
@@ -2846,10 +2787,6 @@ class RelatorioNormasVigenciaView(RelatorioMixin, FilterView):
return context
-@method_decorator(ratelimit(key=smart_key,
- rate=smart_rate,
- block=True),
- name='dispatch')
class RelatorioHistoricoTramitacaoAdmView(RelatorioMixin, FilterView):
model = DocumentoAdministrativo
filterset_class = RelatorioHistoricoTramitacaoAdmFilterSet
@@ -2900,10 +2837,6 @@ class RelatorioHistoricoTramitacaoAdmView(RelatorioMixin, FilterView):
return context
-@method_decorator(ratelimit(key=smart_key,
- rate=smart_rate,
- block=True),
- name='dispatch')
class RelatorioNormasPorAutorView(RelatorioMixin, FilterView):
model = NormaJuridica
filterset_class = RelatorioNormasPorAutorFilterSet
diff --git a/sapl/sessao/views.py b/sapl/sessao/views.py
index 35c24eb18..5ca38cab1 100755
--- a/sapl/sessao/views.py
+++ b/sapl/sessao/views.py
@@ -9,7 +9,7 @@ from django.contrib import messages
from django.contrib.auth.decorators import permission_required
from django.contrib.auth.mixins import PermissionRequiredMixin
from django.core.exceptions import ObjectDoesNotExist
-from django.db.models import Max, Q
+from django.db.models import Max, Prefetch, Q
from django.http import JsonResponse
from django.http.response import Http404, HttpResponseRedirect
from django.urls import reverse
@@ -174,7 +174,7 @@ def verifica_sessao_iniciada(request, spk, is_leitura=False):
aux_text = 'leitura' if is_leitura else 'votação'
logger.info('user=' + username + '. Não é possível abrir matérias para {}. '
'Esta SessaoPlenaria (id={}) não foi iniciada ou está finalizada.'.format(
- aux_text, spk))
+ aux_text, spk))
msg = _('Não é possível abrir matérias para {}. '
'Esta Sessão Plenária não foi iniciada ou está finalizada.'
' Vá em "Abertura"->"Dados Básicos" e altere os valores dos campos necessários.'.format(aux_text))
@@ -226,38 +226,43 @@ def abrir_votacao(request, pk, spk):
def customize_link_materia(context, pk, has_permission, is_expediente):
+ # sessao_plenaria is the same for every row — resolve once
+ object_list = context['object_list']
+ if object_list:
+ sessao_plenaria = object_list[0].sessao_plenaria
+ else:
+ sessao_plenaria = SessaoPlenaria.objects.get(id=pk)
+ data_sessao = sessao_plenaria.data_fim or sessao_plenaria.data_inicio
+
for i, row in enumerate(context['rows']):
- materia = context['object_list'][i].materia
- obj = context['object_list'][i]
+ obj = object_list[i]
+ materia = obj.materia # already select_related
+
url_materia = reverse(
'sapl.materia:materialegislativa_detail', kwargs={'pk': materia.id})
- numeracao = materia.numeracao_set.first() if materia.numeracao_set.first() else "-"
- todos_autoria = materia.autoria_set.all()
- autoria = todos_autoria.filter(primeiro_autor=True)
+
+ numeracao = materia._numeracao_prefetch[0] if materia._numeracao_prefetch else "-"
+
+ todos_autoria = materia._autoria_prefetch
+ autoria = [a for a in todos_autoria if a.primeiro_autor]
autor = ', '.join([str(a.autor) for a in autoria]) if autoria else "-"
+ todos_autores = ', '.join([str(a.autor) for a in todos_autoria]) if autoria else "-"
- todos_autores = ', '.join([str(a.autor)
- for a in todos_autoria]) if autoria else "-"
+ num_protocolo = materia.numero_protocolo or "-"
- num_protocolo = materia.numero_protocolo if materia.numero_protocolo else "-"
- sessao_plenaria = SessaoPlenaria.objects.get(id=pk)
- data_sessao = sessao_plenaria.data_fim if sessao_plenaria.data_fim else sessao_plenaria.data_inicio
- tramitacao = Tramitacao.objects \
- .select_related('materia', 'status', 'materia__tipo') \
- .filter(materia=materia, turno__isnull=False, data_tramitacao__lte=data_sessao) \
- .exclude(turno__exact='') \
- .order_by('-data_tramitacao', '-id') \
- .first()
+ tramitacao = next(
+ (t for t in materia._tramitacao_prefetch if t.data_tramitacao <= data_sessao),
+ None,
+ )
turno = '-'
if tramitacao:
for t in Tramitacao.TURNO_CHOICES:
if t[0] == tramitacao.turno:
turno = t[1]
break
- materia_em_tramitacao = MateriaEmTramitacao.objects \
- .select_related("materia", "tramitacao") \
- .filter(materia=materia) \
- .first()
+
+ materia_em_tramitacao = materia._met_prefetch[0] if materia._met_prefetch else None
+
# idUnica para cada materia
idAutor = "autor" + str(i)
idAutores = "autores" + str(i)
@@ -283,12 +288,9 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
# url em toda a string de title_materia
context['rows'][i][1] = (title_materia, None)
- exist_resultado = obj.registrovotacao_set.filter(
- materia=obj.materia).exists()
- exist_retirada = obj.retiradapauta_set.filter(
- materia=obj.materia).exists()
- exist_leitura = obj.registroleitura_set.filter(
- materia=obj.materia).exists()
+ exist_resultado = bool(obj._votacao_prefetch)
+ exist_retirada = bool(obj._retirada_prefetch)
+ exist_leitura = bool(obj._leitura_prefetch)
if (obj.tipo_votacao != LEITURA and not exist_resultado and not exist_retirada) or \
(obj.tipo_votacao == LEITURA and not exist_leitura):
@@ -410,8 +412,7 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
resultado = '''Não há resultado'''
elif exist_retirada:
- retirada = obj.retiradapauta_set.filter(
- materia_id=obj.materia_id).last()
+ retirada = obj._retirada_prefetch[-1]
retirada_descricao = retirada.tipo_de_retirada.descricao
retirada_observacao = retirada.observacao
url = reverse('sapl.sessao:retiradapauta_detail',
@@ -423,13 +424,11 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
else:
if obj.tipo_votacao == LEITURA:
- resultado = obj.registroleitura_set.filter(
- materia_id=obj.materia_id).last()
+ resultado = obj._leitura_prefetch[-1]
resultado_descricao = "Matéria lida"
resultado_observacao = resultado.observacao
else:
- resultado = obj.registrovotacao_set.filter(
- materia_id=obj.materia_id).last()
+ resultado = obj._votacao_prefetch[-1]
resultado_descricao = resultado.tipo_resultado_votacao.nome
resultado_observacao = resultado.observacao
@@ -488,11 +487,11 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
'mid': obj.materia_id})
resultado = (
- '%s
%s' % (
- url,
- context.get('page', 1),
- resultado_descricao,
- resultado_observacao))
+ '%s
%s' % (
+ url,
+ context.get('page', 1),
+ resultado_descricao,
+ resultado_observacao))
else:
if obj.tipo_votacao == NOMINAL:
@@ -503,7 +502,7 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
'pk': obj.sessao_plenaria_id,
'oid': obj.pk,
'mid': obj.materia_id}) + \
- '?&materia=expediente'
+ '?&materia=expediente'
else:
url = reverse(
'sapl.sessao:votacao_nominal_transparencia',
@@ -511,7 +510,7 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
'pk': obj.sessao_plenaria_id,
'oid': obj.pk,
'mid': obj.materia_id}) + \
- '?&materia=ordem'
+ '?&materia=ordem'
resultado = ('%s
%s' %
(url,
@@ -526,7 +525,7 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
'pk': obj.sessao_plenaria_id,
'oid': obj.pk,
'mid': obj.materia_id}) + \
- '?&materia=expediente'
+ '?&materia=expediente'
else:
url = reverse(
'sapl.sessao:votacao_simbolica_transparencia',
@@ -534,7 +533,7 @@ def customize_link_materia(context, pk, has_permission, is_expediente):
'pk': obj.sessao_plenaria_id,
'oid': obj.pk,
'mid': obj.materia_id}) + \
- '?&materia=ordem'
+ '?&materia=ordem'
resultado = ('%s
%s' %
(url,
@@ -798,7 +797,7 @@ class MateriaOrdemDiaCrud(MasterDetailCrud):
sessao_plenaria=self.kwargs['pk']).aggregate(
Max('numero_ordem'))['numero_ordem__max']
self.initial['numero_ordem'] = (
- max_numero_ordem if max_numero_ordem else 0) + 1
+ max_numero_ordem if max_numero_ordem else 0) + 1
return self.initial
def get_success_url(self):
@@ -835,20 +834,58 @@ class MateriaOrdemDiaCrud(MasterDetailCrud):
layout_key = 'OrdemDiaDetail'
class ListView(MasterDetailCrud.ListView):
- paginate_by = None
+ paginate_by = 100
ordering = ['numero_ordem', 'materia', 'resultado']
def get_context_data(self, **kwargs):
- if self.get_queryset().count() > 500:
- self.paginate_by = 50
- else:
- self.paginate_by = None
-
context = super().get_context_data(**kwargs)
-
has_permition = self.request.user.has_module_perms(AppConfig.label)
return customize_link_materia(context, self.kwargs['pk'], has_permition, False)
+ def get_queryset(self):
+ return super().get_queryset().select_related(
+ 'materia', 'materia__tipo', 'sessao_plenaria',
+ ).prefetch_related(
+ Prefetch(
+ 'materia__materiaemtramitacao_set',
+ to_attr='_met_prefetch',
+ ),
+ Prefetch(
+ 'materia__numeracao_set',
+ to_attr='_numeracao_prefetch',
+ ),
+ Prefetch(
+ 'materia__autoria_set',
+ queryset=Autoria.objects.select_related('autor'),
+ to_attr='_autoria_prefetch',
+ ),
+ Prefetch(
+ 'materia__tramitacao_set',
+ queryset=Tramitacao.objects.filter(
+ turno__isnull=False,
+ ).exclude(turno='').order_by('-data_tramitacao', '-id'),
+ to_attr='_tramitacao_prefetch',
+ ),
+ Prefetch(
+ 'registrovotacao_set',
+ queryset=RegistroVotacao.objects.select_related(
+ 'tipo_resultado_votacao',
+ ),
+ to_attr='_votacao_prefetch',
+ ),
+ Prefetch(
+ 'retiradapauta_set',
+ queryset=RetiradaPauta.objects.select_related(
+ 'tipo_de_retirada',
+ ),
+ to_attr='_retirada_prefetch',
+ ),
+ Prefetch(
+ 'registroleitura_set',
+ to_attr='_leitura_prefetch',
+ ),
+ )
+
def recuperar_materia(request):
tipo = TipoMateriaLegislativa.objects.get(pk=request.GET['tipo_materia'])
@@ -907,24 +944,60 @@ class ExpedienteMateriaCrud(MasterDetailCrud):
'resultado']
class ListView(MasterDetailCrud.ListView):
- paginate_by = None
+ paginate_by = 100
ordering = ['numero_ordem', 'materia', 'resultado']
def get_context_data(self, **kwargs):
-
- if self.get_queryset().count() > 500:
- self.paginate_by = 50
- else:
- self.paginate_by = None
-
context = super().get_context_data(**kwargs)
-
if self.request.GET.get('page'):
context['page'] = self.request.GET.get('page')
-
has_permition = self.request.user.has_module_perms(AppConfig.label)
return customize_link_materia(context, self.kwargs['pk'], has_permition, True)
+ def get_queryset(self):
+ return super().get_queryset().select_related(
+ 'materia', 'materia__tipo', 'sessao_plenaria',
+ ).prefetch_related(
+ Prefetch(
+ 'materia__materiaemtramitacao_set',
+ to_attr='_met_prefetch',
+ ),
+ Prefetch(
+ 'materia__numeracao_set',
+ to_attr='_numeracao_prefetch',
+ ),
+ Prefetch(
+ 'materia__autoria_set',
+ queryset=Autoria.objects.select_related('autor'),
+ to_attr='_autoria_prefetch',
+ ),
+ Prefetch(
+ 'materia__tramitacao_set',
+ queryset=Tramitacao.objects.filter(
+ turno__isnull=False,
+ ).exclude(turno='').order_by('-data_tramitacao', '-id'),
+ to_attr='_tramitacao_prefetch',
+ ),
+ Prefetch(
+ 'registrovotacao_set',
+ queryset=RegistroVotacao.objects.select_related(
+ 'tipo_resultado_votacao',
+ ),
+ to_attr='_votacao_prefetch',
+ ),
+ Prefetch(
+ 'retiradapauta_set',
+ queryset=RetiradaPauta.objects.select_related(
+ 'tipo_de_retirada',
+ ),
+ to_attr='_retirada_prefetch',
+ ),
+ Prefetch(
+ 'registroleitura_set',
+ to_attr='_leitura_prefetch',
+ ),
+ )
+
class CreateView(MasterDetailCrud.CreateView):
form_class = ExpedienteMateriaForm
@@ -941,7 +1014,7 @@ class ExpedienteMateriaCrud(MasterDetailCrud):
sessao_plenaria=self.kwargs['pk']).aggregate(
Max('numero_ordem'))['numero_ordem__max']
initial['numero_ordem'] = (
- max_numero_ordem if max_numero_ordem else 0) + 1
+ max_numero_ordem if max_numero_ordem else 0) + 1
return initial
def get_success_url(self):
@@ -975,7 +1048,6 @@ class ExpedienteMateriaCrud(MasterDetailCrud):
return initial
class DetailView(MasterDetailCrud.DetailView):
-
layout_key = 'ExpedienteMateriaDetail'
@@ -1426,7 +1498,7 @@ class PresencaView(FormMixin, PresencaMixin, DetailView):
# Id dos parlamentares presentes
marcados = request.POST.getlist('presenca_ativos') \
- + request.POST.getlist('presenca_inativos')
+ + request.POST.getlist('presenca_inativos')
# Deletar os que foram desmarcados
deletar = set(presentes_banco) - set(marcados)
@@ -1541,7 +1613,7 @@ class PresencaOrdemDiaView(FormMixin, PresencaMixin, DetailView):
# Id dos parlamentares presentes
marcados = request.POST.getlist('presenca_ativos') \
- + request.POST.getlist('presenca_inativos')
+ + request.POST.getlist('presenca_inativos')
# Deletar os que foram desmarcados
deletar = set(presentes_banco) - set(marcados)
@@ -1803,7 +1875,7 @@ def insere_parlamentar_composicao(request):
username = request.user.username
if request.user.has_perm(
'%s.add_%s' % (
- AppConfig.label, IntegranteMesa._meta.model_name)):
+ AppConfig.label, IntegranteMesa._meta.model_name)):
composicao = IntegranteMesa()
@@ -1867,7 +1939,7 @@ def remove_parlamentar_composicao(request):
username = request.user.username
if request.POST and request.user.has_perm(
'%s.delete_%s' % (
- AppConfig.label, IntegranteMesa._meta.model_name)):
+ AppConfig.label, IntegranteMesa._meta.model_name)):
if 'composicao_mesa' in request.POST:
try:
@@ -2921,7 +2993,7 @@ class VotacaoView(SessaoPermissionMixin):
username = request.user.username
self.logger.error('user=' + username + '. Problemas ao salvar RegistroVotacao da materia de id={} '
'e da ordem de id={}. '.format(materia_id, ordem_id) + str(
- e))
+ e))
return self.form_invalid(form)
else:
ordem = OrdemDia.objects.get(id=ordem_id)
@@ -3991,7 +4063,8 @@ class PautaSessaoDetailView(PautaMultiFormatOutputMixin, DetailView):
'resultado_observacao': resultado_observacao,
'situacao': ultima_tramitacao.status if ultima_tramitacao else _("Não informada"),
'processo': f'{str(numeracao.numero_materia)}/{str(numeracao.ano_materia)}' if numeracao else '-',
- 'autor': [str(x.autor) for x in Autoria.objects.select_related("autor").filter(materia_id=o.materia_id)],
+ 'autor': [str(x.autor) for x in
+ Autoria.objects.select_related("autor").filter(materia_id=o.materia_id)],
'turno': get_turno(ultima_tramitacao.turno) if ultima_tramitacao else '',
'periodo': 'ordem dia',
})
@@ -4099,7 +4172,6 @@ class PesquisarSessaoPlenariaView(MultiFormatOutputMixin, FilterView):
return r
-
class PesquisarPautaSessaoView(PesquisarSessaoPlenariaView):
filterset_class = PautaSessaoFilterSet
template_name = 'sessao/pauta_sessao_filter.html'
@@ -5338,7 +5410,7 @@ class CorrespondenciaCrud(MasterDetailCrud):
sessao_plenaria=self.kwargs['pk']).aggregate(
Max('numero_ordem'))['numero_ordem__max']
initial['numero_ordem'] = (
- max_numero_ordem if max_numero_ordem else 0) + 1
+ max_numero_ordem if max_numero_ordem else 0) + 1
return initial
diff --git a/sapl/utils.py b/sapl/utils.py
index 191ea87a0..0c0220a3d 100644
--- a/sapl/utils.py
+++ b/sapl/utils.py
@@ -1,6 +1,6 @@
import csv
import string
-from functools import wraps
+from functools import lru_cache, wraps
import hashlib
import io
from itertools import groupby, chain
@@ -959,13 +959,15 @@ def parlamentares_ativos(data_inicio, data_fim=None):
return Parlamentar.objects.filter(id__in=parlamentares_id)
-def show_results_filter_set(qr):
- query_params = set(qr.keys())
- if ((len(query_params) == 1 and 'iframe' in query_params) or
- len(query_params) == 0):
- return False
+_IGNORED_PARAMS = frozenset({'iframe', 'pesquisar', 'csrfmiddlewaretoken'})
- return True
+
+def show_results_filter_set(qr):
+ meaningful = {
+ k for k, v in qr.items()
+ if k not in _IGNORED_PARAMS and v and v.strip()
+ }
+ return bool(meaningful)
def sort_lista_chave(lista, chave):
@@ -1249,7 +1251,7 @@ class GoogleRecapthaMixin:
return cd
-# TODO: cache this map and invalidate on each update
+@lru_cache(maxsize=None)
def get_report_urls_map():
from django.urls import get_resolver
from django.urls.base import reverse
@@ -1278,13 +1280,11 @@ def get_report_urls_map():
def is_report_allowed(request, url_path=None):
- from sapl.utils import get_report_urls_map # TODO: import global
- url_map = get_report_urls_map() # TODO: cache this!!! Globally
-
+ url_map = get_report_urls_map()
path = url_path if url_path else request.path
- authenticated = True if request.user.is_authenticated else False
+ authenticated = request.user.is_authenticated
- if path in url_map.keys():
+ if path in url_map:
path_metadata = url_map[path]
if not authenticated and path_metadata['public']:
return True