|
|
|
@ -9,6 +9,9 @@ from rest_framework.response import Response |
|
|
|
from rest_framework.views import APIView |
|
|
|
|
|
|
|
from drfautoapi.drfautoapi import ApiViewSetConstrutor |
|
|
|
from django.views.decorators.http import condition as django_condition |
|
|
|
|
|
|
|
from sapl.base.models import AuditLog |
|
|
|
|
|
|
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
|
|
@ -21,8 +24,80 @@ def recria_token(request, pk): |
|
|
|
|
|
|
|
return Response({"message": "Token recriado com sucesso!", "token": token.key}) |
|
|
|
|
|
|
|
class LastModifiedDecorator: |
|
|
|
""" - Decorator para adicionar suporte a Last-Modified em ViewSets |
|
|
|
- Baseado em django.views.decorators.http.condition |
|
|
|
|
|
|
|
- Por padrão utiliza o AuditLog para determinar a data do last_modified |
|
|
|
- Pode ser sobrescrito na customização do ViewSet caso necessário |
|
|
|
- Existe um exemplo de sobrescrita em sapl/api/views_materia.py |
|
|
|
|
|
|
|
- Devolve Last-Modified baseado no timestamp do último AuditLog |
|
|
|
- Se for uma listagem, considera o último AuditLog de todos os objetos |
|
|
|
retornados na listagem levando em consideração resultado de FilterSet. |
|
|
|
- Retorna 304 Not Modified se o recurso não foi modificado |
|
|
|
|
|
|
|
""" |
|
|
|
def __init__(self): |
|
|
|
pass |
|
|
|
|
|
|
|
def __call__(self, cls): |
|
|
|
|
|
|
|
original_dispatch = cls.dispatch |
|
|
|
self.model = cls.queryset.model |
|
|
|
|
|
|
|
def wrapped_dispatch(view, request, *args, **kwargs): |
|
|
|
drf_request = request |
|
|
|
wsgi_request = view.initialize_request(request, *args, **kwargs) |
|
|
|
|
|
|
|
last_modified_func = self.last_modified_func if not hasattr(view, 'last_modified_func') else view.last_modified_func |
|
|
|
|
|
|
|
def patched_viewset_method(*_args, **_kwargs): |
|
|
|
return original_dispatch(view, drf_request, *_args, **_kwargs) |
|
|
|
|
|
|
|
django_decorator = django_condition(last_modified_func=last_modified_func) |
|
|
|
decorated_viewset_method = django_decorator(patched_viewset_method) |
|
|
|
return decorated_viewset_method(wsgi_request, *args, view=view, **kwargs) |
|
|
|
|
|
|
|
cls.dispatch = wrapped_dispatch |
|
|
|
return cls |
|
|
|
|
|
|
|
def last_modified_func(self, request, *args, **kwargs): |
|
|
|
try: |
|
|
|
if 'pk' in kwargs: |
|
|
|
obj_id = kwargs['pk'] |
|
|
|
last_log = AuditLog.objects.filter( |
|
|
|
model_name=self.model._meta.model_name, |
|
|
|
object_id=obj_id |
|
|
|
).order_by('-timestamp').values_list('timestamp', flat=True).first() |
|
|
|
else: |
|
|
|
view = kwargs.get('view', None) |
|
|
|
if view: |
|
|
|
for backend in list(view.filter_backends): |
|
|
|
queryset = backend().filter_queryset(request, view.queryset, view) |
|
|
|
if queryset.exists(): |
|
|
|
last_log = AuditLog.objects.filter( |
|
|
|
model_name=self.model._meta.model_name, |
|
|
|
object_id__in=queryset.values_list('pk', flat=True) |
|
|
|
).order_by('-timestamp').values_list('timestamp', flat=True).first() |
|
|
|
else: |
|
|
|
last_log = None |
|
|
|
else: |
|
|
|
last_log = AuditLog.objects.filter( |
|
|
|
model_name=self.model._meta.model_name, |
|
|
|
object_id__in=self.model.objects.values_list('pk', flat=True) |
|
|
|
).order_by('-timestamp').values_list('timestamp', flat=True).first() |
|
|
|
|
|
|
|
if last_log: |
|
|
|
return last_log |
|
|
|
|
|
|
|
except Exception as e: |
|
|
|
logger.error(f"Erro ao obter last_modified: {e}") |
|
|
|
|
|
|
|
return None |
|
|
|
|
|
|
|
SaplApiViewSetConstrutor = ApiViewSetConstrutor |
|
|
|
SaplApiViewSetConstrutor.last_modified_method(LastModifiedDecorator) |
|
|
|
SaplApiViewSetConstrutor.import_modules([ |
|
|
|
'sapl.api.views_audiencia', |
|
|
|
'sapl.api.views_base', |
|
|
|
|