根据DRF文档,我开始使用ViewSet并实现了list, retrieve, create, update and destroy
操作。我有另一个APIView,可以为其编写架构(ManualSchema),当我导航到/docs/
时,我可以找到文档以及进行交互的实时终结点。
我希望为每个视图集操作创建单独的架构。我尝试写一个,但是没有显示出来,所以我想我缺少了一些东西。
代码如下:
class Clients(viewsets.ViewSet):
'''
Clients is DRF viewset which implements `create`, `update`, `read` actions by implementing create, update, list and retrieve functions respectively.
'''
list_schema = schemas.ManualSchema(fields=[
coreapi.Field(
'status',
required=False,
location='query',
description='Accepted values are `active`, `inactive`'
),
],
description='Clients list',
encoding='application/x-www-form-urlencoded')
@action(detail=True, schema=list_schema)
def list(self, request):
'''Logic for listing'''
def retrieve(self, request, oid=None):
'''Logic for retrieval'''
create_schema = schemas.ManualSchema(fields=[
coreapi.Field(
'name',
required=False,
location='body',
),
coreapi.Field(
'location',
required=False,
location='body',
),
],
description='Clients list',
encoding='application/x-www-form-urlencoded')
@action(detail=True, schema=create_schema)
def create(self, request):
'''Logic for creation'''
答案 0 :(得分:2)
所以我将回答我自己的问题。我看了用于模式生成的DRF源代码。我提出了计划并执行了以下步骤。
我继承了rest_framework.schemas
模块中定义的SchemaGenerator类。下面是代码。
class CoreAPISchemaGenerator(SchemaGenerator):
def get_links(self, request=None, **kwargs):
links = LinkNode()
paths = list()
view_endpoints = list()
for path, method, callback in self.endpoints:
view = self.create_view(callback, method, request)
path = self.coerce_path(path, method, view)
paths.append(path)
view_endpoints.append((path, method, view))
if not paths:
return None
prefix = self.determine_path_prefix(paths)
for path, method, view in view_endpoints:
if not self.has_view_permissions(path, method, view):
continue
actions = getattr(view, 'actions', None)
schemas = getattr(view, 'schemas', None)
if not schemas:
link = view.schema.get_link(path, method, base_url=self.url)
subpath = path[len(prefix):]
keys = self.get_keys(subpath, method, view, view.schema)
insert_into(links, keys, link)
else:
action_map = getattr(view, 'action_map', None)
method_name = action_map.get(method.lower())
schema = schemas.get(method_name)
link = schema.get_link(path, method, base_url=self.url)
subpath = path[len(prefix):]
keys = self.get_keys(subpath, method, view, schema)
insert_into(links, keys, link)
return links
def get_keys(self, subpath, method, view, schema=None):
if schema and hasattr(schema, 'endpoint_name'):
return [schema.endpoint_name]
else:
if hasattr(view, 'action'):
action = view.action
else:
if is_list_view(subpath, method, view):
action = 'list'
else:
action = self.default_mapping[method.lower()]
named_path_components = [
component for component
in subpath.strip('/').split('/')
if '{' not in component
]
if is_custom_action(action):
if len(view.action_map) > 1:
action = self.default_mapping[method.lower()]
if action in self.coerce_method_names:
action = self.coerce_method_names[action]
return named_path_components + [action]
else:
return named_path_components[:-1] + [action]
if action in self.coerce_method_names:
action = self.coerce_method_names[action]
return named_path_components + [action]
我专门修改了两个功能 get_links 和 get_keys ,因为它们可以实现所需的功能。
此外,对于我正在编写的视图集中的所有功能,我都为其专用了一个单独的模式。我只是创建了一个字典来保留函数名到架构实例的映射。为了更好的方法,我创建了一个单独的文件来存储架构。例如。如果我有一个视图集Clients
,则在返回模式实例的已定义静态方法中创建了一个对应的ClientsSchema
类。
示例
In file where I am defining my schemas,
class ClientsSchema():
@staticmethod
def list_schema():
schema = schemas.ManualSchema(
fields = [],
description = ''
)
schema.endpoint_name = 'Clients Listing'
return schema
In my apis.py,
class Clients(viewsets.ViewSet):
schemas = {
'list': ClientsSchema.list_schema()
}
def list(self, request, **kwargs):
pass
此设置使我可以为添加到视图集中的任何类型的功能定义架构。除此之外,我还希望端点具有可识别的名称,而不是DRF生成的名称,例如a > b > update > update
。
为了实现这一点,我向返回的endpoint_name
对象添加了schema
属性。该部分在get_keys
函数中被处理。
最后,在urls.py中,其中包括文档的url,我们需要使用自定义模式生成器。像这样的东西
urlpatterns.append(url(r'^livedocs/', include_docs_urls(title='My Services', generator_class=CoreAPISchemaGenerator)))
出于安全目的,我无法共享任何快照。对此表示歉意。希望这会有所帮助。
答案 1 :(得分:1)
我认为您无法做的事情。 ViewSet
does not provide any method handlers因此,您不能在方法@action
和create
上使用list
装饰器,因为它们是现有路由。