Browse Source

add commentários em viewset deprecated

pull/2465/head
Leandro Roberto 6 years ago
parent
commit
bed2e052dd
  1. 326
      sapl/api/deprecated.py
  2. 36
      sapl/api/urls.py
  3. 281
      sapl/api/views.py

326
sapl/api/deprecated.py

@ -0,0 +1,326 @@
import logging
from django import apps
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.db.models import Q
from django.db.models.fields.files import FileField
from django.http import Http404
from django.utils.decorators import classonlymethod
from django.utils.text import capfirst
from django.utils.translation import ugettext_lazy as _
import django_filters
from django_filters.rest_framework.backends import DjangoFilterBackend
from django_filters.rest_framework.filterset import FilterSet
from django_filters.utils import resolve_field
from rest_framework import serializers as rest_serializers
from rest_framework.decorators import list_route, detail_route,\
permission_classes
from rest_framework.generics import ListAPIView
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin
from rest_framework.permissions import (IsAuthenticated,
IsAuthenticatedOrReadOnly, AllowAny)
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from sapl.api.forms import (AutorChoiceFilterSet, AutoresPossiveisFilterSet,
AutorSearchForFieldFilterSet)
from sapl.api.permissions import SaplModelPermissions
from sapl.api.serializers import (AutorChoiceSerializer, AutorSerializer,
ChoiceSerializer,
ModelChoiceSerializer,
SessaoPlenariaOldSerializer,
MateriaLegislativaOldSerializer)
from sapl.base.models import TipoAutor, Autor
from sapl.comissoes.models import Comissao
from sapl.materia.models import MateriaLegislativa, Proposicao
from sapl.parlamentares.models import Parlamentar
from sapl.sessao.models import SessaoPlenaria
from sapl.utils import SaplGenericRelation
class ModelChoiceView(ListAPIView):
"""
Deprecated
TODO Migrar para customização na api automática
"""
# FIXME aplicar permissão correta de usuário
permission_classes = (IsAuthenticated,)
serializer_class = ModelChoiceSerializer
def get(self, request, *args, **kwargs):
self.model = ContentType.objects.get_for_id(
self.kwargs['content_type']).model_class()
pagination = request.GET.get('pagination', '')
if pagination == 'False':
self.pagination_class = None
return ListAPIView.get(self, request, *args, **kwargs)
def get_queryset(self):
return self.model.objects.all()
class AutorListView(ListAPIView):
"""
Deprecated
TODO Migrar para customização na api automática
Listagem de Autores com filtro para autores cadastrados
e/ou possíveis autores.
- tr - tipo do resultado
Prepera Lista de Autores para 2 cenários distintos
- default = 1
= 1 -> para (value, text) usados geralmente
em combobox, radiobox, checkbox, etc com pesquisa básica
de Autores feita pelo django-filter
-> processo usado nas pesquisas, o mais usado.
= 3 -> Devolve instancias da classe Autor filtradas pelo
django-filter
- tipo - chave primária do Tipo de Autor a ser filtrado
- q - busca textual no nome do Autor ou em fields_search
declarados no field SaplGenericRelation das GenericFks
A busca textual acontece via django-filter com a
variável `tr` igual 1 ou 3. Em caso contrário,
o django-filter é desativado e a busca é feita
no model do ContentType associado ao tipo.
- q_0 / q_1 - q_0 é opcional e quando usado, faz o código ignorar "q"...
q_0 -> campos lookup a serem filtrados em qualquer Model
que implemente SaplGenericRelation
q_1 -> o valor que será pesquisado no lookup de q_0
q_0 e q_1 podem ser separados por ","... isso dará a
possibilidade de filtrar mais de um campo.
http://localhost:8000
/api/autor?tr=1&q_0=parlamentar_set__ativo&q_1=False
/api/autor?tr=1&q_0=parlamentar_set__ativo&q_1=True
/api/autor?tr=3&q_0=parlamentar_set__ativo&q_1=False
/api/autor?tr=3&q_0=parlamentar_set__ativo&q_1=True
http://localhost:8000
/api/autor?tr=1
&q_0=parlamentar_set__nome_parlamentar__icontains,
parlamentar_set__ativo
&q_1=Carvalho,False
/api/autor?tr=1
&q_0=parlamentar_set__nome_parlamentar__icontains,
parlamentar_set__ativo
&q_1=Carvalho,True
/api/autor?tr=3
&q_0=parlamentar_set__nome_parlamentar__icontains,
parlamentar_set__ativo
&q_1=Carvalho,False
/api/autor?tr=3
&q_0=parlamentar_set__nome_parlamentar__icontains,
parlamentar_set__ativo
&q_1=Carvalho,True
não importa o campo que vc passe de qualquer dos Models
ligados... é possível ver que models são esses,
na ocasião do commit deste texto, executando:
In [6]: from sapl.utils import models_with_gr_for_model
In [7]: models_with_gr_for_model(Autor)
Out[7]:
[sapl.parlamentares.models.Parlamentar,
sapl.parlamentares.models.Frente,
sapl.comissoes.models.Comissao,
sapl.materia.models.Orgao,
sapl.sessao.models.Bancada,
sapl.sessao.models.Bloco]
qualquer atributo destes models podem ser passados
para busca
"""
logger = logging.getLogger(__name__)
TR_AUTOR_CHOICE_SERIALIZER = 1
TR_AUTOR_SERIALIZER = 3
permission_classes = (IsAuthenticatedOrReadOnly,)
queryset = Autor.objects.all()
model = Autor
filter_class = AutorChoiceFilterSet
filter_backends = (DjangoFilterBackend, )
serializer_class = AutorChoiceSerializer
@property
def tr(self):
username = self.request.user.username
try:
tr = int(self.request.GET.get
('tr', AutorListView.TR_AUTOR_CHOICE_SERIALIZER))
if tr not in (AutorListView.TR_AUTOR_CHOICE_SERIALIZER,
AutorListView.TR_AUTOR_SERIALIZER):
return AutorListView.TR_AUTOR_CHOICE_SERIALIZER
except Exception as e:
self.logger.error('user=' + username + '. ' + str(e))
return AutorListView.TR_AUTOR_CHOICE_SERIALIZER
return tr
def get(self, request, *args, **kwargs):
if self.tr == AutorListView.TR_AUTOR_SERIALIZER:
self.serializer_class = AutorSerializer
self.permission_classes = (IsAuthenticated,)
if self.filter_class and 'q_0' in request.GET:
self.filter_class = AutorSearchForFieldFilterSet
return ListAPIView.get(self, request, *args, **kwargs)
class AutoresProvaveisListView(ListAPIView):
"""
Deprecated
TODO Migrar para customização na api automática
"""
logger = logging.getLogger(__name__)
permission_classes = (IsAuthenticatedOrReadOnly,)
queryset = Autor.objects.all()
model = Autor
filter_class = None
filter_backends = []
serializer_class = ChoiceSerializer
def get_queryset(self):
params = {'content_type__isnull': False}
username = self.request.user.username
tipo = ''
try:
tipo = int(self.request.GET.get('tipo', ''))
if tipo:
params['id'] = tipo
except Exception as e:
self.logger.error('user= ' + username + '. ' + str(e))
pass
tipos = TipoAutor.objects.filter(**params)
if not tipos.exists() and tipo:
raise Http404()
r = []
for tipo in tipos:
q = self.request.GET.get('q', '').strip()
model_class = tipo.content_type.model_class()
fields = list(filter(
lambda field: isinstance(field, SaplGenericRelation) and
field.related_model == Autor,
model_class._meta.get_fields(include_hidden=True)))
"""
fields - é um array de SaplGenericRelation que deve possuir o
atributo fields_search. Verifique na documentação da classe
a estrutura de fields_search.
"""
assert len(fields) >= 1, (_(
'Não foi encontrado em %(model)s um atributo do tipo '
'SaplGenericRelation que use o model %(model_autor)s') % {
'model': model_class._meta.verbose_name,
'model_autor': Autor._meta.verbose_name})
qs = model_class.objects.all()
q_filter = Q()
if q:
for item in fields:
if item.related_model != Autor:
continue
q_fs = Q()
for field in item.fields_search:
q_fs = q_fs | Q(**{'%s%s' % (
field[0],
field[1]): q})
q_filter = q_filter & q_fs
qs = qs.filter(q_filter).distinct(
fields[0].fields_search[0][0]).order_by(
fields[0].fields_search[0][0])
else:
qs = qs.order_by(fields[0].fields_search[0][0])
qs = qs.values_list(
'id', fields[0].fields_search[0][0])
r += list(qs)
if tipos.count() > 1:
r.sort(key=lambda x: x[1].upper())
return r
class AutoresPossiveisListView(ListAPIView):
"""
Deprecated
TODO Migrar para customização na api automática
"""
permission_classes = (IsAuthenticatedOrReadOnly,)
queryset = Autor.objects.all()
model = Autor
pagination_class = None
filter_class = AutoresPossiveisFilterSet
serializer_class = AutorChoiceSerializer
class MateriaLegislativaViewSet(ListModelMixin,
RetrieveModelMixin,
GenericViewSet):
"""
Deprecated
TODO Migrar para customização na api automática
"""
permission_classes = (IsAuthenticated,)
serializer_class = MateriaLegislativaOldSerializer
queryset = MateriaLegislativa.objects.all()
filter_backends = (DjangoFilterBackend,)
filter_fields = ('numero', 'ano', 'tipo', )
class SessaoPlenariaViewSet(ListModelMixin,
RetrieveModelMixin,
GenericViewSet):
"""
Deprecated
TODO Migrar para customização na api automática
"""
permission_classes = (AllowAny,)
serializer_class = SessaoPlenariaOldSerializer
queryset = SessaoPlenaria.objects.all()
filter_backends = (DjangoFilterBackend,)
filter_fields = ('data_inicio', 'data_fim', 'interativa')

36
sapl/api/urls.py

@ -5,10 +5,10 @@ from drf_yasg.views import get_schema_view
from rest_framework import permissions
from rest_framework.routers import DefaultRouter
from sapl.api.views import (AutoresPossiveisListView, AutoresProvaveisListView,
AutorListView, MateriaLegislativaViewSet,
ModelChoiceView, SessaoPlenariaViewSet,
SaplSetViews)
from sapl.api.deprecated import MateriaLegislativaViewSet, SessaoPlenariaViewSet,\
AutoresProvaveisListView, AutoresPossiveisListView, AutorListView,\
ModelChoiceView
from sapl.api.views import SaplSetViews
from .apps import AppConfig
@ -28,18 +28,6 @@ for app, built_sets in SaplSetViews.items():
urlpatterns_router = router.urls
# TODO: refatorar para customização da api automática
urlpatterns_api = [
url(r'^autor/provaveis',
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'),
]
schema_view = get_schema_view(
openapi.Info(
@ -52,18 +40,30 @@ schema_view = get_schema_view(
permission_classes=(permissions.AllowAny,),
)
urlpatterns_api += [
urlpatterns_api = [
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 = [
url(r'^autor/provaveis',
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 = [
url(r'^api/', include(deprecated_urlpatterns_api)),
url(r'^api/', include(urlpatterns_api)),
url(r'^api/', include(urlpatterns_router)),

281
sapl/api/views.py

@ -1,4 +1,3 @@
import logging
from django import apps
@ -6,7 +5,6 @@ from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.db.models import Q
from django.db.models.fields.files import FileField
from django.http import Http404
from django.utils.decorators import classonlymethod
from django.utils.text import capfirst
from django.utils.translation import ugettext_lazy as _
@ -15,284 +13,13 @@ from django_filters.rest_framework.backends import DjangoFilterBackend
from django_filters.rest_framework.filterset import FilterSet
from django_filters.utils import resolve_field
from rest_framework import serializers as rest_serializers
from rest_framework.decorators import list_route, detail_route,\
permission_classes
from rest_framework.generics import ListAPIView
from rest_framework.mixins import ListModelMixin, RetrieveModelMixin
from rest_framework.permissions import (IsAuthenticated,
IsAuthenticatedOrReadOnly, AllowAny)
from rest_framework.response import Response
from rest_framework.viewsets import GenericViewSet, ModelViewSet
from sapl.api.forms import (AutorChoiceFilterSet, AutoresPossiveisFilterSet,
AutorSearchForFieldFilterSet)
from rest_framework.decorators import list_route, detail_route
from rest_framework.viewsets import ModelViewSet
from sapl.api.permissions import SaplModelPermissions
from sapl.api.serializers import (AutorChoiceSerializer, AutorSerializer,
ChoiceSerializer,
ModelChoiceSerializer,
SessaoPlenariaOldSerializer,
MateriaLegislativaOldSerializer)
from sapl.base.models import TipoAutor, Autor
from sapl.comissoes.models import Comissao
from sapl.materia.models import MateriaLegislativa, Proposicao
from sapl.materia.models import Proposicao
from sapl.parlamentares.models import Parlamentar
from sapl.sessao.models import SessaoPlenaria
from sapl.utils import SaplGenericRelation
class ModelChoiceView(ListAPIView):
# FIXME aplicar permissão correta de usuário
permission_classes = (IsAuthenticated,)
serializer_class = ModelChoiceSerializer
def get(self, request, *args, **kwargs):
self.model = ContentType.objects.get_for_id(
self.kwargs['content_type']).model_class()
pagination = request.GET.get('pagination', '')
if pagination == 'False':
self.pagination_class = None
return ListAPIView.get(self, request, *args, **kwargs)
def get_queryset(self):
return self.model.objects.all()
class AutorListView(ListAPIView):
"""
Listagem de Autores com filtro para autores cadastrados
e/ou possíveis autores.
- tr - tipo do resultado
Prepera Lista de Autores para 3 cenários distintos
- default = 1
= 1 -> para (value, text) usados geralmente
em combobox, radiobox, checkbox, etc com pesquisa básica
de Autores feita pelo django-filter
-> processo usado nas pesquisas, o mais usado.
= 3 -> Devolve instancias da classe Autor filtradas pelo
django-filter
- tipo - chave primária do Tipo de Autor a ser filtrado
- q - busca textual no nome do Autor ou em fields_search
declarados no field SaplGenericRelation das GenericFks
A busca textual acontece via django-filter com a
variável `tr` igual 1 ou 3. Em caso contrário,
o django-filter é desativado e a busca é feita
no model do ContentType associado ao tipo.
- q_0 / q_1 - q_0 é opcional e quando usado, faz o código ignorar "q"...
q_0 -> campos lookup a serem filtrados em qualquer Model
que implemente SaplGenericRelation
q_1 -> o valor que será pesquisado no lookup de q_0
q_0 e q_1 podem ser separados por ","... isso dará a
possibilidade de filtrar mais de um campo.
http://localhost:8000
/api/autor?tr=1&q_0=parlamentar_set__ativo&q_1=False
/api/autor?tr=1&q_0=parlamentar_set__ativo&q_1=True
/api/autor?tr=3&q_0=parlamentar_set__ativo&q_1=False
/api/autor?tr=3&q_0=parlamentar_set__ativo&q_1=True
http://localhost:8000
/api/autor?tr=1
&q_0=parlamentar_set__nome_parlamentar__icontains,
parlamentar_set__ativo
&q_1=Carvalho,False
/api/autor?tr=1
&q_0=parlamentar_set__nome_parlamentar__icontains,
parlamentar_set__ativo
&q_1=Carvalho,True
/api/autor?tr=3
&q_0=parlamentar_set__nome_parlamentar__icontains,
parlamentar_set__ativo
&q_1=Carvalho,False
/api/autor?tr=3
&q_0=parlamentar_set__nome_parlamentar__icontains,
parlamentar_set__ativo
&q_1=Carvalho,True
não importa o campo que vc passe de qualquer dos Models
ligados... é possível ver que models são esses,
na ocasião do commit deste texto, executando:
In [6]: from sapl.utils import models_with_gr_for_model
In [7]: models_with_gr_for_model(Autor)
Out[7]:
[sapl.parlamentares.models.Parlamentar,
sapl.parlamentares.models.Frente,
sapl.comissoes.models.Comissao,
sapl.materia.models.Orgao,
sapl.sessao.models.Bancada,
sapl.sessao.models.Bloco]
qualquer atributo destes models podem ser passados
para busca
"""
logger = logging.getLogger(__name__)
TR_AUTOR_CHOICE_SERIALIZER = 1
TR_AUTOR_SERIALIZER = 3
permission_classes = (IsAuthenticatedOrReadOnly,)
queryset = Autor.objects.all()
model = Autor
filter_class = AutorChoiceFilterSet
filter_backends = (DjangoFilterBackend, )
serializer_class = AutorChoiceSerializer
@property
def tr(self):
username = self.request.user.username
try:
tr = int(self.request.GET.get
('tr', AutorListView.TR_AUTOR_CHOICE_SERIALIZER))
if tr not in (AutorListView.TR_AUTOR_CHOICE_SERIALIZER,
AutorListView.TR_AUTOR_SERIALIZER):
return AutorListView.TR_AUTOR_CHOICE_SERIALIZER
except Exception as e:
self.logger.error('user=' + username + '. ' + str(e))
return AutorListView.TR_AUTOR_CHOICE_SERIALIZER
return tr
def get(self, request, *args, **kwargs):
if self.tr == AutorListView.TR_AUTOR_SERIALIZER:
self.serializer_class = AutorSerializer
self.permission_classes = (IsAuthenticated,)
if self.filter_class and 'q_0' in request.GET:
self.filter_class = AutorSearchForFieldFilterSet
return ListAPIView.get(self, request, *args, **kwargs)
class AutoresProvaveisListView(ListAPIView):
logger = logging.getLogger(__name__)
permission_classes = (IsAuthenticatedOrReadOnly,)
queryset = Autor.objects.all()
model = Autor
filter_class = None
filter_backends = []
serializer_class = ChoiceSerializer
def get_queryset(self):
params = {'content_type__isnull': False}
username = self.request.user.username
tipo = ''
try:
tipo = int(self.request.GET.get('tipo', ''))
if tipo:
params['id'] = tipo
except Exception as e:
self.logger.error('user= ' + username + '. ' + str(e))
pass
tipos = TipoAutor.objects.filter(**params)
if not tipos.exists() and tipo:
raise Http404()
r = []
for tipo in tipos:
q = self.request.GET.get('q', '').strip()
model_class = tipo.content_type.model_class()
fields = list(filter(
lambda field: isinstance(field, SaplGenericRelation) and
field.related_model == Autor,
model_class._meta.get_fields(include_hidden=True)))
"""
fields - é um array de SaplGenericRelation que deve possuir o
atributo fields_search. Verifique na documentação da classe
a estrutura de fields_search.
"""
assert len(fields) >= 1, (_(
'Não foi encontrado em %(model)s um atributo do tipo '
'SaplGenericRelation que use o model %(model_autor)s') % {
'model': model_class._meta.verbose_name,
'model_autor': Autor._meta.verbose_name})
qs = model_class.objects.all()
q_filter = Q()
if q:
for item in fields:
if item.related_model != Autor:
continue
q_fs = Q()
for field in item.fields_search:
q_fs = q_fs | Q(**{'%s%s' % (
field[0],
field[1]): q})
q_filter = q_filter & q_fs
qs = qs.filter(q_filter).distinct(
fields[0].fields_search[0][0]).order_by(
fields[0].fields_search[0][0])
else:
qs = qs.order_by(fields[0].fields_search[0][0])
qs = qs.values_list(
'id', fields[0].fields_search[0][0])
r += list(qs)
if tipos.count() > 1:
r.sort(key=lambda x: x[1].upper())
return r
class AutoresPossiveisListView(ListAPIView):
permission_classes = (IsAuthenticatedOrReadOnly,)
queryset = Autor.objects.all()
model = Autor
pagination_class = None
filter_class = AutoresPossiveisFilterSet
serializer_class = AutorChoiceSerializer
class MateriaLegislativaViewSet(ListModelMixin,
RetrieveModelMixin,
GenericViewSet):
permission_classes = (IsAuthenticated,)
serializer_class = MateriaLegislativaOldSerializer
queryset = MateriaLegislativa.objects.all()
filter_backends = (DjangoFilterBackend,)
filter_fields = ('numero', 'ano', 'tipo', )
class SessaoPlenariaViewSet(ListModelMixin,
RetrieveModelMixin,
GenericViewSet):
permission_classes = (AllowAny,)
serializer_class = SessaoPlenariaOldSerializer
queryset = SessaoPlenaria.objects.all()
filter_backends = (DjangoFilterBackend,)
filter_fields = ('data_inicio', 'data_fim', 'interativa')
class SaplApiViewSetConstrutor(ModelViewSet):

Loading…
Cancel
Save