diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 83fe0b714b..64ec37770f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,3 +18,10 @@ repos: - id: flake8 additional_dependencies: - 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 diff --git a/docs/api-guide/caching.md b/docs/api-guide/caching.md index ab4f82cd2f..503acb09e6 100644 --- a/docs/api-guide/caching.md +++ b/docs/api-guide/caching.md @@ -28,33 +28,33 @@ from rest_framework import viewsets class UserViewSet(viewsets.ViewSet): # 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) def list(self, request, format=None): content = { - 'user_feed': request.user.get_user_feed() + "user_feed": request.user.get_user_feed(), } return Response(content) class ProfileView(APIView): # With auth: cache requested url for each user for 2 hours - @method_decorator(cache_page(60*60*2)) - @method_decorator(vary_on_headers("Authorization",)) + @method_decorator(cache_page(60 * 60 * 2)) + @method_decorator(vary_on_headers("Authorization")) def get(self, request, format=None): content = { - 'user_feed': request.user.get_user_feed() + "user_feed": request.user.get_user_feed(), } return Response(content) class PostView(APIView): # 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): content = { - 'title': 'Post title', - 'body': 'Post content' + "title": "Post title", + "body": "Post content", } return Response(content) ``` diff --git a/docs/api-guide/schemas.md b/docs/api-guide/schemas.md index 3f0b155306..7af98dbf5e 100644 --- a/docs/api-guide/schemas.md +++ b/docs/api-guide/schemas.md @@ -94,11 +94,13 @@ urlpatterns = [ # Use the `get_schema_view()` helper to add a `SchemaView` to project URLs. # * `title` and `description` parameters are passed to `SchemaGenerator`. # * Provide view name for use with `reverse()`. - path('openapi', get_schema_view( - title="Your Project", - description="API for all things …", - version="1.0.0" - ), name='openapi-schema'), + path( + "openapi", + get_schema_view( + title="Your Project", description="API for all things …", version="1.0.0" + ), + name="openapi-schema", + ), # ... ] ``` @@ -259,11 +261,13 @@ class CustomSchema(AutoSchema): """ AutoSchema subclass using schema_extra_info on the view. """ + ... + class CustomView(APIView): 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 @@ -278,10 +282,13 @@ class BaseSchema(AutoSchema): """ AutoSchema subclass that knows how to use extra_info. """ + ... + class CustomSchema(BaseSchema): - extra_info = ... some extra info ... + extra_info = ... # some extra info + class CustomView(APIView): schema = CustomSchema() @@ -302,10 +309,9 @@ class CustomSchema(BaseSchema): self.extra_info = kwargs.pop("extra_info") super().__init__(**kwargs) + class CustomView(APIView): - schema = CustomSchema( - extra_info=... some extra info ... - ) + schema = CustomSchema(extra_info=...) # some extra info ``` This saves you having to create a custom subclass per-view for a commonly used option. diff --git a/docs/api-guide/viewsets.md b/docs/api-guide/viewsets.md index 5d5491a83f..a20381e94b 100644 --- a/docs/api-guide/viewsets.md +++ b/docs/api-guide/viewsets.md @@ -194,15 +194,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. ```python - @action(detail=True, methods=['put'], name='Change Password') - def password(self, request, pk=None): - """Update the user's password.""" - ... - - @password.mapping.delete - def delete_password(self, request, pk=None): - """Delete the user's password.""" - ... +@action(detail=True, methods=["put"], name="Change Password") +def password(self, request, pk=None): + """Update the user's password.""" + ... + + +@password.mapping.delete +def delete_password(self, request, pk=None): + """Delete the user's password.""" + ... ``` ## Reversing action URLs @@ -213,14 +214,14 @@ Note that the `basename` is provided by the router during `ViewSet` registration Using the example from the previous section: -```python ->>> view.reverse_action('set-password', args=['1']) +```pycon +>>> view.reverse_action("set-password", args=["1"]) 'http://localhost:8000/api/users/1/set_password' ``` 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']) 'http://localhost:8000/api/users/1/set_password' ``` diff --git a/docs/community/3.10-announcement.md b/docs/community/3.10-announcement.md index 23b6330a7b..a2135fd20f 100644 --- a/docs/community/3.10-announcement.md +++ b/docs/community/3.10-announcement.md @@ -41,8 +41,8 @@ update your REST framework settings to include `DEFAULT_SCHEMA_CLASS` explicitly ```python 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. # * `title` and `description` parameters are passed to `SchemaGenerator`. # * Provide view name for use with `reverse()`. - path('openapi', get_schema_view( - title="Your Project", - description="API for all things …" - ), name='openapi-schema'), + path( + "openapi", + get_schema_view(title="Your Project", description="API for all things …"), + name="openapi-schema", + ), # ... ] ``` diff --git a/docs/community/3.11-announcement.md b/docs/community/3.11-announcement.md index 83dd636d19..5a1f2c8e30 100644 --- a/docs/community/3.11-announcement.md +++ b/docs/community/3.11-announcement.md @@ -43,10 +43,11 @@ be extracted from the class docstring: ```python class DocStringExampleListView(APIView): -""" -get: A description of my GET operation. -post: A description of my POST operation. -""" + """ + get: A description of my GET operation. + post: A description of my POST operation. + """ + permission_classes = [permissions.IsAuthenticatedOrReadOnly] def get(self, request, *args, **kwargs): diff --git a/docs/community/3.12-announcement.md b/docs/community/3.12-announcement.md index 4a589e39c0..f7455cd643 100644 --- a/docs/community/3.12-announcement.md +++ b/docs/community/3.12-announcement.md @@ -41,7 +41,7 @@ The tags used for a particular view may also be overridden... ```python 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 class MyOrders(APIView): - schema = AutoSchema(component_name="OrderDetails") + schema = AutoSchema(component_name="OrderDetails") ``` ## More Public API @@ -118,10 +118,11 @@ class SitesSearchView(generics.ListAPIView): by a search against the site name or location. (Location searches are matched against the region and country names.) """ + queryset = Sites.objects.all() serializer_class = SitesSerializer filter_backends = [filters.SearchFilter] - search_fields = ['site_name', 'location__region', 'location__country'] + search_fields = ["site_name", "location__region", "location__country"] ``` ### Searches against annotate fields @@ -135,10 +136,11 @@ class PublisherSearchView(generics.ListAPIView): Search for publishers, optionally filtering the search against the average 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 filter_backends = [filters.SearchFilter] - search_fields = ['avg_rating'] + search_fields = ["avg_rating"] ``` --- diff --git a/docs/community/3.9-announcement.md b/docs/community/3.9-announcement.md index d673fdd183..6bc5e3cc39 100644 --- a/docs/community/3.9-announcement.md +++ b/docs/community/3.9-announcement.md @@ -65,15 +65,12 @@ from rest_framework.renderers import JSONOpenAPIRenderer from django.urls import path schema_view = get_schema_view( - title='Server Monitoring API', - url='https://www.example.org/api/', - renderer_classes=[JSONOpenAPIRenderer] + title="Server Monitoring API", + url="https://www.example.org/api/", + renderer_classes=[JSONOpenAPIRenderer], ) -urlpatterns = [ - path('schema.json', schema_view), - ... -] +urlpatterns = [path("schema.json", schema_view), ...] ``` And here's how you can use the `generateschema` management command: diff --git a/docs/community/release-notes.md b/docs/community/release-notes.md index 887cae3b47..a9c9e6533e 100644 --- a/docs/community/release-notes.md +++ b/docs/community/release-notes.md @@ -305,7 +305,11 @@ Be sure to upgrade to Python 3 before upgrading to Django REST Framework 3.10. class NullableCharField(serializers.CharField): def __init__(self, *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 by default, and add schema docs. [#6233][gh6233] diff --git a/docs/topics/documenting-your-api.md b/docs/topics/documenting-your-api.md index b85d6310ad..edb989290d 100644 --- a/docs/topics/documenting-your-api.md +++ b/docs/topics/documenting-your-api.md @@ -96,10 +96,14 @@ urlpatterns = [ # ... # Route TemplateView to serve Swagger UI template. # * Provide `extra_context` with view name of `SchemaView`. - path('swagger-ui/', TemplateView.as_view( - template_name='swagger-ui.html', - extra_context={'schema_url':'openapi-schema'} - ), name='swagger-ui'), + path( + "swagger-ui/", + TemplateView.as_view( + 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. # * Provide `extra_context` with view name of `SchemaView`. - path('redoc/', TemplateView.as_view( - template_name='redoc.html', - extra_context={'schema_url':'openapi-schema'} - ), name='redoc'), + path( + "redoc/", + TemplateView.as_view( + template_name="redoc.html", extra_context={"schema_url": "openapi-schema"} + ), + name="redoc", + ), ] ```