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:**
|
||||
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
|
||||
----------------|------------
|
||||
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.
|
||||
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.
|
||||
|
||||
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`
|
||||
|
||||
Http Method | Path | Tags
|
||||
-------------------------------------|-------------------|-------------
|
||||
PUT, PATCH, GET(Retrieve), DELETE | /users/{id}/ | [users]
|
||||
POST, GET(List) | /users/ | [users]
|
||||
PUT, PATCH, GET(Retrieve), DELETE | /users/{id}/ | ['users']
|
||||
POST, GET(List) | /users/ | ['users']
|
||||
|
||||
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.
|
||||
|
@ -246,11 +253,21 @@ Tags can be used for logical grouping operations. Each tag name in the list MUST
|
|||
|
||||
Http Method | Path | Tags
|
||||
-------------------------------------|----------------------------------------------------|-------------------
|
||||
PUT, PATCH, GET(Retrieve), DELETE: | /restaurants/{restaurant_id}/branches/{branch_id} | [restaurants]
|
||||
POST, GET(List): | /restaurants/{restaurant_id}/branches/ | [restaurants]
|
||||
PUT, PATCH, GET(Retrieve), DELETE: | /restaurants/{restaurant_id}/branches/{branch_id} | ['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.
|
||||
```python
|
||||
class MyView(APIView):
|
||||
|
|
|
@ -15,6 +15,7 @@ from rest_framework import exceptions, renderers, serializers
|
|||
from rest_framework.compat import uritemplate
|
||||
from rest_framework.fields import _UnvalidatedField, empty
|
||||
|
||||
from ..utils.formatting import camelcase_to_spaces
|
||||
from .generators import BaseSchemaGenerator
|
||||
from .inspectors import ViewInspector
|
||||
from .utils import get_pk_description, is_list_view
|
||||
|
@ -597,7 +598,7 @@ class AutoSchema(ViewInspector):
|
|||
name = name[:-7]
|
||||
elif name.endswith('View'):
|
||||
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.
|
||||
# PUT, PATCH, GET(Retrieve), DELETE: /users/{id}/ tags = [users]
|
||||
|
@ -605,4 +606,4 @@ class AutoSchema(ViewInspector):
|
|||
if path.startswith('/'):
|
||||
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):
|
||||
class ExampleViewSet(views.ExampleTagsViewSet):
|
||||
class ExampleIPViewSet(views.ExampleTagsViewSet):
|
||||
pass
|
||||
|
||||
class ExampleView(views.ExampleTagsViewSet):
|
||||
class ExampleXYZView(views.ExampleTagsViewSet):
|
||||
pass
|
||||
|
||||
class Example(views.ExampleTagsViewSet):
|
||||
pass
|
||||
|
||||
router = routers.SimpleRouter()
|
||||
router.register('test1', ExampleViewSet, basename="test")
|
||||
router.register('test2', ExampleView, basename="test")
|
||||
router.register('test1', ExampleIPViewSet, basename="test")
|
||||
router.register('test2', ExampleXYZView, basename="test")
|
||||
router.register('test3', Example, basename="test")
|
||||
|
||||
generator = SchemaGenerator(patterns=router.urls)
|
||||
schema = generator.get_schema(request=create_request('/'))
|
||||
assert schema['paths']['/test1/{id}/']['get']['tags'] == ['Example']
|
||||
assert schema['paths']['/test2/{id}/']['get']['tags'] == ['Example']
|
||||
assert schema['paths']['/test3/{id}/']['get']['tags'] == ['Example']
|
||||
assert schema['paths']['/test1/{id}/']['get']['tags'] == ['example ip']
|
||||
assert schema['paths']['/test2/{id}/']['get']['tags'] == ['example xyz']
|
||||
assert schema['paths']['/test3/{id}/']['get']['tags'] == ['example']
|
||||
assert schema['tags'] == []
|
||||
|
||||
def test_auto_generated_apiview_tags(self):
|
||||
|
@ -805,12 +805,12 @@ class TestOperationIntrospection(TestCase):
|
|||
pass
|
||||
|
||||
url_patterns = [
|
||||
url(r'^restaurants/?$', RestaurantAPIView.as_view()),
|
||||
url(r'^any-dash_underscore/?$', RestaurantAPIView.as_view()),
|
||||
url(r'^restaurants/branches/?$', BranchAPIView.as_view())
|
||||
]
|
||||
generator = SchemaGenerator(patterns=url_patterns)
|
||||
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['tags'] == []
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user