mirror of https://github.com/interlegis/sapl.git
Leandro Roberto
6 years ago
3 changed files with 348 additions and 295 deletions
@ -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 já 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') |
Loading…
Reference in new issue