from django.db import IntegrityError
from rest_framework.response   import Response
from rest_framework.pagination import PageNumberPagination
from dynamic_rest.viewsets     import DynamicModelViewSet

class CustomPagination(PageNumberPagination):
  page_size = 100
  max_page_size = 10000
  page_size_query_param = 'page_size'

class CustomModelViewSet(DynamicModelViewSet):
  pagination_class = CustomPagination
  ordering_fields  = '__all__'
  ordering         = 'pk'

  # don't check global permissions for detail routes
  def check_permissions(self, request):
    if self.action in ('retrieve', 'update', 'partial_update', 'destroy'): return

    method  = request.method.lower()
    handler = getattr(self, method, None)

    if handler and getattr(handler, 'detail', False): return

    return super().check_permissions(request)

  def handle_exception(self, exc):
    try:
      return super().handle_exception(exc)
    except IntegrityError as error:
      return Response({ 'detail': error.args[0] }, status = 400)

def viewset_for(model, serializer, **attrs):
  attrs['queryset']         = model.objects
  attrs['serializer_class'] = serializer

  return type(model.__name__ + 'ViewSet', (CustomModelViewSet,), attrs)
