views.py 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. """
  2. views.py # Houses `SchemaView`, `APIView` subclass.
  3. See schemas.__init__.py for package overview.
  4. """
  5. from rest_framework import exceptions, renderers
  6. from rest_framework.response import Response
  7. from rest_framework.schemas import coreapi
  8. from rest_framework.settings import api_settings
  9. from rest_framework.views import APIView
  10. class SchemaView(APIView):
  11. _ignore_model_permissions = True
  12. schema = None # exclude from schema
  13. renderer_classes = None
  14. schema_generator = None
  15. public = False
  16. def __init__(self, *args, **kwargs):
  17. super().__init__(*args, **kwargs)
  18. if self.renderer_classes is None:
  19. if coreapi.is_enabled():
  20. self.renderer_classes = [
  21. renderers.CoreAPIOpenAPIRenderer,
  22. renderers.CoreJSONRenderer
  23. ]
  24. else:
  25. self.renderer_classes = [
  26. renderers.OpenAPIRenderer,
  27. renderers.JSONOpenAPIRenderer,
  28. ]
  29. if renderers.BrowsableAPIRenderer in api_settings.DEFAULT_RENDERER_CLASSES:
  30. self.renderer_classes += [renderers.BrowsableAPIRenderer]
  31. def get(self, request, *args, **kwargs):
  32. schema = self.schema_generator.get_schema(request, self.public)
  33. if schema is None:
  34. raise exceptions.PermissionDenied()
  35. return Response(schema)
  36. def handle_exception(self, exc):
  37. # Schema renderers do not render exceptions, so re-perform content
  38. # negotiation with default renderers.
  39. self.renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
  40. neg = self.perform_content_negotiation(self.request, force=True)
  41. self.request.accepted_renderer, self.request.accepted_media_type = neg
  42. return super().handle_exception(exc)