mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-04 12:30:11 +03:00
Initial Refactor Step
* Add descriptor class * call from generator * proxy back to generator for implementation.
This commit is contained in:
parent
9aaea2586b
commit
8f13e9c143
|
@ -256,6 +256,38 @@ class EndpointInspector(object):
|
|||
]
|
||||
|
||||
|
||||
class APIViewSchemaDescriptor(object):
|
||||
"""
|
||||
Descriptor class on APIView.
|
||||
|
||||
Responsible for per-view instrospection and schema generation.
|
||||
"""
|
||||
def __get__(self, instance, owner):
|
||||
# ???: Is this TOO simple? (Option is to return a new instance each time.)
|
||||
self.view = instance
|
||||
return self
|
||||
|
||||
def get_link(self, path, method, generator):
|
||||
"""
|
||||
Generate `coreapi.Link` for view.
|
||||
|
||||
This is the main _public_ access point.
|
||||
"""
|
||||
assert self.view is not None, "Schema generation REQUIRES a view instance. (Hint: you accessed `schema` from the view CLASS rather than an instance.)"
|
||||
view = self.view
|
||||
|
||||
# TEMP: now we proxy back to the generator
|
||||
link = generator.get_link(path, method, view)
|
||||
|
||||
return link
|
||||
|
||||
# TODO: Where should this live?
|
||||
# - We import APIView here. So we can't import the descriptor into `views`
|
||||
# - APIView is only used by SchemaView.
|
||||
# - ???: Make `schemas` a package and move SchemaView to `schema.views`
|
||||
APIView.schema = APIViewSchemaDescriptor()
|
||||
|
||||
|
||||
class SchemaGenerator(object):
|
||||
# Map HTTP methods onto actions.
|
||||
default_mapping = {
|
||||
|
@ -341,7 +373,7 @@ class SchemaGenerator(object):
|
|||
for path, method, view in view_endpoints:
|
||||
if not self.has_view_permissions(path, method, view):
|
||||
continue
|
||||
link = self.get_link(path, method, view)
|
||||
link = self.get_link_proxy(path, method, view)
|
||||
subpath = path[len(prefix):]
|
||||
keys = self.get_keys(subpath, method, view)
|
||||
insert_into(links, keys, link)
|
||||
|
@ -434,6 +466,18 @@ class SchemaGenerator(object):
|
|||
return path.replace('{pk}', '{%s}' % field_name)
|
||||
|
||||
# Methods for generating each individual `Link` instance...
|
||||
def get_link_proxy(self, path, method, view):
|
||||
"""
|
||||
Proxy to view's descriptor for link
|
||||
|
||||
TEMPORARY NAME at least.
|
||||
"""
|
||||
schema = view.schema
|
||||
|
||||
# To begin we pass generator — we still need its methods.
|
||||
link = schema.get_link(path, method, self)
|
||||
|
||||
return link
|
||||
|
||||
def get_link(self, path, method, view):
|
||||
"""
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import unittest
|
||||
|
||||
import pytest
|
||||
from django.conf.urls import include, url
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.http import Http404
|
||||
|
@ -10,7 +11,9 @@ from rest_framework.compat import coreapi, coreschema
|
|||
from rest_framework.decorators import detail_route, list_route
|
||||
from rest_framework.request import Request
|
||||
from rest_framework.routers import DefaultRouter
|
||||
from rest_framework.schemas import SchemaGenerator, get_schema_view
|
||||
from rest_framework.schemas import (
|
||||
APIViewSchemaDescriptor, SchemaGenerator, get_schema_view
|
||||
)
|
||||
from rest_framework.test import APIClient, APIRequestFactory
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.viewsets import ModelViewSet
|
||||
|
@ -496,3 +499,16 @@ class Test4605Regression(TestCase):
|
|||
'/auth/convert-token/'
|
||||
])
|
||||
assert prefix == '/'
|
||||
|
||||
|
||||
class TestDescriptor(TestCase):
|
||||
|
||||
def test_apiview_schema_descriptor(self):
|
||||
view = APIView()
|
||||
assert hasattr(view, 'schema')
|
||||
assert isinstance(view.schema, APIViewSchemaDescriptor)
|
||||
|
||||
def test_get_link_requires_instance(self):
|
||||
descriptor = APIView.schema # Accessed from class
|
||||
with pytest.raises(AssertionError):
|
||||
descriptor.get_link(None, None, None) # ???: Do the dummy arguments require a tighter assert?
|
||||
|
|
Loading…
Reference in New Issue
Block a user