Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions dados_brasil_io/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'django_filters',
'comum',
'empresas',
'politicos',
Expand Down Expand Up @@ -147,9 +148,17 @@
},
}

CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
}
# CACHES = {
# 'default': {
# 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
# 'LOCATION': '127.0.0.1:11211',
# }
# }

REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': (
'django_filters.rest_framework.DjangoFilterBackend',
),
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 20,
}
5 changes: 4 additions & 1 deletion dados_brasil_io/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,12 @@
from django.contrib import admin
from django.urls import path

from politicos.views import DeputadoListView
from empresas.views import EmpresaDetailView
from politicos.views import DeputadoListView, DeputadoGastosView

urlpatterns = [
path('admin/', admin.site.urls),
path('deputados/', DeputadoListView.as_view(), name='deputados'),
path('deputados-gastos', DeputadoGastosView.as_view(), name='deputados-gastos'),
path('empresa/<pk>/', EmpresaDetailView.as_view(), name='empresa'),
]
2 changes: 1 addition & 1 deletion empresas/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from django.db import models
from django.db.models import Case, Count, F, OuterRef, Q, Subquery, Sum, Value, When
from django.db.models import Case, Count, Exists, F, OuterRef, Q, Subquery, Sum, Value, When
from django.db.models.functions import Coalesce


Expand Down
19 changes: 17 additions & 2 deletions empresas/views.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
from django.shortcuts import render
from rest_framework import generics, serializers
from rest_framework.response import Response

from empresas.models import Empresa, Sociedade


class EmpresaSerializer(serializers.ModelSerializer):

class Meta:
model = Empresa
fields = ['cnpj', 'nome', 'sociedades']
depth = 10


class EmpresaDetailView(generics.RetrieveAPIView):
serializer_class = EmpresaSerializer
queryset = Empresa.objects.all()

# Create your views here.
43 changes: 43 additions & 0 deletions politicos/filters.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from datetime import date
from django_filters import rest_framework as filters

from politicos.models import Deputado


class DeputadoFilter(filters.FilterSet):
nome = filters.CharFilter(field_name='nome', lookup_expr='icontains')
exibir_gasto_mensal = filters.BooleanFilter(method='filter_exibir_gasto_mensal')
fornecedor_gasto = filters.CharFilter(field_name='gastos__empresa__nome', lookup_expr='icontains')

class Meta:
model = Deputado
fields = [
'nome', 'partido', 'uf', 'id_legislatura',
]

def filter_exibir_gasto_mensal(self, queryset, name, value):
if value and not {'gastos_mes', 'gastos_ano'} & set(self.data.keys()):
queryset = queryset.annotate_gasto_mensal_por_deputado()
return queryset


class DeputadoGastosFilter(filters.FilterSet):
nome = filters.CharFilter(field_name='nome', lookup_expr='icontains')
gastos_mes = filters.NumberFilter(method='add_prefetch_gastos')
gastos_ano = filters.NumberFilter(method='add_prefetch_gastos')

class Meta:
model = Deputado
fields = [
'nome', 'partido', 'uf', 'id_legislatura',
]

def add_prefetch_gastos(self, queryset, name, value):
filtros = self.data.dict()
hoje = date.today()
mes = filtros.get('gastos_mes', hoje.month)
ano = filtros.get('gastos_ano', hoje.year)
if not hasattr(self, '_prefetch_added') and mes and ano:
queryset = queryset.prefetch_gastos(mes=mes, ano=ano)
self._prefetch_added = True
return queryset
31 changes: 27 additions & 4 deletions politicos/models.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.db import models
from django.db.models import Avg, F, FilteredRelation, Prefetch, Q, Sum
from django.db.models import Avg, Case, Count, Exists, F, FilteredRelation, OuterRef, Prefetch, Q, Sum, Value, When
from django.db.models.functions import Coalesce


class DeputadoQuerySet(models.QuerySet):
Expand Down Expand Up @@ -54,9 +55,31 @@ def prefetch_gastos(self, **kwargs):
def annotate_gastos_acima_dobro(self, descricao_gasto):
media = GastoCotaParlamentar.objects.filter_descricao(descricao_gasto).media()
acima_dobro = Q(gastos__descricao=descricao_gasto, gastos__valor_liquido__gt=media * 2)
count_acima_dobro = Count('pk', filter=acima_dobro)
count_geral = Count('pk', filter=Q(gastos__descricao=descricao_gasto))
return self.annotate(gastos_acima_dobro=count_acima_dobro, qtd_gastos=count_geral)
return self.annotate(
qtd_gastos=Count('gastos', filter=Q(gastos__descricao=descricao_gasto)),
qtd_acima_dobro=Coalesce(
Sum(
Case(
When(
Q(gastos__valor_liquido__gt=media * 2, gastos__descricao=descricao_gasto),
then=Value(1)
),
output_field=models.IntegerField()
)
),
0
)
)

def annotate_empresas(self):
from empresas.models import Empresa
empresas_qs = Empresa.objects.filter(
sociedades__socio_pessoa_fisica__nome=OuterRef('nome'),
uf=OuterRef('uf')
)
return self.annotate(
empresas=Exists(empresas_qs)
)


class GastoCotaParlamentarQuerySet(models.QuerySet):
Expand Down
56 changes: 56 additions & 0 deletions politicos/serializers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from rest_framework import serializers

from politicos.models import Deputado, GastoCotaParlamentar


class GastoCotaParlamentarSerializer(serializers.ModelSerializer):
class Meta:
model = GastoCotaParlamentar
fields = [
'id',
'data_emissao',
'ano',
'especificacao_subcota',
'mes',
'ressarcimento',
'cpf',
'descricao',
'descricao_especificacao',
'fornecedor',
'valor_documento',
'valor_glosa',
'valor_liquido',
'valor_restituicao',
'empresa',
]
depth = 1


class DeputadoSerializer(serializers.ModelSerializer):
gastos_mensais = serializers.SerializerMethodField()

class Meta:
model = Deputado
fields = [
'id', 'nome', 'partido', 'uf', 'id_legislatura',
'gastos_mensais',
]
depth = 2

def get_gastos_mensais(self, obj):
return {
key: value for key, value in obj.__dict__.items()
if key.startswith('gastos_')
}


class DeputadoGastosSerializer(serializers.ModelSerializer):
gastos = GastoCotaParlamentarSerializer(many=True)

class Meta:
model = Deputado
fields = [
'id', 'nome', 'partido', 'uf', 'id_legislatura',
'gastos',
]
depth = 2
53 changes: 16 additions & 37 deletions politicos/views.py
Original file line number Diff line number Diff line change
@@ -1,42 +1,21 @@
from datetime import date
from rest_framework import generics, serializers
from rest_framework.response import Response
from rest_framework import generics

from politicos.models import Deputado, GastoCotaParlamentar


class GastoCotaParlamentarSerializer(serializers.ModelSerializer):
class Meta:
model = GastoCotaParlamentar
fields = '__all__'


class DeputadoSerializer(serializers.ModelSerializer):

class Meta:
model = Deputado
fields = [
'id', 'nome', 'partido', 'uf', 'id_legislatura',
'gastos'
]
depth = 2
from politicos.filters import DeputadoFilter
from politicos.models import Deputado
from politicos.serializers import DeputadoSerializer, DeputadoGastosSerializer


class DeputadoListView(generics.ListAPIView):
serializer_class = DeputadoSerializer

def get_queryset(self):
queryset = Deputado.objects.all().select_related('partido', 'uf')

hoje = date.today()
filtros = self.request.query_params.dict()
filtros.setdefault('gastos_mes', hoje.month)
filtros.setdefault('gastos_ano', hoje.year)

queryset = queryset.prefetch_gastos(**{
campo.replace('gastos_', ''): valor
for campo, valor in filtros.items()
if campo.startswith('gastos_')
})

return queryset
filterset_class = DeputadoFilter
queryset = Deputado.objects.all().select_related(
'partido', 'uf'
)


class DeputadoGastosView(generics.ListAPIView):
serializer_class = DeputadoGastosSerializer
filterset_class = DeputadoFilter
queryset = Deputado.objects.all().select_related(
'partido', 'uf'
).prefetch_related('gastos__empresa')
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ cycler==0.10.0
dateutils==0.6.6
decorator==4.2.1
Django==2.0.4
django-filter==2.0.0
djangorestframework==3.8.2
idna==2.6
ipdb==0.11
Expand Down