mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-28 00:49:49 +03:00
remove tag generation from viewset
This commit is contained in:
parent
48c02dd53a
commit
64a4828a06
|
@ -223,46 +223,32 @@ Tags can be used to group logical operations. Each tag name in the list MUST be
|
||||||
---
|
---
|
||||||
#### Django REST Framework generates tags automatically with the following logic:
|
#### Django REST Framework generates tags automatically with the following logic:
|
||||||
|
|
||||||
1. Extract tag from `ViewSet`.
|
Tag name will be first element from the path. Also, any `_` in path name will be replaced by a `-`.
|
||||||
1. If `ViewSet` name ends with `ViewSet`, or `View`; remove it.
|
|
||||||
2. Convert class name into lowercase words & join each word using a `-`(dash).
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
|
|
||||||
ViewSet Class | Tags
|
|
||||||
----------------|------------
|
|
||||||
User | ['user']
|
|
||||||
UserView | ['user']
|
|
||||||
UserViewSet | ['user']
|
|
||||||
PascalCaseXYZ | ['pascal-case-xyz']
|
|
||||||
IPAddressView | ['ip-address']
|
|
||||||
|
|
||||||
2. If View is not an instance of ViewSet, tag name will be first element from the path. Also, any `_` in path name will be replaced by a `-`.
|
|
||||||
Consider below examples.
|
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.
|
||||||
Here first element from the paths is: `restaurants`. Hence tag wil be `restaurants`.
|
Here first element from the paths is: `restaurants`. Hence tag wil be `restaurants`.
|
||||||
|
|
||||||
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.
|
Example 3: Consider Order items for an e commerce company.
|
||||||
|
|
||||||
Http Method | Path | Tags
|
Http Method | Path | Tags
|
||||||
-------------------------------------|-------------------------|-------------
|
-------------------------------------|-------------------------|-------------
|
||||||
PUT, PATCH, GET(Retrieve), DELETE | /order_items/{id}/ | ['order-items']
|
PUT, PATCH, GET(Retrieve), DELETE | /order_items/{id}/ | ['order-items']
|
||||||
POST, GET(List) | /order_items/ | ['order-items']
|
POST, GET(List) | /order_items/ | ['order-items']
|
||||||
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
@ -15,7 +15,6 @@ 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
|
||||||
|
@ -578,18 +577,6 @@ class AutoSchema(ViewInspector):
|
||||||
if self._tags:
|
if self._tags:
|
||||||
return self._tags
|
return self._tags
|
||||||
|
|
||||||
# Extract tag from viewset name
|
|
||||||
# UserProfileViewSet tags = [user-profile]
|
|
||||||
# UserProfileView tags = [user-profile]
|
|
||||||
# UserProfile tags = [user-profile]
|
|
||||||
if hasattr(self.view, 'action'):
|
|
||||||
name = self.view.__class__.__name__
|
|
||||||
if name.endswith('ViewSet'):
|
|
||||||
name = name[:-7]
|
|
||||||
elif name.endswith('View'):
|
|
||||||
name = name[:-4]
|
|
||||||
return [camelcase_to_spaces(name).lower().replace(' ', '-')]
|
|
||||||
|
|
||||||
# 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: /user_profile/{id}/ tags = [user-profile]
|
# PUT, PATCH, GET(Retrieve), DELETE: /user_profile/{id}/ tags = [user-profile]
|
||||||
# POST, GET(List): /user_profile/ tags = [user-profile]
|
# POST, GET(List): /user_profile/ tags = [user-profile]
|
||||||
|
|
|
@ -699,14 +699,15 @@ class TestOperationIntrospection(TestCase):
|
||||||
assert 'format' not in properties['ip']
|
assert 'format' not in properties['ip']
|
||||||
|
|
||||||
def test_overridden_tags(self):
|
def test_overridden_tags(self):
|
||||||
class ExampleStringTagsViewSet(views.ExampleTagsViewSet):
|
class ExampleStringTagsViewSet(views.ExampleGenericAPIView):
|
||||||
schema = AutoSchema(tags=['example1', 'example2'])
|
schema = AutoSchema(tags=['example1', 'example2'])
|
||||||
|
|
||||||
router = routers.SimpleRouter()
|
url_patterns = [
|
||||||
router.register('test', ExampleStringTagsViewSet, basename="test")
|
url(r'^test/?$', ExampleStringTagsViewSet.as_view()),
|
||||||
generator = SchemaGenerator(patterns=router.urls)
|
]
|
||||||
|
generator = SchemaGenerator(patterns=url_patterns)
|
||||||
schema = generator.get_schema(request=create_request('/'))
|
schema = generator.get_schema(request=create_request('/'))
|
||||||
assert schema['paths']['/test/{id}/']['get']['tags'] == ['example1', 'example2']
|
assert schema['paths']['/test/']['get']['tags'] == ['example1', 'example2']
|
||||||
|
|
||||||
def test_overridden_get_tags_method(self):
|
def test_overridden_get_tags_method(self):
|
||||||
class MySchema(AutoSchema):
|
class MySchema(AutoSchema):
|
||||||
|
@ -730,32 +731,6 @@ class TestOperationIntrospection(TestCase):
|
||||||
assert schema['paths']['/example/new/']['get']['tags'] == ['tag1', 'tag2']
|
assert schema['paths']['/example/new/']['get']['tags'] == ['tag1', 'tag2']
|
||||||
assert schema['paths']['/example/old/']['get']['tags'] == ['tag2', 'tag3']
|
assert schema['paths']['/example/old/']['get']['tags'] == ['tag2', 'tag3']
|
||||||
|
|
||||||
def test_auto_generated_viewset_tags(self):
|
|
||||||
class ExampleIPViewSet(views.ExampleTagsViewSet):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class ExampleXYZView(views.ExampleTagsViewSet):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class Example(views.ExampleTagsViewSet):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class PascalCaseXYZTestIp(views.ExampleTagsViewSet):
|
|
||||||
pass
|
|
||||||
|
|
||||||
router = routers.SimpleRouter()
|
|
||||||
router.register('test1', ExampleIPViewSet, basename="test1")
|
|
||||||
router.register('test2', ExampleXYZView, basename="test2")
|
|
||||||
router.register('test3', Example, basename="test3")
|
|
||||||
router.register('test4', PascalCaseXYZTestIp, basename="test4")
|
|
||||||
|
|
||||||
generator = SchemaGenerator(patterns=router.urls)
|
|
||||||
schema = generator.get_schema(request=create_request('/'))
|
|
||||||
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['paths']['/test4/{id}/']['get']['tags'] == ['pascal-case-xyz-test-ip']
|
|
||||||
|
|
||||||
def test_auto_generated_apiview_tags(self):
|
def test_auto_generated_apiview_tags(self):
|
||||||
class RestaurantAPIView(views.ExampleGenericAPIView):
|
class RestaurantAPIView(views.ExampleGenericAPIView):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -137,14 +137,3 @@ class ExampleValidatedAPIView(generics.GenericAPIView):
|
||||||
url='http://localhost', uuid=uuid.uuid4(), ip4='127.0.0.1', ip6='::1',
|
url='http://localhost', uuid=uuid.uuid4(), ip4='127.0.0.1', ip6='::1',
|
||||||
ip='192.168.1.1')
|
ip='192.168.1.1')
|
||||||
return Response(serializer.data)
|
return Response(serializer.data)
|
||||||
|
|
||||||
|
|
||||||
class ExampleTagsViewSet(GenericViewSet):
|
|
||||||
serializer_class = ExampleSerializer
|
|
||||||
|
|
||||||
def retrieve(self, request, *args, **kwargs):
|
|
||||||
serializer = self.get_serializer(integer=33, string='hello', regex='foo', decimal1=3.55,
|
|
||||||
decimal2=5.33, email='a@b.co',
|
|
||||||
url='http://localhost', uuid=uuid.uuid4(), ip4='127.0.0.1', ip6='::1',
|
|
||||||
ip='192.168.1.1')
|
|
||||||
return Response(serializer.data)
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user