From 1ecc66b34ff1a80c3327083c7b7f40b7ab818b4b Mon Sep 17 00:00:00 2001 From: Joseph Victor Zammit Date: Wed, 15 Mar 2023 12:09:05 +0100 Subject: [PATCH 1/6] blacken-docs: Manual fixes for command to pass without errors --- docs/api-guide/schemas.md | 6 +++--- docs/api-guide/viewsets.md | 4 ++-- docs/community/3.10-announcement.md | 4 ++-- docs/community/3.11-announcement.md | 8 ++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/api-guide/schemas.md b/docs/api-guide/schemas.md index 3f0b155306..992e801f24 100644 --- a/docs/api-guide/schemas.md +++ b/docs/api-guide/schemas.md @@ -263,7 +263,7 @@ class CustomSchema(AutoSchema): 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 @@ -281,7 +281,7 @@ class BaseSchema(AutoSchema): ... class CustomSchema(BaseSchema): - extra_info = ... some extra info ... + extra_info = ... # some extra info class CustomView(APIView): schema = CustomSchema() @@ -304,7 +304,7 @@ class CustomSchema(BaseSchema): class CustomView(APIView): schema = CustomSchema( - extra_info=... some extra info ... + extra_info=... # some extra info ) ``` diff --git a/docs/api-guide/viewsets.md b/docs/api-guide/viewsets.md index 5d5491a83f..a5a24cae69 100644 --- a/docs/api-guide/viewsets.md +++ b/docs/api-guide/viewsets.md @@ -213,14 +213,14 @@ Note that the `basename` is provided by the router during `ViewSet` registration Using the example from the previous section: -```python +```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..b03b5a4607 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', } ``` diff --git a/docs/community/3.11-announcement.md b/docs/community/3.11-announcement.md index 83dd636d19..d4b91120ca 100644 --- a/docs/community/3.11-announcement.md +++ b/docs/community/3.11-announcement.md @@ -43,10 +43,10 @@ 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): From d947b146bcb8f1a8cad794f3b361cada0d7611ee Mon Sep 17 00:00:00 2001 From: Joseph Victor Zammit Date: Wed, 15 Mar 2023 12:10:34 +0100 Subject: [PATCH 2/6] blacken-docs: Adds blacken-docs step to precommit hook. --- .pre-commit-config.yaml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 83fe0b714b..70952cc6f0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,3 +18,9 @@ repos: - id: flake8 additional_dependencies: - flake8-tidy-imports +- repo: https://github.com/adamchainz/blacken-docs + rev: 1.13.0 + hooks: + - id: blacken-docs + additional_dependencies: + - black==23.1.0 From 81b6bf4bbb91b973bc0847f4e63fd73d6dc65a98 Mon Sep 17 00:00:00 2001 From: Joseph Victor Zammit Date: Wed, 15 Mar 2023 12:15:15 +0100 Subject: [PATCH 3/6] blacken-docs: Adds changes made by command itself. --- docs/api-guide/caching.md | 25 +++++++++++-------------- docs/api-guide/schemas.md | 22 ++++++++++++++-------- docs/api-guide/viewsets.md | 21 +++++++++++---------- docs/community/3.10-announcement.md | 13 +++++++------ docs/community/3.11-announcement.md | 1 + docs/community/3.12-announcement.md | 12 +++++++----- docs/community/3.9-announcement.md | 11 ++++------- docs/community/release-notes.md | 6 +++++- docs/topics/documenting-your-api.md | 23 +++++++++++++++-------- 9 files changed, 75 insertions(+), 59 deletions(-) diff --git a/docs/api-guide/caching.md b/docs/api-guide/caching.md index ab4f82cd2f..b9a77876d5 100644 --- a/docs/api-guide/caching.md +++ b/docs/api-guide/caching.md @@ -28,34 +28,31 @@ 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() - } + content = {"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() - } + content = {"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' - } + 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 992e801f24..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,8 +261,10 @@ class CustomSchema(AutoSchema): """ AutoSchema subclass using schema_extra_info on the view. """ + ... + class CustomView(APIView): schema = CustomSchema() schema_extra_info = ... # some extra info @@ -278,11 +282,14 @@ class BaseSchema(AutoSchema): """ AutoSchema subclass that knows how to use extra_info. """ + ... + class CustomSchema(BaseSchema): 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 a5a24cae69..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 @@ -214,7 +215,7 @@ Note that the `basename` is provided by the router during `ViewSet` registration Using the example from the previous section: ```pycon ->>> view.reverse_action('set-password', args=['1']) +>>> view.reverse_action("set-password", 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 b03b5a4607..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 d4b91120ca..5a1f2c8e30 100644 --- a/docs/community/3.11-announcement.md +++ b/docs/community/3.11-announcement.md @@ -47,6 +47,7 @@ class DocStringExampleListView(APIView): 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", + ), ] ``` From 75f91578ce5897ca6eb20e2751df4614fa0b809f Mon Sep 17 00:00:00 2001 From: Joseph Victor Zammit Date: Wed, 15 Mar 2023 12:46:19 +0100 Subject: [PATCH 4/6] blacken-docs: Modifies blacken-docs step to only process files under "docs" directory --- .pre-commit-config.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 70952cc6f0..a6cbc1d3ac 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,5 +22,6 @@ repos: rev: 1.13.0 hooks: - id: blacken-docs + files: docs additional_dependencies: - black==23.1.0 From 9586719c4550058505dd948ccf28e25bd74a694d Mon Sep 17 00:00:00 2001 From: Joseph Victor Zammit Date: Wed, 15 Mar 2023 16:50:56 +0100 Subject: [PATCH 5/6] blacken-docs: Updates pre-commit config file to exclude all directories other than "docs" to be compatible with "--all-files" flag. --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a6cbc1d3ac..64ec37770f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -22,6 +22,6 @@ repos: rev: 1.13.0 hooks: - id: blacken-docs - files: docs + exclude: ^(?!docs).*$ additional_dependencies: - black==23.1.0 From a19a202d3a4e3dbc3b716d866a2f453cd0e851ea Mon Sep 17 00:00:00 2001 From: Joseph Victor Zammit Date: Thu, 30 Mar 2023 12:51:36 +0200 Subject: [PATCH 6/6] blacken-docs: Adds commas at the end to make it look identical to pre-black version --- docs/api-guide/caching.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/docs/api-guide/caching.md b/docs/api-guide/caching.md index b9a77876d5..503acb09e6 100644 --- a/docs/api-guide/caching.md +++ b/docs/api-guide/caching.md @@ -31,20 +31,20 @@ class UserViewSet(viewsets.ViewSet): @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()} + content = { + "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(vary_on_headers("Authorization")) def get(self, request, format=None): - content = {"user_feed": request.user.get_user_feed()} + content = { + "user_feed": request.user.get_user_feed(), + } return Response(content) @@ -52,7 +52,10 @@ class PostView(APIView): # Cache page for the requested url @method_decorator(cache_page(60 * 60 * 2)) def get(self, request, format=None): - content = {"title": "Post title", "body": "Post content"} + content = { + "title": "Post title", + "body": "Post content", + } return Response(content) ```