mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-25 02:53:58 +03:00
blacken-docs (#8906)
* blacken-docs: Manual fixes for command to pass without errors * blacken-docs: Adds blacken-docs step to precommit hook. * blacken-docs: Adds changes made by command itself. * blacken-docs: Modifies blacken-docs step to only process files under "docs" directory * blacken-docs: Updates pre-commit config file to exclude all directories other than "docs" to be compatible with "--all-files" flag. * blacken-docs: Adds commas at the end to make it look identical to pre-black version
This commit is contained in:
parent
18b02ce00e
commit
e794e5e5e4
|
@ -18,3 +18,10 @@ repos:
|
||||||
- id: flake8
|
- id: flake8
|
||||||
additional_dependencies:
|
additional_dependencies:
|
||||||
- flake8-tidy-imports
|
- flake8-tidy-imports
|
||||||
|
- repo: https://github.com/adamchainz/blacken-docs
|
||||||
|
rev: 1.13.0
|
||||||
|
hooks:
|
||||||
|
- id: blacken-docs
|
||||||
|
exclude: ^(?!docs).*$
|
||||||
|
additional_dependencies:
|
||||||
|
- black==23.1.0
|
||||||
|
|
|
@ -28,33 +28,33 @@ from rest_framework import viewsets
|
||||||
|
|
||||||
class UserViewSet(viewsets.ViewSet):
|
class UserViewSet(viewsets.ViewSet):
|
||||||
# With cookie: cache requested url for each user for 2 hours
|
# With cookie: cache requested url for each user for 2 hours
|
||||||
@method_decorator(cache_page(60*60*2))
|
@method_decorator(cache_page(60 * 60 * 2))
|
||||||
@method_decorator(vary_on_cookie)
|
@method_decorator(vary_on_cookie)
|
||||||
def list(self, request, format=None):
|
def list(self, request, format=None):
|
||||||
content = {
|
content = {
|
||||||
'user_feed': request.user.get_user_feed()
|
"user_feed": request.user.get_user_feed(),
|
||||||
}
|
}
|
||||||
return Response(content)
|
return Response(content)
|
||||||
|
|
||||||
|
|
||||||
class ProfileView(APIView):
|
class ProfileView(APIView):
|
||||||
# With auth: cache requested url for each user for 2 hours
|
# With auth: cache requested url for each user for 2 hours
|
||||||
@method_decorator(cache_page(60*60*2))
|
@method_decorator(cache_page(60 * 60 * 2))
|
||||||
@method_decorator(vary_on_headers("Authorization",))
|
@method_decorator(vary_on_headers("Authorization"))
|
||||||
def get(self, request, format=None):
|
def get(self, request, format=None):
|
||||||
content = {
|
content = {
|
||||||
'user_feed': request.user.get_user_feed()
|
"user_feed": request.user.get_user_feed(),
|
||||||
}
|
}
|
||||||
return Response(content)
|
return Response(content)
|
||||||
|
|
||||||
|
|
||||||
class PostView(APIView):
|
class PostView(APIView):
|
||||||
# Cache page for the requested url
|
# Cache page for the requested url
|
||||||
@method_decorator(cache_page(60*60*2))
|
@method_decorator(cache_page(60 * 60 * 2))
|
||||||
def get(self, request, format=None):
|
def get(self, request, format=None):
|
||||||
content = {
|
content = {
|
||||||
'title': 'Post title',
|
"title": "Post title",
|
||||||
'body': 'Post content'
|
"body": "Post content",
|
||||||
}
|
}
|
||||||
return Response(content)
|
return Response(content)
|
||||||
```
|
```
|
||||||
|
|
|
@ -94,11 +94,13 @@ urlpatterns = [
|
||||||
# Use the `get_schema_view()` helper to add a `SchemaView` to project URLs.
|
# Use the `get_schema_view()` helper to add a `SchemaView` to project URLs.
|
||||||
# * `title` and `description` parameters are passed to `SchemaGenerator`.
|
# * `title` and `description` parameters are passed to `SchemaGenerator`.
|
||||||
# * Provide view name for use with `reverse()`.
|
# * Provide view name for use with `reverse()`.
|
||||||
path('openapi', get_schema_view(
|
path(
|
||||||
title="Your Project",
|
"openapi",
|
||||||
description="API for all things …",
|
get_schema_view(
|
||||||
version="1.0.0"
|
title="Your Project", description="API for all things …", version="1.0.0"
|
||||||
), name='openapi-schema'),
|
),
|
||||||
|
name="openapi-schema",
|
||||||
|
),
|
||||||
# ...
|
# ...
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
@ -259,11 +261,13 @@ class CustomSchema(AutoSchema):
|
||||||
"""
|
"""
|
||||||
AutoSchema subclass using schema_extra_info on the view.
|
AutoSchema subclass using schema_extra_info on the view.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
class CustomView(APIView):
|
class CustomView(APIView):
|
||||||
schema = CustomSchema()
|
schema = CustomSchema()
|
||||||
schema_extra_info = ... some extra info ...
|
schema_extra_info = ... # some extra info
|
||||||
```
|
```
|
||||||
|
|
||||||
Here, the `AutoSchema` subclass goes looking for `schema_extra_info` on the
|
Here, the `AutoSchema` subclass goes looking for `schema_extra_info` on the
|
||||||
|
@ -278,10 +282,13 @@ class BaseSchema(AutoSchema):
|
||||||
"""
|
"""
|
||||||
AutoSchema subclass that knows how to use extra_info.
|
AutoSchema subclass that knows how to use extra_info.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
class CustomSchema(BaseSchema):
|
class CustomSchema(BaseSchema):
|
||||||
extra_info = ... some extra info ...
|
extra_info = ... # some extra info
|
||||||
|
|
||||||
|
|
||||||
class CustomView(APIView):
|
class CustomView(APIView):
|
||||||
schema = CustomSchema()
|
schema = CustomSchema()
|
||||||
|
@ -302,10 +309,9 @@ class CustomSchema(BaseSchema):
|
||||||
self.extra_info = kwargs.pop("extra_info")
|
self.extra_info = kwargs.pop("extra_info")
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
|
|
||||||
|
|
||||||
class CustomView(APIView):
|
class CustomView(APIView):
|
||||||
schema = CustomSchema(
|
schema = CustomSchema(extra_info=...) # some extra info
|
||||||
extra_info=... some extra info ...
|
|
||||||
)
|
|
||||||
```
|
```
|
||||||
|
|
||||||
This saves you having to create a custom subclass per-view for a commonly used option.
|
This saves you having to create a custom subclass per-view for a commonly used option.
|
||||||
|
|
|
@ -201,15 +201,16 @@ To view all extra actions, call the `.get_extra_actions()` method.
|
||||||
Extra actions can map additional HTTP methods to separate `ViewSet` methods. For example, the above password set/unset methods could be consolidated into a single route. Note that additional mappings do not accept arguments.
|
Extra actions can map additional HTTP methods to separate `ViewSet` methods. For example, the above password set/unset methods could be consolidated into a single route. Note that additional mappings do not accept arguments.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
@action(detail=True, methods=['put'], name='Change Password')
|
@action(detail=True, methods=["put"], name="Change Password")
|
||||||
def password(self, request, pk=None):
|
def password(self, request, pk=None):
|
||||||
"""Update the user's password."""
|
"""Update the user's password."""
|
||||||
...
|
...
|
||||||
|
|
||||||
@password.mapping.delete
|
|
||||||
def delete_password(self, request, pk=None):
|
@password.mapping.delete
|
||||||
"""Delete the user's password."""
|
def delete_password(self, request, pk=None):
|
||||||
...
|
"""Delete the user's password."""
|
||||||
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
## Reversing action URLs
|
## Reversing action URLs
|
||||||
|
@ -220,14 +221,14 @@ Note that the `basename` is provided by the router during `ViewSet` registration
|
||||||
|
|
||||||
Using the example from the previous section:
|
Using the example from the previous section:
|
||||||
|
|
||||||
```python
|
```pycon
|
||||||
>>> view.reverse_action('set-password', args=['1'])
|
>>> view.reverse_action("set-password", args=["1"])
|
||||||
'http://localhost:8000/api/users/1/set_password'
|
'http://localhost:8000/api/users/1/set_password'
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively, you can use the `url_name` attribute set by the `@action` decorator.
|
Alternatively, you can use the `url_name` attribute set by the `@action` decorator.
|
||||||
|
|
||||||
```python
|
```pycon
|
||||||
>>> view.reverse_action(view.set_password.url_name, args=['1'])
|
>>> view.reverse_action(view.set_password.url_name, args=['1'])
|
||||||
'http://localhost:8000/api/users/1/set_password'
|
'http://localhost:8000/api/users/1/set_password'
|
||||||
```
|
```
|
||||||
|
|
|
@ -41,8 +41,8 @@ update your REST framework settings to include `DEFAULT_SCHEMA_CLASS` explicitly
|
||||||
|
|
||||||
```python
|
```python
|
||||||
REST_FRAMEWORK = {
|
REST_FRAMEWORK = {
|
||||||
...
|
...: ...,
|
||||||
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema'
|
"DEFAULT_SCHEMA_CLASS": "rest_framework.schemas.coreapi.AutoSchema",
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -74,10 +74,11 @@ urlpatterns = [
|
||||||
# Use the `get_schema_view()` helper to add a `SchemaView` to project URLs.
|
# Use the `get_schema_view()` helper to add a `SchemaView` to project URLs.
|
||||||
# * `title` and `description` parameters are passed to `SchemaGenerator`.
|
# * `title` and `description` parameters are passed to `SchemaGenerator`.
|
||||||
# * Provide view name for use with `reverse()`.
|
# * Provide view name for use with `reverse()`.
|
||||||
path('openapi', get_schema_view(
|
path(
|
||||||
title="Your Project",
|
"openapi",
|
||||||
description="API for all things …"
|
get_schema_view(title="Your Project", description="API for all things …"),
|
||||||
), name='openapi-schema'),
|
name="openapi-schema",
|
||||||
|
),
|
||||||
# ...
|
# ...
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
|
@ -43,10 +43,11 @@ be extracted from the class docstring:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
class DocStringExampleListView(APIView):
|
class DocStringExampleListView(APIView):
|
||||||
"""
|
"""
|
||||||
get: A description of my GET operation.
|
get: A description of my GET operation.
|
||||||
post: A description of my POST operation.
|
post: A description of my POST operation.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
|
permission_classes = [permissions.IsAuthenticatedOrReadOnly]
|
||||||
|
|
||||||
def get(self, request, *args, **kwargs):
|
def get(self, request, *args, **kwargs):
|
||||||
|
|
|
@ -41,7 +41,7 @@ The tags used for a particular view may also be overridden...
|
||||||
|
|
||||||
```python
|
```python
|
||||||
class MyOrders(APIView):
|
class MyOrders(APIView):
|
||||||
schema = AutoSchema(tags=['users', 'orders'])
|
schema = AutoSchema(tags=["users", "orders"])
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ may be overridden if needed](https://www.django-rest-framework.org/api-guide/sch
|
||||||
|
|
||||||
```python
|
```python
|
||||||
class MyOrders(APIView):
|
class MyOrders(APIView):
|
||||||
schema = AutoSchema(component_name="OrderDetails")
|
schema = AutoSchema(component_name="OrderDetails")
|
||||||
```
|
```
|
||||||
|
|
||||||
## More Public API
|
## More Public API
|
||||||
|
@ -118,10 +118,11 @@ class SitesSearchView(generics.ListAPIView):
|
||||||
by a search against the site name or location. (Location searches are
|
by a search against the site name or location. (Location searches are
|
||||||
matched against the region and country names.)
|
matched against the region and country names.)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
queryset = Sites.objects.all()
|
queryset = Sites.objects.all()
|
||||||
serializer_class = SitesSerializer
|
serializer_class = SitesSerializer
|
||||||
filter_backends = [filters.SearchFilter]
|
filter_backends = [filters.SearchFilter]
|
||||||
search_fields = ['site_name', 'location__region', 'location__country']
|
search_fields = ["site_name", "location__region", "location__country"]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Searches against annotate fields
|
### Searches against annotate fields
|
||||||
|
@ -135,10 +136,11 @@ class PublisherSearchView(generics.ListAPIView):
|
||||||
Search for publishers, optionally filtering the search against the average
|
Search for publishers, optionally filtering the search against the average
|
||||||
rating of all their books.
|
rating of all their books.
|
||||||
"""
|
"""
|
||||||
queryset = Publisher.objects.annotate(avg_rating=Avg('book__rating'))
|
|
||||||
|
queryset = Publisher.objects.annotate(avg_rating=Avg("book__rating"))
|
||||||
serializer_class = PublisherSerializer
|
serializer_class = PublisherSerializer
|
||||||
filter_backends = [filters.SearchFilter]
|
filter_backends = [filters.SearchFilter]
|
||||||
search_fields = ['avg_rating']
|
search_fields = ["avg_rating"]
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
@ -65,15 +65,12 @@ from rest_framework.renderers import JSONOpenAPIRenderer
|
||||||
from django.urls import path
|
from django.urls import path
|
||||||
|
|
||||||
schema_view = get_schema_view(
|
schema_view = get_schema_view(
|
||||||
title='Server Monitoring API',
|
title="Server Monitoring API",
|
||||||
url='https://www.example.org/api/',
|
url="https://www.example.org/api/",
|
||||||
renderer_classes=[JSONOpenAPIRenderer]
|
renderer_classes=[JSONOpenAPIRenderer],
|
||||||
)
|
)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [path("schema.json", schema_view), ...]
|
||||||
path('schema.json', schema_view),
|
|
||||||
...
|
|
||||||
]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
And here's how you can use the `generateschema` management command:
|
And here's how you can use the `generateschema` management command:
|
||||||
|
|
|
@ -306,7 +306,11 @@ Be sure to upgrade to Python 3 before upgrading to Django REST Framework 3.10.
|
||||||
class NullableCharField(serializers.CharField):
|
class NullableCharField(serializers.CharField):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.validators = [v for v in self.validators if not isinstance(v, ProhibitNullCharactersValidator)]
|
self.validators = [
|
||||||
|
v
|
||||||
|
for v in self.validators
|
||||||
|
if not isinstance(v, ProhibitNullCharactersValidator)
|
||||||
|
]
|
||||||
```
|
```
|
||||||
* Add `OpenAPIRenderer` and `generate_schema` management command. [#6229][gh6229]
|
* Add `OpenAPIRenderer` and `generate_schema` management command. [#6229][gh6229]
|
||||||
* Add OpenAPIRenderer by default, and add schema docs. [#6233][gh6233]
|
* Add OpenAPIRenderer by default, and add schema docs. [#6233][gh6233]
|
||||||
|
|
|
@ -96,10 +96,14 @@ urlpatterns = [
|
||||||
# ...
|
# ...
|
||||||
# Route TemplateView to serve Swagger UI template.
|
# Route TemplateView to serve Swagger UI template.
|
||||||
# * Provide `extra_context` with view name of `SchemaView`.
|
# * Provide `extra_context` with view name of `SchemaView`.
|
||||||
path('swagger-ui/', TemplateView.as_view(
|
path(
|
||||||
template_name='swagger-ui.html',
|
"swagger-ui/",
|
||||||
extra_context={'schema_url':'openapi-schema'}
|
TemplateView.as_view(
|
||||||
), name='swagger-ui'),
|
template_name="swagger-ui.html",
|
||||||
|
extra_context={"schema_url": "openapi-schema"},
|
||||||
|
),
|
||||||
|
name="swagger-ui",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -145,10 +149,13 @@ urlpatterns = [
|
||||||
# ...
|
# ...
|
||||||
# Route TemplateView to serve the ReDoc template.
|
# Route TemplateView to serve the ReDoc template.
|
||||||
# * Provide `extra_context` with view name of `SchemaView`.
|
# * Provide `extra_context` with view name of `SchemaView`.
|
||||||
path('redoc/', TemplateView.as_view(
|
path(
|
||||||
template_name='redoc.html',
|
"redoc/",
|
||||||
extra_context={'schema_url':'openapi-schema'}
|
TemplateView.as_view(
|
||||||
), name='redoc'),
|
template_name="redoc.html", extra_context={"schema_url": "openapi-schema"}
|
||||||
|
),
|
||||||
|
name="redoc",
|
||||||
|
),
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user