Browse Source

ajustes automáticos da IDE no app api

pull/3453/head
Leandro Roberto 3 years ago
parent
commit
ca9ecf00c0
  1. 7
      sapl/api/core/__init__.py
  2. 2
      sapl/api/core/filters.py
  3. 9
      sapl/api/deprecated.py
  4. 10
      sapl/api/forms.py
  5. 18
      sapl/api/serializers.py
  6. 36
      sapl/api/urls.py
  7. 29
      sapl/api/views_customize.py

7
sapl/api/core/__init__.py

@ -22,11 +22,12 @@ from rest_framework.viewsets import ModelViewSet
from sapl.api.core.filters import SaplFilterSetMixin
from sapl.api.permissions import SaplModelPermissions
from sapl.api.serializers import ChoiceSerializer, ParlamentarSerializer,\
from sapl.api.serializers import ChoiceSerializer, ParlamentarSerializer, \
ParlamentarEditSerializer, ParlamentarResumeSerializer
class BusinessRulesNotImplementedMixin:
def create(self, request, *args, **kwargs):
raise Exception(_("POST Create não implementado"))
@ -126,6 +127,7 @@ class SaplApiViewSetConstrutor():
# Define uma classe padrão para filtro caso não tenha sido
# criada a classe sapl.api.forms.{model}FilterSet
class SaplFilterSet(_filterset_class):
class Meta(_meta_filterset):
if not hasattr(_meta_filterset, 'model'):
model = _model
@ -159,7 +161,6 @@ class SaplApiViewSetConstrutor():
return cls
"""
1. Constroi uma rest_framework.viewsets.ModelViewSet para
todos os models de todas as apps do sapl
@ -232,6 +233,7 @@ class SaplApiViewSetConstrutor():
class wrapper_queryset_response_for_drf_action(object):
def __init__(self, model):
self.model = model
@ -268,6 +270,7 @@ class wrapper_queryset_response_for_drf_action(object):
# decorator para recuperar e transformar o default
class customize(object):
def __init__(self, model):
self.model = model

2
sapl/api/core/filters.py

@ -3,11 +3,11 @@ from collections import OrderedDict
from django.db.models.fields.files import FileField
from django.template.defaultfilters import capfirst
import django_filters
from django_filters.constants import ALL_FIELDS
from django_filters.filters import CharFilter
from django_filters.filterset import FilterSet
from django_filters.utils import resolve_field, get_all_model_fields
import django_filters
class SaplFilterSetMixin(FilterSet):

9
sapl/api/deprecated.py

@ -1,5 +1,4 @@
import logging
import logging
from django.contrib.contenttypes.models import ContentType
@ -10,19 +9,17 @@ from django.forms.widgets import MultiWidget, TextInput
from django.http import Http404
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext_lazy as _
from django_filters.filters import CharFilter, ModelChoiceFilter, DateFilter
from django_filters.rest_framework.backends import DjangoFilterBackend
from django_filters.rest_framework.filterset import FilterSet
from rest_framework import serializers
from rest_framework import serializers
from rest_framework.generics import ListAPIView
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin
from rest_framework.permissions import (IsAuthenticated,
IsAuthenticatedOrReadOnly, AllowAny)
from rest_framework.viewsets import GenericViewSet
from sapl.api.serializers import ModelChoiceSerializer, AutorSerializer,\
from sapl.api.serializers import ModelChoiceSerializer, AutorSerializer, \
ChoiceSerializer
from sapl.base.models import TipoAutor, Autor, CasaLegislativa
from sapl.materia.models import MateriaLegislativa
@ -514,7 +511,7 @@ class AutorListView(ListAPIView):
model = Autor
filter_class = AutorChoiceFilterSet
filter_backends = (DjangoFilterBackend, )
filter_backends = (DjangoFilterBackend,)
serializer_class = AutorChoiceSerializer
@property
@ -660,7 +657,7 @@ class MateriaLegislativaViewSet(ListModelMixin,
serializer_class = MateriaLegislativaOldSerializer
queryset = MateriaLegislativa.objects.all()
filter_backends = (DjangoFilterBackend,)
filter_fields = ('numero', 'ano', 'tipo', )
filter_fields = ('numero', 'ano', 'tipo',)
class SessaoPlenariaViewSet(ListModelMixin,

10
sapl/api/forms.py

@ -2,7 +2,17 @@
from sapl.api.core.filters import SaplFilterSetMixin
from sapl.sessao.models import SessaoPlenaria
# esta classe não é necessária
# a api construiría uma igual
# mas está demonstrar que caso queira customizar um filter_set
# que a api consiga recuperá-lo, para os endpoints básicos
# deve seguir os critérios de nomenclatura e herança
# class [Model]FilterSet(SaplFilterSetMixin):
# class Meta(SaplFilterSetMixin.Meta):
class SessaoPlenariaFilterSet(SaplFilterSetMixin):
class Meta(SaplFilterSetMixin.Meta):
model = SessaoPlenaria

18
sapl/api/serializers.py

@ -1,16 +1,18 @@
import logging
from django.conf import settings
from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
from django.db.models import F, Q
from django.db.models import Q
from image_cropping.utils import get_backend
from rest_framework import serializers
from rest_framework.relations import StringRelatedField
from sapl.parlamentares.models import Parlamentar, Mandato, Filiacao, Legislatura
from sapl.base.models import Autor, CasaLegislativa
from sapl.utils import filiacao_data
from image_cropping.utils import get_backend
from sapl.parlamentares.models import Parlamentar, Mandato, Legislatura
class IntRelatedField(StringRelatedField):
def to_representation(self, value):
return int(value)
@ -86,7 +88,7 @@ class ParlamentarResumeSerializer(serializers.ModelSerializer):
fotografia_cropped = serializers.SerializerMethodField('crop_fotografia')
logger = logging.getLogger(__name__)
def crop_fotografia(self,obj):
def crop_fotografia(self, obj):
thumbnail_url = ""
try:
import os
@ -107,7 +109,7 @@ class ParlamentarResumeSerializer(serializers.ModelSerializer):
return thumbnail_url
def check_titular(self,obj):
def check_titular(self, obj):
is_titular = None
if not Legislatura.objects.exists():
self.logger.error("Não há legislaturas cadastradas.")
@ -128,14 +130,14 @@ class ParlamentarResumeSerializer(serializers.ModelSerializer):
is_titular = '-'
return is_titular
def check_partido(self,obj):
def check_partido(self, obj):
# Coloca a filiação atual ao invés da última
# As condições para mostrar a filiação são:
# A data de filiacao deve ser menor que a data de fim
# da legislatura e data de desfiliação deve nula, ou maior,
# ou igual a data de fim da legislatura
username = self.context['request'].user.username
username = self.context['request'].user.username
if not Legislatura.objects.exists():
self.logger.error("Não há legislaturas cadastradas.")
return ""

36
sapl/api/urls.py

@ -1,32 +1,28 @@
from django.conf.urls import include, url
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView,\
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView, \
SpectacularRedocView
from rest_framework.routers import DefaultRouter
from sapl.api.deprecated import MateriaLegislativaViewSet, SessaoPlenariaViewSet,\
AutoresProvaveisListView, AutoresPossiveisListView, AutorListView,\
from sapl.api.deprecated import MateriaLegislativaViewSet, SessaoPlenariaViewSet, \
AutoresProvaveisListView, AutoresPossiveisListView, AutorListView, \
ModelChoiceView
from sapl.api.views import AppVersionView, recria_token
from sapl.api.views_customize import SaplApiViewSetConstrutor
from .apps import AppConfig
app_name = AppConfig.name
router = DefaultRouter()
router.register(r'materia$', MateriaLegislativaViewSet)
router.register(r'sessao-plenaria', SessaoPlenariaViewSet)
for app, built_sets in SaplApiViewSetConstrutor._built_sets.items():
for view_prefix, viewset in built_sets.items():
router.register(app.label + '/' +
view_prefix._meta.model_name, viewset)
urlpatterns_router = router.urls
urlpatterns_api_doc = [
@ -38,28 +34,6 @@ urlpatterns_api_doc = [
# YOUR PATTERNS
url('^schema/', SpectacularAPIView.as_view(), name='schema_api'),
]
"""if 'drf_yasg' in settings.INSTALLED_APPS:
from drf_yasg import openapi
from drf_yasg.views import get_schema_view
schema_view = get_schema_view(
openapi.Info(
title="Sapl API - docs",
default_version='v1',
description="Sapl API - Docs - Configuração Básica",
),
url=settings.SITE_URL,
public=True,
permission_classes=(permissions.AllowAny,),
)
urlpatterns_api_doc = [
url(r'^docs/swagger(?P<format>\.json|\.yaml)$',
schema_view.without_ui(cache_timeout=0), name='schema-json'),
url(r'^docs/swagger/$',
schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
url(r'^docs/redoc/$',
schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
]"""
# TODO: refatorar para customização da api automática
deprecated_urlpatterns_api = [
@ -67,13 +41,9 @@ deprecated_urlpatterns_api = [
AutoresProvaveisListView.as_view(), name='autores_provaveis_list'),
url(r'^autor/possiveis',
AutoresPossiveisListView.as_view(), name='autores_possiveis_list'),
url(r'^autor', AutorListView.as_view(), name='autor_list'),
url(r'^model/(?P<content_type>\d+)/(?P<pk>\d*)$',
ModelChoiceView.as_view(), name='model_list'),
]
urlpatterns = [

29
sapl/api/views_customize.py

@ -8,24 +8,23 @@ from django.utils.translation import ugettext_lazy as _
from rest_framework.decorators import action
from rest_framework.response import Response
from sapl.api.core import customize, SaplApiViewSetConstrutor,\
wrapper_queryset_response_for_drf_action,\
from sapl.api.core import customize, SaplApiViewSetConstrutor, \
wrapper_queryset_response_for_drf_action, \
BusinessRulesNotImplementedMixin
from sapl.api.permissions import SaplModelPermissions
from sapl.api.serializers import ChoiceSerializer, \
ParlamentarEditSerializer, ParlamentarResumeSerializer
from sapl.base.models import Autor, AppConfig, DOC_ADM_OSTENSIVO
from sapl.materia.models import Proposicao, TipoMateriaLegislativa,\
from sapl.materia.models import Proposicao, TipoMateriaLegislativa, \
MateriaLegislativa, Tramitacao
from sapl.norma.models import NormaJuridica
from sapl.parlamentares.models import Mandato, Legislatura
from sapl.parlamentares.models import Parlamentar
from sapl.protocoloadm.models import DocumentoAdministrativo,\
from sapl.protocoloadm.models import DocumentoAdministrativo, \
DocumentoAcessorioAdministrativo, TramitacaoAdministrativo, Anexado
from sapl.sessao.models import SessaoPlenaria, ExpedienteSessao
from sapl.utils import models_with_gr_for_model, choice_anos_com_sessaoplenaria
SaplApiViewSetConstrutor = SaplApiViewSetConstrutor.build_class()
@ -33,7 +32,7 @@ SaplApiViewSetConstrutor = SaplApiViewSetConstrutor.build_class()
class _AutorViewSet:
# Customização para AutorViewSet com implementação de actions específicas
"""
Neste exemplo de customização do que foi criado em
Nesta customização do que foi criado em
SaplApiViewSetConstrutor além do ofertado por
rest_framework.viewsets.ModelViewSet, dentre outras customizações
possíveis, foi adicionado as rotas referentes aos relacionamentos genéricos
@ -100,7 +99,9 @@ class _AutorViewSet:
@customize(Parlamentar)
class _ParlamentarViewSet:
class ParlamentarPermission(SaplModelPermissions):
def has_permission(self, request, view):
if request.method == 'GET':
return True
@ -108,7 +109,7 @@ class _ParlamentarViewSet:
perm = super().has_permission(request, view)
return perm
permission_classes = (ParlamentarPermission, )
permission_classes = (ParlamentarPermission,)
def get_serializer(self, *args, **kwargs):
if self.request.user.has_perm('parlamentares.add_parlamentar'):
@ -219,7 +220,9 @@ class _ProposicaoViewSet:
* Pode recuperar qualquer das proposições incorporadas
"""
class ProposicaoPermission(SaplModelPermissions):
def has_permission(self, request, view):
if request.method == 'GET':
return True
@ -234,7 +237,7 @@ class _ProposicaoViewSet:
# não é list ou detail, então passa pelas regras de permissão e,
# depois disso ainda passa pelo filtro de get_queryset
permission_classes = (ProposicaoPermission, )
permission_classes = (ProposicaoPermission,)
def get_queryset(self):
qs = super().get_queryset()
@ -259,6 +262,7 @@ class _ProposicaoViewSet:
@customize(MateriaLegislativa)
class _MateriaLegislativaViewSet:
class Meta:
ordering = ['-ano', 'tipo', 'numero']
@ -305,6 +309,7 @@ class _TipoMateriaLegislativaViewSet:
class _DocumentoAdministrativoViewSet:
class DocumentoAdministrativoPermission(SaplModelPermissions):
def has_permission(self, request, view):
if request.method == 'GET':
comportamento = AppConfig.attr('documentos_administrativos')
@ -320,7 +325,7 @@ class _DocumentoAdministrativoViewSet:
"""
return super().has_permission(request, view)
permission_classes = (DocumentoAdministrativoPermission, )
permission_classes = (DocumentoAdministrativoPermission,)
def get_queryset(self):
"""
@ -340,7 +345,7 @@ class _DocumentoAdministrativoViewSet:
class _DocumentoAcessorioAdministrativoViewSet:
permission_classes = (
_DocumentoAdministrativoViewSet.DocumentoAdministrativoPermission, )
_DocumentoAdministrativoViewSet.DocumentoAdministrativoPermission,)
def get_queryset(self):
qs = super().get_queryset()
@ -355,7 +360,7 @@ class _TramitacaoAdministrativoViewSet(BusinessRulesNotImplementedMixin):
# TODO: Implementar regras de manutenção das tramitações de docs adms
permission_classes = (
_DocumentoAdministrativoViewSet.DocumentoAdministrativoPermission, )
_DocumentoAdministrativoViewSet.DocumentoAdministrativoPermission,)
def get_queryset(self):
qs = super().get_queryset()
@ -369,7 +374,7 @@ class _TramitacaoAdministrativoViewSet(BusinessRulesNotImplementedMixin):
class _AnexadoViewSet(BusinessRulesNotImplementedMixin):
permission_classes = (
_DocumentoAdministrativoViewSet.DocumentoAdministrativoPermission, )
_DocumentoAdministrativoViewSet.DocumentoAdministrativoPermission,)
def get_queryset(self):
qs = super().get_queryset()

Loading…
Cancel
Save