Browse Source

refactor: ref sapl/api para impl drfautoapi

pull/3606/head
LeandroJatai 3 years ago
parent
commit
9b1f2aba10
  1. 3
      sapl/api/apps.py
  2. 25
      sapl/api/core/forms.py
  3. 50
      sapl/api/core/serializers.py
  4. 8
      sapl/api/deprecated.py
  5. 5
      sapl/api/forms.py
  6. 5
      sapl/api/schema.py
  7. 90
      sapl/api/serializers.py
  8. 10
      sapl/api/signals.py
  9. 8
      sapl/api/views.py
  10. 14
      sapl/api/viewset.py
  11. 9
      sapl/settings.py

3
sapl/api/apps.py

@ -6,3 +6,6 @@ class AppConfig(apps.AppConfig):
name = 'sapl.api'
label = 'api'
verbose_name = _('API Rest')
def ready(self):
from . import signals

25
sapl/api/core/forms.py

@ -1,25 +0,0 @@
from sapl.api.core.filters import SaplFilterSetMixin
from sapl.sessao.models import SessaoPlenaria
# ATENÇÃO: MUDANÇAS NO CORE DEVEM SER REALIZADAS COM
# EXTREMA CAUTELA E CONSCIENTE DOS IMPACTOS NA API
# FILTER SET dentro do core devem ser criados se o intuíto é um filter-set
# para o list da api.
# filter_set para actions, devem ser criados fora do core.
# A CLASSE SessaoPlenariaFilterSet não é necessária
# o construtor da api construiría uma igual
# mas está aqui para 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

50
sapl/api/core/serializers.py

@ -1,50 +0,0 @@
import logging
from django.conf import settings
from rest_framework import serializers
from rest_framework.relations import StringRelatedField
from sapl.base.models import CasaLegislativa
class IntRelatedField(StringRelatedField):
def to_representation(self, value):
return int(value)
class ChoiceSerializer(serializers.Serializer):
value = serializers.SerializerMethodField()
text = serializers.SerializerMethodField()
def get_text(self, obj):
return obj[1]
def get_value(self, obj):
return obj[0]
class ModelChoiceSerializer(ChoiceSerializer):
def get_text(self, obj):
return str(obj)
def get_value(self, obj):
return obj.id
class ModelChoiceObjectRelatedField(serializers.RelatedField):
def to_representation(self, value):
return ModelChoiceSerializer(value).data
class CasaLegislativaSerializer(serializers.ModelSerializer):
version = serializers.SerializerMethodField()
def get_version(self, obj):
return settings.SAPL_VERSION
class Meta:
model = CasaLegislativa
fields = '__all__'

8
sapl/api/deprecated.py

@ -1,8 +1,5 @@
import logging
from django.contrib.contenttypes.models import ContentType
from django.db.models import Q
from django.db.models import Q
from django.forms.fields import CharField, MultiValueField
from django.forms.widgets import MultiWidget, TextInput
@ -17,10 +14,11 @@ from rest_framework.generics import ListAPIView
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin
from rest_framework.permissions import (IsAuthenticated,
IsAuthenticatedOrReadOnly, AllowAny)
from rest_framework.relations import StringRelatedField
from rest_framework.viewsets import GenericViewSet
from sapl.api.core.serializers import ModelChoiceSerializer, ChoiceSerializer
from sapl.api.serializers import AutorSerializer
from sapl.api.serializers import AutorSerializer, ModelChoiceSerializer,\
ChoiceSerializer
from sapl.base.models import TipoAutor, Autor, CasaLegislativa
from sapl.materia.models import MateriaLegislativa
from sapl.parlamentares.models import Legislatura

5
sapl/api/forms.py

@ -0,0 +1,5 @@
from drfautoapi.drfautoapi import ApiFilterSetMixin
class SaplFilterSetMixin(ApiFilterSetMixin):
pass

5
sapl/api/schema.py

@ -0,0 +1,5 @@
from drf_spectacular.openapi import AutoSchema
class Schema(AutoSchema):
pass

90
sapl/api/serializers.py

@ -1,19 +1,68 @@
import logging
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import MultipleObjectsReturned, ObjectDoesNotExist
from django.db.models import Q
from image_cropping.utils import get_backend
from rest_framework import serializers
from rest_framework.fields import SerializerMethodField
from rest_framework.relations import StringRelatedField
from sapl.api.core.serializers import ModelChoiceObjectRelatedField
from sapl.base.models import Autor
from sapl.base.models import Autor, CasaLegislativa, Metadata
from sapl.parlamentares.models import Parlamentar, Mandato, Legislatura
class AutorSerializer(serializers.ModelSerializer):
# AutorSerializer sendo utilizado pelo gerador automático da api devidos aos
# critérios anotados em views.py
class SaplSerializerMixin(serializers.ModelSerializer):
__str__ = SerializerMethodField()
metadata = SerializerMethodField()
class Meta:
fields = '__all__'
def get___str__(self, obj) -> str:
return str(obj)
def get_metadata(self, obj) -> dict:
try:
metadata = Metadata.objects.get(
content_type=ContentType.objects.get_for_model(
obj._meta.model),
object_id=obj.id
).metadata
except:
metadata = {}
finally:
return metadata
class ChoiceSerializer(serializers.Serializer):
value = serializers.SerializerMethodField()
text = serializers.SerializerMethodField()
def get_text(self, obj):
return obj[1]
def get_value(self, obj):
return obj[0]
class ModelChoiceSerializer(ChoiceSerializer):
def get_text(self, obj):
return str(obj)
def get_value(self, obj):
return obj.id
class ModelChoiceObjectRelatedField(serializers.RelatedField):
def to_representation(self, value):
return ModelChoiceSerializer(value).data
class AutorSerializer(SaplSerializerMixin):
autor_related = ModelChoiceObjectRelatedField(read_only=True)
@ -22,7 +71,18 @@ class AutorSerializer(serializers.ModelSerializer):
fields = '__all__'
class ParlamentarSerializerPublic(serializers.ModelSerializer):
class CasaLegislativaSerializer(SaplSerializerMixin):
version = serializers.SerializerMethodField()
def get_version(self, obj):
return settings.SAPL_VERSION
class Meta:
model = CasaLegislativa
fields = '__all__'
class ParlamentarSerializerPublic(SaplSerializerMixin):
class Meta:
model = Parlamentar
@ -32,7 +92,7 @@ class ParlamentarSerializerPublic(serializers.ModelSerializer):
"telefone_residencia", "titulo_eleitor", "fax_residencia"]
class ParlamentarSerializerVerbose(serializers.ModelSerializer):
class ParlamentarSerializerVerbose(SaplSerializerMixin):
titular = serializers.SerializerMethodField('check_titular')
partido = serializers.SerializerMethodField('check_partido')
fotografia_cropped = serializers.SerializerMethodField('crop_fotografia')
@ -55,7 +115,8 @@ class ParlamentarSerializerVerbose(serializers.ModelSerializer):
)
except Exception as e:
self.logger.error(e)
self.logger.error('erro processando arquivo: %s' % obj.fotografia.path)
self.logger.error('erro processando arquivo: %s' %
obj.fotografia.path)
return thumbnail_url
@ -66,7 +127,8 @@ class ParlamentarSerializerVerbose(serializers.ModelSerializer):
return ""
try:
legislatura = Legislatura.objects.get(id=self.context.get('legislatura'))
legislatura = Legislatura.objects.get(
id=self.context.get('legislatura'))
except ObjectDoesNotExist:
legislatura = Legislatura.objects.first()
mandato = Mandato.objects.filter(
@ -92,7 +154,8 @@ class ParlamentarSerializerVerbose(serializers.ModelSerializer):
self.logger.error("Não há legislaturas cadastradas.")
return ""
try:
legislatura = Legislatura.objects.get(id=self.context.get('legislatura'))
legislatura = Legislatura.objects.get(
id=self.context.get('legislatura'))
except ObjectDoesNotExist:
legislatura = Legislatura.objects.first()
@ -109,8 +172,8 @@ class ParlamentarSerializerVerbose(serializers.ModelSerializer):
# Caso não exista filiação com essas condições
except ObjectDoesNotExist:
self.logger.warning("user=" + username + ". Parlamentar com (data<={} e data_desfiliacao>={}) "
"ou (data<={} e data_desfiliacao=Null)) não possui filiação."
.format(legislatura.data_fim, legislatura.data_fim, legislatura.data_fim))
"ou (data<={} e data_desfiliacao=Null)) não possui filiação."
.format(legislatura.data_fim, legislatura.data_fim, legislatura.data_fim))
filiacao = 'Não possui filiação'
# Caso exista mais de uma filiação nesse intervalo
@ -131,4 +194,5 @@ class ParlamentarSerializerVerbose(serializers.ModelSerializer):
class Meta:
model = Parlamentar
fields = ['id', 'nome_parlamentar', 'fotografia_cropped', 'fotografia', 'ativo', 'partido', 'titular']
fields = ['id', 'nome_parlamentar', 'fotografia_cropped',
'fotografia', 'ativo', 'partido', 'titular', ]

10
sapl/api/signals.py

@ -0,0 +1,10 @@
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch.dispatcher import receiver
from rest_framework.authtoken.models import Token
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)

8
sapl/api/views.py

@ -1,8 +1,6 @@
import logging
from django.conf import settings
from django.db.models.signals import post_save
from django.dispatch import receiver
from django.utils.translation import ugettext_lazy as _
from rest_framework.authtoken.models import Token
from rest_framework.decorators import api_view, permission_classes
@ -11,12 +9,6 @@ from rest_framework.response import Response
from rest_framework.views import APIView
@receiver(post_save, sender=settings.AUTH_USER_MODEL)
def create_auth_token(sender, instance=None, created=False, **kwargs):
if created:
Token.objects.create(user=instance)
@api_view(['POST'])
@permission_classes([IsAdminUser])
def recria_token(request, pk):

14
sapl/api/viewset.py

@ -1,5 +1,7 @@
import logging
from django.apps.registry import apps
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist
from django.db.models import Q
@ -8,10 +10,9 @@ 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, \
from drfautoapi.drfautoapi import customize, ApiViewSetConstrutor, \
wrapper_queryset_response_for_drf_action, \
BusinessRulesNotImplementedMixin
from sapl.api.core.serializers import ChoiceSerializer
from sapl.api.permissions import SaplModelPermissions
from sapl.api.serializers import ParlamentarSerializerVerbose, \
ParlamentarSerializerPublic
@ -26,7 +27,14 @@ from sapl.protocoloadm.models import DocumentoAdministrativo, \
from sapl.sessao.models import SessaoPlenaria, ExpedienteSessao
from sapl.utils import models_with_gr_for_model, choice_anos_com_sessaoplenaria
SaplApiViewSetConstrutor = SaplApiViewSetConstrutor.build_class()
SaplApiViewSetConstrutor = ApiViewSetConstrutor.build_class(
[
apps.get_app_config('contenttypes')
] + [
apps.get_app_config(n[5:]) for n in settings.SAPL_APPS
]
)
@customize(ContentType)

9
sapl/settings.py

@ -158,7 +158,7 @@ REST_FRAMEWORK = {
"rest_framework.authentication.SessionAuthentication",
),
'DEFAULT_SCHEMA_CLASS': 'sapl.api.core.schema.Schema',
'DEFAULT_SCHEMA_CLASS': 'sapl.api.schema.Schema',
"DEFAULT_PAGINATION_CLASS": "sapl.api.pagination.StandardPagination",
@ -168,6 +168,13 @@ REST_FRAMEWORK = {
),
}
DRFAUTOAPI = {
'DEFAULT_SERIALIZER_MODULE': 'sapl.api.serializers',
'DEFAULT_FILTER_MODULE': 'sapl.api.forms',
'GLOBAL_SERIALIZER_MIXIN': 'sapl.api.serializers.SaplSerializerMixin',
'GLOBAL_FILTERSET_MIXIN': 'sapl.api.forms.SaplFilterSetMixin'
}
SPECTACULAR_SETTINGS = {
'TITLE': 'Sapl API - docs',
'DESCRIPTION': 'Sapl API - Docs',

Loading…
Cancel
Save