mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-04 20:40:14 +03:00
Merge f772d72093
into 836e49b535
This commit is contained in:
commit
81f138203b
|
@ -69,6 +69,20 @@ When using viewsets, you should use the relevant action names as delimiters.
|
|||
Create a new user instance.
|
||||
"""
|
||||
|
||||
When using the `@detail_route` or `@list_route` decorators, the docstring for
|
||||
the decorated method may use the `action:` style delimiters.
|
||||
|
||||
class UserViewSet(viewsets.ModelViewSet):
|
||||
@detail_route(methods=('get', 'post'))
|
||||
def groups(self, request, pk=None):
|
||||
"""
|
||||
retrieve:
|
||||
Return the groups for the given user.
|
||||
|
||||
create:
|
||||
Add the user to a new group.
|
||||
"""
|
||||
|
||||
---
|
||||
|
||||
## Third party packages
|
||||
|
|
|
@ -8,7 +8,7 @@ from django.core.exceptions import PermissionDenied
|
|||
from django.db import models
|
||||
from django.http import Http404
|
||||
from django.utils import six
|
||||
from django.utils.encoding import force_text, smart_text
|
||||
from django.utils.encoding import force_text
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
from rest_framework import exceptions, renderers, serializers
|
||||
|
@ -19,7 +19,6 @@ from rest_framework.compat import (
|
|||
from rest_framework.request import clone_request
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.settings import api_settings
|
||||
from rest_framework.utils import formatting
|
||||
from rest_framework.utils.model_meta import _get_pk
|
||||
from rest_framework.views import APIView
|
||||
|
||||
|
@ -469,31 +468,36 @@ class SchemaGenerator(object):
|
|||
This will be based on the method docstring if one exists,
|
||||
or else the class docstring.
|
||||
"""
|
||||
method_name = getattr(view, 'action', method.lower())
|
||||
method_docstring = getattr(view, method_name, None).__doc__
|
||||
if method_docstring:
|
||||
method = method.lower()
|
||||
method_name = getattr(view, 'action', method)
|
||||
view_method = getattr(view, method_name, None)
|
||||
description = None
|
||||
if view_method:
|
||||
# An explicit docstring on the method or action.
|
||||
return formatting.dedent(smart_text(method_docstring))
|
||||
|
||||
description = view.get_view_description()
|
||||
description = api_settings.VIEW_DESCRIPTION_FUNCTION(view_method)
|
||||
if not description:
|
||||
description = view.get_view_description()
|
||||
lines = [line.strip() for line in description.splitlines()]
|
||||
current_section = ''
|
||||
sections = {'': ''}
|
||||
|
||||
for line in lines:
|
||||
if header_regex.match(line):
|
||||
current_section, seperator, lead = line.partition(':')
|
||||
current_section, separator, lead = line.partition(':')
|
||||
sections[current_section] = lead.strip()
|
||||
else:
|
||||
sections[current_section] += '\n' + line
|
||||
|
||||
header = getattr(view, 'action', method.lower())
|
||||
if header in sections:
|
||||
return sections[header].strip()
|
||||
if header in self.coerce_method_names:
|
||||
if self.coerce_method_names[header] in sections:
|
||||
return sections[self.coerce_method_names[header]].strip()
|
||||
return sections[''].strip()
|
||||
section_name = ''
|
||||
for attempt in (method_name, self.default_mapping.get(method, method)):
|
||||
if attempt in sections:
|
||||
section_name = attempt
|
||||
break
|
||||
if self.coerce_method_names.get(attempt) in sections:
|
||||
section_name = self.coerce_method_names[attempt]
|
||||
break
|
||||
|
||||
return sections[section_name].strip()
|
||||
|
||||
def get_encoding(self, path, method, view):
|
||||
"""
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
{% load rest_framework %}
|
||||
|
||||
{% for link_key, link in section.links|items %}
|
||||
{% with section_key=parent_key %}
|
||||
{% include "rest_framework/docs/link.html" %}
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
|
||||
{% for section_key, sect in section.data|items %}
|
||||
{% if section_key %}
|
||||
<h2 id="{{ parent_key|add:'-' }}{{ section_key }}" class="coredocs-section-title">{{ parent_key|add:' / ' }}{{ section_key }} <a href="#{{ parent_key|add:'-' }}{{ section_key }}"><i class="fa fa-link" aria-hidden="true"></i></a></h2>
|
||||
{% endif %}
|
||||
|
||||
{% with parent_key=parent_key|add:'-'|add:section_key section=sect %}
|
||||
{% include "rest_framework/docs/document-incl.html" %}
|
||||
{% endwith %}
|
||||
{% endfor %}
|
|
@ -14,17 +14,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{% for section_key, section in document.data|items %}
|
||||
{% if section_key %}
|
||||
<h2 id="{{ section_key }}" class="coredocs-section-title">{{ section_key }} <a href="#{{ section_key }}"><i class="fa fa-link" aria-hidden="true"></i>
|
||||
</a></h2>
|
||||
{% endif %}
|
||||
|
||||
{% for link_key, link in section.links|items %}
|
||||
{% include "rest_framework/docs/link.html" %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
|
||||
{% for link_key, link in document.links|items %}
|
||||
{% include "rest_framework/docs/link.html" %}
|
||||
{% endfor %}
|
||||
{% with parent_key=None section=document %}
|
||||
{% include "rest_framework/docs/document-incl.html" %}
|
||||
{% endwith %}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
{% load rest_framework %}
|
||||
|
||||
{% if section.links %}
|
||||
<ul class="sub-menu {% if parent_key %}collapse{% endif %}" id="{{ parent_key }}-dropdown">
|
||||
{% for link_key, link in section.links|items %}
|
||||
<li><a href="#{{ parent_key }}-{{ link_key }}">{{ link.title|default:link_key }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
{% for key, sect in section.data|items %}
|
||||
<li data-toggle="collapse" data-target="#{{ parent_key|add:'-' }}{{ key }}-dropdown" class="collapsed">
|
||||
<a><i class="fa fa-dot-circle-o fa-lg"></i> {{ parent_key|add:' / ' }}{% if key %}{{ key }}{% else %}API Endpoints{% endif %} <span class="arrow"></span></a>
|
||||
</li>
|
||||
{% with section=sect parent_key=parent_key|add:'-'|add:key %}
|
||||
{% include 'rest_framework/docs/sidebar-menu.html' %}
|
||||
{% endwith %}
|
||||
{% endfor %}
|
|
@ -1,20 +1,12 @@
|
|||
{% load rest_framework %}
|
||||
<div class="sidebar">
|
||||
<h3 class="brand"><a href="#">{{ document.title }}</a></h3>
|
||||
|
||||
<i class="fa fa-bars fa-2x toggle-btn" data-toggle="collapse" data-target="#menu-content"></i>
|
||||
<div class="menu-list">
|
||||
<ul id="menu-content" class="menu-content collapse out">
|
||||
{% for section_key, section in document.data|items %}
|
||||
<li data-toggle="collapse" data-target="#{{ section_key }}-dropdown" class="collapsed">
|
||||
<a><i class="fa fa-dot-circle-o fa-lg"></i> {% if section_key %}{{ section_key }}{% else %}API Endpoints{% endif %} <span class="arrow"></span></a>
|
||||
</li>
|
||||
<ul class="sub-menu {% if section_key %}collapse{% endif %}" id="{{ section_key }}-dropdown">
|
||||
{% for link_key, link in section.links|items %}
|
||||
<li><a href="#{{ section_key }}-{{ link_key }}">{{ link.title|default:link_key }}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endfor %}
|
||||
{% with parent_key=None section=document %}
|
||||
{% include 'rest_framework/docs/sidebar-menu.html' %}
|
||||
{% endwith %}
|
||||
</ul>
|
||||
|
||||
<ul class="menu-list menu-list-bottom">
|
||||
|
|
|
@ -55,7 +55,19 @@ class ExampleViewSet(ModelViewSet):
|
|||
"""
|
||||
A description of custom action.
|
||||
"""
|
||||
return super(ExampleSerializer, self).retrieve(self, request)
|
||||
return super(ExampleViewSet, self).retrieve(self, request)
|
||||
|
||||
@detail_route(methods=['get', 'post'], serializer_class=EmptySerializer)
|
||||
def custom_action2(self, request, pk):
|
||||
"""
|
||||
read: A description for getting items.
|
||||
|
||||
create: A description for creating items.
|
||||
"""
|
||||
if request.method == 'GET':
|
||||
return super(ExampleViewSet, self).retrieve(self, request)
|
||||
else:
|
||||
return super(ExampleViewSet, self).create(self, request)
|
||||
|
||||
@list_route()
|
||||
def custom_list_action(self, request):
|
||||
|
@ -105,6 +117,16 @@ class TestRouterGeneratedSchema(TestCase):
|
|||
coreapi.Field('ordering', required=False, location='query', schema=coreschema.String(title='Ordering', description='Which field to use when ordering the results.'))
|
||||
]
|
||||
),
|
||||
'custom_action2': {
|
||||
'read': coreapi.Link(
|
||||
url='/example/{id}/custom_action2/',
|
||||
action='get',
|
||||
description='A description for getting items.',
|
||||
fields=[
|
||||
coreapi.Field('id', required=True, location='path', schema=coreschema.String()),
|
||||
],
|
||||
),
|
||||
},
|
||||
'custom_list_action': coreapi.Link(
|
||||
url='/example/custom_list_action/',
|
||||
action='get'
|
||||
|
@ -173,6 +195,24 @@ class TestRouterGeneratedSchema(TestCase):
|
|||
coreapi.Field('d', required=False, location='form', schema=coreschema.String(title='D')),
|
||||
]
|
||||
),
|
||||
'custom_action2': {
|
||||
'read': coreapi.Link(
|
||||
url='/example/{id}/custom_action2/',
|
||||
action='get',
|
||||
description='A description for getting items.',
|
||||
fields=[
|
||||
coreapi.Field('id', required=True, location='path', schema=coreschema.String()),
|
||||
],
|
||||
),
|
||||
'create': coreapi.Link(
|
||||
url='/example/{id}/custom_action2/',
|
||||
action='post',
|
||||
description='A description for creating items.',
|
||||
fields=[
|
||||
coreapi.Field('id', required=True, location='path', schema=coreschema.String()),
|
||||
],
|
||||
),
|
||||
},
|
||||
'custom_list_action': coreapi.Link(
|
||||
url='/example/custom_list_action/',
|
||||
action='get'
|
||||
|
|
Loading…
Reference in New Issue
Block a user