mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-28 00:49:49 +03:00
fix changes given by kevin-brown
This commit is contained in:
parent
9c3a632e29
commit
b0f11cdd29
|
@ -222,23 +222,30 @@ Tags can be used for logical grouping operations. Each tag name in the list MUST
|
||||||
|
|
||||||
---
|
---
|
||||||
**Django REST Framework generates tags automatically with following logic:**
|
**Django REST Framework generates tags automatically with following logic:**
|
||||||
1. Extract tag name from `ViewSet`. If `ViewSet` name ends with `ViewSet`, or `View`, it will be truncated from tag name.
|
1. Extract tag from `ViewSet`.
|
||||||
|
1. If `ViewSet` name ends with `ViewSet`, or `View`, remove them.
|
||||||
|
2. Convert class name into words & join each word with a space.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
ViewSet Class | Tags
|
||||||
|
----------------|------------
|
||||||
|
User | ['user']
|
||||||
|
UserView | ['user']
|
||||||
|
UserViewSet | ['user']
|
||||||
|
PascalCaseXYZ | ['pascal case xyz']
|
||||||
|
IPAddressView | ['ip address']
|
||||||
|
|
||||||
ViewSet Class | Tags
|
2. If View is not an instance of ViewSet, tag name will be first element from the path. Also, any `-` or `_` in path name will be converted as a space.
|
||||||
----------------|------------
|
Consider below examples.
|
||||||
User | User
|
|
||||||
UserView | User
|
|
||||||
UserViewSet | user
|
|
||||||
|
|
||||||
2. If View is not an instance of ViewSet, tag name will be first element from the path. Consider below examples.
|
|
||||||
|
|
||||||
Example 1: Consider a user management system. The following table will illustrate the tag generation logic.
|
Example 1: Consider a user management system. The following table will illustrate the tag generation logic.
|
||||||
Here first element from the paths is: `users`. Hence tag wil be `users`
|
Here first element from the paths is: `users`. Hence tag wil be `users`
|
||||||
|
|
||||||
Http Method | Path | Tags
|
Http Method | Path | Tags
|
||||||
-------------------------------------|-------------------|-------------
|
-------------------------------------|-------------------|-------------
|
||||||
PUT, PATCH, GET(Retrieve), DELETE | /users/{id}/ | [users]
|
PUT, PATCH, GET(Retrieve), DELETE | /users/{id}/ | ['users']
|
||||||
POST, GET(List) | /users/ | [users]
|
POST, GET(List) | /users/ | ['users']
|
||||||
|
|
||||||
Example 2: Consider a restaurant management system. The System has restaurants. Each restaurant has branches.
|
Example 2: Consider a restaurant management system. The System has restaurants. Each restaurant has branches.
|
||||||
Consider REST APIs to deal with a branch of a particular restaurant.
|
Consider REST APIs to deal with a branch of a particular restaurant.
|
||||||
|
@ -246,11 +253,21 @@ Tags can be used for logical grouping operations. Each tag name in the list MUST
|
||||||
|
|
||||||
Http Method | Path | Tags
|
Http Method | Path | Tags
|
||||||
-------------------------------------|----------------------------------------------------|-------------------
|
-------------------------------------|----------------------------------------------------|-------------------
|
||||||
PUT, PATCH, GET(Retrieve), DELETE: | /restaurants/{restaurant_id}/branches/{branch_id} | [restaurants]
|
PUT, PATCH, GET(Retrieve), DELETE: | /restaurants/{restaurant_id}/branches/{branch_id} | ['restaurants']
|
||||||
POST, GET(List): | /restaurants/{restaurant_id}/branches/ | [restaurants]
|
POST, GET(List): | /restaurants/{restaurant_id}/branches/ | ['restaurants']
|
||||||
|
|
||||||
|
Example 3: Consider Order items for an e commerce company.
|
||||||
|
|
||||||
|
Http Method | Path | Tags
|
||||||
|
-------------------------------------|-------------------------|-------------
|
||||||
|
PUT, PATCH, GET(Retrieve), DELETE | /order-items/{id}/ | ['order items']
|
||||||
|
POST, GET(List) | /order-items/ | ['order items']
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
**You can override auto-generated tags by passing a list of tags to each `View` by passing `tags` as an argument to the constructor of `AutoSchema`. `tags` argument can be:**
|
**You can override auto-generated tags by passing `tags` argument to the constructor of `AutoSchema`.**
|
||||||
|
|
||||||
|
**`tags` argument can be a**
|
||||||
1. list of string.
|
1. list of string.
|
||||||
```python
|
```python
|
||||||
class MyView(APIView):
|
class MyView(APIView):
|
||||||
|
|
|
@ -15,6 +15,7 @@ from rest_framework import exceptions, renderers, serializers
|
||||||
from rest_framework.compat import uritemplate
|
from rest_framework.compat import uritemplate
|
||||||
from rest_framework.fields import _UnvalidatedField, empty
|
from rest_framework.fields import _UnvalidatedField, empty
|
||||||
|
|
||||||
|
from ..utils.formatting import camelcase_to_spaces
|
||||||
from .generators import BaseSchemaGenerator
|
from .generators import BaseSchemaGenerator
|
||||||
from .inspectors import ViewInspector
|
from .inspectors import ViewInspector
|
||||||
from .utils import get_pk_description, is_list_view
|
from .utils import get_pk_description, is_list_view
|
||||||
|
@ -597,7 +598,7 @@ class AutoSchema(ViewInspector):
|
||||||
name = name[:-7]
|
name = name[:-7]
|
||||||
elif name.endswith('View'):
|
elif name.endswith('View'):
|
||||||
name = name[:-4]
|
name = name[:-4]
|
||||||
return [name]
|
return [camelcase_to_spaces(name).lower()]
|
||||||
|
|
||||||
# First element of a specific path could be valid tag. This is a fallback solution.
|
# First element of a specific path could be valid tag. This is a fallback solution.
|
||||||
# PUT, PATCH, GET(Retrieve), DELETE: /users/{id}/ tags = [users]
|
# PUT, PATCH, GET(Retrieve), DELETE: /users/{id}/ tags = [users]
|
||||||
|
@ -605,4 +606,4 @@ class AutoSchema(ViewInspector):
|
||||||
if path.startswith('/'):
|
if path.startswith('/'):
|
||||||
path = path[1:]
|
path = path[1:]
|
||||||
|
|
||||||
return [path.split('/')[0]]
|
return [path.split('/')[0].translate(str.maketrans({'-': ' ', '_': ' '}))]
|
||||||
|
|
|
@ -776,25 +776,25 @@ class TestOperationIntrospection(TestCase):
|
||||||
]
|
]
|
||||||
|
|
||||||
def test_auto_generated_viewset_tags(self):
|
def test_auto_generated_viewset_tags(self):
|
||||||
class ExampleViewSet(views.ExampleTagsViewSet):
|
class ExampleIPViewSet(views.ExampleTagsViewSet):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class ExampleView(views.ExampleTagsViewSet):
|
class ExampleXYZView(views.ExampleTagsViewSet):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Example(views.ExampleTagsViewSet):
|
class Example(views.ExampleTagsViewSet):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
router = routers.SimpleRouter()
|
router = routers.SimpleRouter()
|
||||||
router.register('test1', ExampleViewSet, basename="test")
|
router.register('test1', ExampleIPViewSet, basename="test")
|
||||||
router.register('test2', ExampleView, basename="test")
|
router.register('test2', ExampleXYZView, basename="test")
|
||||||
router.register('test3', Example, basename="test")
|
router.register('test3', Example, basename="test")
|
||||||
|
|
||||||
generator = SchemaGenerator(patterns=router.urls)
|
generator = SchemaGenerator(patterns=router.urls)
|
||||||
schema = generator.get_schema(request=create_request('/'))
|
schema = generator.get_schema(request=create_request('/'))
|
||||||
assert schema['paths']['/test1/{id}/']['get']['tags'] == ['Example']
|
assert schema['paths']['/test1/{id}/']['get']['tags'] == ['example ip']
|
||||||
assert schema['paths']['/test2/{id}/']['get']['tags'] == ['Example']
|
assert schema['paths']['/test2/{id}/']['get']['tags'] == ['example xyz']
|
||||||
assert schema['paths']['/test3/{id}/']['get']['tags'] == ['Example']
|
assert schema['paths']['/test3/{id}/']['get']['tags'] == ['example']
|
||||||
assert schema['tags'] == []
|
assert schema['tags'] == []
|
||||||
|
|
||||||
def test_auto_generated_apiview_tags(self):
|
def test_auto_generated_apiview_tags(self):
|
||||||
|
@ -805,12 +805,12 @@ class TestOperationIntrospection(TestCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
url_patterns = [
|
url_patterns = [
|
||||||
url(r'^restaurants/?$', RestaurantAPIView.as_view()),
|
url(r'^any-dash_underscore/?$', RestaurantAPIView.as_view()),
|
||||||
url(r'^restaurants/branches/?$', BranchAPIView.as_view())
|
url(r'^restaurants/branches/?$', BranchAPIView.as_view())
|
||||||
]
|
]
|
||||||
generator = SchemaGenerator(patterns=url_patterns)
|
generator = SchemaGenerator(patterns=url_patterns)
|
||||||
schema = generator.get_schema(request=create_request('/'))
|
schema = generator.get_schema(request=create_request('/'))
|
||||||
assert schema['paths']['/restaurants/']['get']['tags'] == ['restaurants']
|
assert schema['paths']['/any-dash_underscore/']['get']['tags'] == ['any dash underscore']
|
||||||
assert schema['paths']['/restaurants/branches/']['get']['tags'] == ['restaurants']
|
assert schema['paths']['/restaurants/branches/']['get']['tags'] == ['restaurants']
|
||||||
assert schema['tags'] == []
|
assert schema['tags'] == []
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user