import csv import io from rest_framework.views import APIView from drf_yasg.utils import swagger_auto_schema from drf_yasg import openapi from .serializers import ExportModelSerializer from rest_framework.response import Response from django.http import HttpResponse import openpyxl from django.apps import apps from rest_framework import status from django.shortcuts import render from rest_framework import viewsets from .serializers import ExportModelSerializer def export_model_to_csv(request, model_name, fields, filters=None): model = apps.get_model('datastage', model_name) queryset = model.objects.filter(**(filters or {})).values(*fields) response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = f'attachment; filename="{model_name}.csv"' writer = csv.DictWriter(response, fieldnames=fields) writer.writeheader() for row in queryset: writer.writerow(row) return response def export_model_to_excel(request, model_name, fields, filters=None): model = apps.get_model('datastage', model_name) queryset = model.objects.filter(**(filters or {})).values(*fields) wb = openpyxl.Workbook() ws = wb.active ws.append(fields) for row in queryset: ws.append([row[field] for field in fields]) output = io.BytesIO() wb.save(output) output.seek(0) response = HttpResponse(output.read(), content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') response['Content-Disposition'] = f'attachment; filename="{model_name}.xlsx"' return response # Create your views here. from rest_framework.views import APIView class ExportModelView(APIView): my_tags = ['Reportes'] @swagger_auto_schema( manual_parameters=[ openapi.Parameter('model', openapi.IN_QUERY, description="Nombre del modelo (ejemplo: Registro500)", type=openapi.TYPE_STRING, required=True) ], responses={200: openapi.Response('Campos disponibles', schema=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ 'fields': openapi.Schema(type=openapi.TYPE_ARRAY, items=openapi.Items(type=openapi.TYPE_STRING)) } ))} ) def get(self, request, *args, **kwargs): """ Devuelve los campos disponibles para el modelo solicitado. Ejemplo: /api/reports/exportmodel/?model=Registro500 """ model_name = request.query_params.get('model') if not model_name: return Response({'error': 'model is required'}, status=status.HTTP_400_BAD_REQUEST) try: model = apps.get_model('datastage', model_name) except LookupError: return Response({'error': f'Model {model_name} not found'}, status=status.HTTP_404_NOT_FOUND) fields = [f.name for f in model._meta.fields] return Response({'fields': fields}) @swagger_auto_schema( request_body=ExportModelSerializer, responses={200: 'Archivo generado (Excel o CSV)'} ) def post(self, request, *args, **kwargs): model_name = request.data.get('model') fields = request.data.get('fields') filters = request.data.get('filters', {}) export_type = request.data.get('type', 'csv') if not model_name or not fields: return Response({'error': 'model and fields are required'}, status=status.HTTP_400_BAD_REQUEST) if export_type == 'excel': return export_model_to_excel(request, model_name, fields, filters) else: return export_model_to_csv(request, model_name, fields, filters)