From 3fa4affce21dd2b27677b415730a73fe8263d40e Mon Sep 17 00:00:00 2001 From: Shyamkumar Yadav Date: Sat, 15 Oct 2022 13:41:31 +0530 Subject: [PATCH] Docs: fix code block style --- docs/api-guide/caching.md | 68 +++++++------ docs/api-guide/renderers.md | 4 +- docs/api-guide/schemas.md | 146 ++++++++++++---------------- docs/api-guide/viewsets.md | 26 ++--- docs/community/3.10-announcement.md | 36 +++---- docs/community/3.11-announcement.md | 42 ++++---- docs/community/3.12-announcement.md | 56 +++++------ docs/community/3.13-announcement.md | 8 +- docs/community/3.5-announcement.md | 22 ++--- docs/community/3.9-announcement.md | 46 ++++----- docs/community/release-notes.md | 12 +-- docs/topics/documenting-your-api.md | 146 +++++++++++++--------------- 12 files changed, 269 insertions(+), 343 deletions(-) diff --git a/docs/api-guide/caching.md b/docs/api-guide/caching.md index ab4f82cd2..0cabe87db 100644 --- a/docs/api-guide/caching.md +++ b/docs/api-guide/caching.md @@ -16,48 +16,46 @@ decorators with class based views. This can be used with other cache decorators such as [`cache_page`][page], [`vary_on_cookie`][cookie] and [`vary_on_headers`][headers]. -```python -from django.utils.decorators import method_decorator -from django.views.decorators.cache import cache_page -from django.views.decorators.vary import vary_on_cookie, vary_on_headers + from django.utils.decorators import method_decorator + from django.views.decorators.cache import cache_page + from django.views.decorators.vary import vary_on_cookie, vary_on_headers -from rest_framework.response import Response -from rest_framework.views import APIView -from rest_framework import viewsets + from rest_framework.response import Response + from rest_framework.views import APIView + 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(vary_on_cookie) - def list(self, request, format=None): - content = { - 'user_feed': request.user.get_user_feed() - } - return Response(content) + class UserViewSet(viewsets.ViewSet): + # With cookie: cache requested url for each user for 2 hours + @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() + } + 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",)) - def get(self, request, format=None): - 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",)) + def get(self, request, format=None): + 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)) - def get(self, request, format=None): - content = { - 'title': 'Post title', - 'body': 'Post content' - } - return Response(content) -``` + 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' + } + return Response(content) **NOTE:** The [`cache_page`][page] decorator only caches the `GET` and `HEAD` responses with status 200. diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md index 685a98f5e..b8ed94200 100644 --- a/docs/api-guide/renderers.md +++ b/docs/api-guide/renderers.md @@ -107,9 +107,7 @@ The TemplateHTMLRenderer will create a `RequestContext`, using the `response.dat **Note:** When used with a view that makes use of a serializer the `Response` sent for rendering may not be a dictionary and will need to be wrapped in a dict before returning to allow the TemplateHTMLRenderer to render it. For example: -``` -response.data = {'results': response.data} -``` + response.data = {'results': response.data} --- diff --git a/docs/api-guide/schemas.md b/docs/api-guide/schemas.md index 004e2d3ce..3181d3c9e 100644 --- a/docs/api-guide/schemas.md +++ b/docs/api-guide/schemas.md @@ -48,9 +48,7 @@ The following sections explain more. If your schema is static, you can use the `generateschema` management command: -```bash -./manage.py generateschema --file openapi-schema.yml -``` + ./manage.py generateschema --file openapi-schema.yml Once you've generated a schema in this way you can annotate it with any additional information that cannot be automatically inferred by the schema @@ -69,22 +67,20 @@ To route a `SchemaView`, use the `get_schema_view()` helper. In `urls.py`: -```python -from rest_framework.schemas import get_schema_view + from rest_framework.schemas import get_schema_view -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'), - # ... -] -``` + 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'), + # ... + ] #### `get_schema_view()` @@ -139,9 +135,7 @@ The `get_schema_view()` helper takes the following keyword arguments: **Schema-level customization** -```python -from rest_framework.schemas.openapi import SchemaGenerator -``` + from rest_framework.schemas.openapi import SchemaGenerator `SchemaGenerator` is a class that walks a list of routed URL patterns, requests the schema for each view and collates the resulting OpenAPI schema. @@ -179,21 +173,17 @@ This is a good point to override if you want to customize the generated dictionary For example you might wish to add terms of service to the [top-level `info` object][info-object]: -``` -class TOSSchemaGenerator(SchemaGenerator): - def get_schema(self, *args, **kwargs): - schema = super().get_schema(*args, **kwargs) - schema["info"]["termsOfService"] = "https://example.com/tos.html" - return schema -``` + class TOSSchemaGenerator(SchemaGenerator): + def get_schema(self, *args, **kwargs): + schema = super().get_schema(*args, **kwargs) + schema["info"]["termsOfService"] = "https://example.com/tos.html" + return schema ## AutoSchema **Per-View Customization** -```python -from rest_framework.schemas.openapi import AutoSchema -``` + from rest_framework.schemas.openapi import AutoSchema By default, view introspection is performed by an `AutoSchema` instance accessible via the `schema` attribute on `APIView`. @@ -209,10 +199,8 @@ and path: the endpoint, including path and query parameters for pagination, filtering, and so on. -```python -components = auto_schema.get_components(...) -operation = auto_schema.get_operation(...) -``` + components = auto_schema.get_components(...) + operation = auto_schema.get_operation(...) In compiling the schema, `SchemaGenerator` calls `get_components()` and `get_operation()` for each view, allowed method, and path. @@ -236,17 +224,15 @@ Keeping with this pattern, try not to let schema logic leak into your own views, serializers, or fields when customizing the schema generation. You might be tempted to do something like this: -```python -class CustomSchema(AutoSchema): - """ - AutoSchema subclass using schema_extra_info on the view. - """ - ... + class CustomSchema(AutoSchema): + """ + AutoSchema subclass using schema_extra_info on the view. + """ + ... -class CustomView(APIView): - schema = CustomSchema() - schema_extra_info = ... some extra info ... -``` + class CustomView(APIView): + schema = CustomSchema() + schema_extra_info = ... some extra info ... Here, the `AutoSchema` subclass goes looking for `schema_extra_info` on the view. This is _OK_ (it doesn't actually hurt) but it means you'll end up with @@ -255,19 +241,17 @@ your schema logic spread out in a number of different places. Instead try to subclass `AutoSchema` such that the `extra_info` doesn't leak out into the view: -```python -class BaseSchema(AutoSchema): - """ - AutoSchema subclass that knows how to use extra_info. - """ - ... + class BaseSchema(AutoSchema): + """ + AutoSchema subclass that knows how to use extra_info. + """ + ... -class CustomSchema(BaseSchema): - extra_info = ... some extra info ... + class CustomSchema(BaseSchema): + extra_info = ... some extra info ... -class CustomView(APIView): - schema = CustomSchema() -``` + class CustomView(APIView): + schema = CustomSchema() This style is slightly more verbose but maintains the encapsulation of the schema related code. It's more _cohesive_ in the _parlance_. It'll keep the @@ -277,18 +261,16 @@ If an option applies to many view classes, rather than creating a specific subclass per-view, you may find it more convenient to allow specifying the option as an `__init__()` kwarg to your base `AutoSchema` subclass: -```python -class CustomSchema(BaseSchema): - def __init__(self, **kwargs): - # store extra_info for later - self.extra_info = kwargs.pop("extra_info") - super().__init__(**kwargs) + class CustomSchema(BaseSchema): + def __init__(self, **kwargs): + # store extra_info for later + self.extra_info = kwargs.pop("extra_info") + super().__init__(**kwargs) -class CustomView(APIView): - schema = CustomSchema( - extra_info=... some extra info ... - ) -``` + class CustomView(APIView): + schema = CustomSchema( + extra_info=... some extra info ... + ) This saves you having to create a custom subclass per-view for a commonly used option. @@ -333,15 +315,13 @@ will handle the default fields that Django REST Framework provides. For `SerializerMethodField` instances, for which the schema is unknown, or custom field subclasses you should override `map_field()` to generate the correct schema: -```python -class CustomSchema(AutoSchema): - """Extension of ``AutoSchema`` to add support for custom field schemas.""" + class CustomSchema(AutoSchema): + """Extension of ``AutoSchema`` to add support for custom field schemas.""" - def map_field(self, field): - # Handle SerializerMethodFields or custom fields here... - # ... - return super().map_field(field) -``` + def map_field(self, field): + # Handle SerializerMethodFields or custom fields here... + # ... + return super().map_field(field) Authors of third-party packages should aim to provide an `AutoSchema` subclass, and a mixin, overriding `map_field()` so that users can easily generate schemas @@ -407,15 +387,13 @@ The available kwargs are: You pass the kwargs when declaring the `AutoSchema` instance on your view: -``` -class PetDetailView(generics.RetrieveUpdateDestroyAPIView): - schema = AutoSchema( - tags=['Pets'], - component_name='Pet', - operation_id_base='Pet', - ) - ... -``` + class PetDetailView(generics.RetrieveUpdateDestroyAPIView): + schema = AutoSchema( + tags=['Pets'], + component_name='Pet', + operation_id_base='Pet', + ) + ... Assuming a `Pet` model and `PetSerializer` serializer, the kwargs in this example are probably not needed. Often, though, you'll need to pass the kwargs diff --git a/docs/api-guide/viewsets.md b/docs/api-guide/viewsets.md index 417972507..4a946bc7c 100644 --- a/docs/api-guide/viewsets.md +++ b/docs/api-guide/viewsets.md @@ -174,16 +174,16 @@ A more complete example of extra actions: The `action` decorator will route `GET` requests by default, but may also accept other HTTP methods by setting the `methods` argument. For example: - @action(detail=True, methods=['post', 'delete']) - def unset_password(self, request, pk=None): - ... + @action(detail=True, methods=['post', 'delete']) + def unset_password(self, request, pk=None): + ... The decorator allows you to override any viewset-level configuration such as `permission_classes`, `serializer_class`, `filter_backends`...: - @action(detail=True, methods=['post'], permission_classes=[IsAdminOrIsSelf]) - def set_password(self, request, pk=None): - ... + @action(detail=True, methods=['post'], permission_classes=[IsAdminOrIsSelf]) + def set_password(self, request, pk=None): + ... The two new actions will then be available at the urls `^users/{pk}/set_password/$` and `^users/{pk}/unset_password/$`. Use the `url_path` and `url_name` parameters to change the URL segment and the reverse URL name of the action. @@ -193,7 +193,6 @@ 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.""" @@ -203,7 +202,6 @@ Extra actions can map additional HTTP methods to separate `ViewSet` methods. For def delete_password(self, request, pk=None): """Delete the user's password.""" ... -``` ## Reversing action URLs @@ -213,17 +211,13 @@ 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']) -'http://localhost:8000/api/users/1/set_password' -``` + >>> 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 ->>> view.reverse_action(view.set_password.url_name, args=['1']) -'http://localhost:8000/api/users/1/set_password' -``` + >>> view.reverse_action(view.set_password.url_name, args=['1']) + 'http://localhost:8000/api/users/1/set_password' The `url_name` argument for `.reverse_action()` should match the same argument to the `@action` decorator. Additionally, this method can be used to reverse the default actions, such as `list` and `create`. diff --git a/docs/community/3.10-announcement.md b/docs/community/3.10-announcement.md index 19748aa40..c94d29cbc 100644 --- a/docs/community/3.10-announcement.md +++ b/docs/community/3.10-announcement.md @@ -39,12 +39,10 @@ update your REST framework settings to include `DEFAULT_SCHEMA_CLASS` explicitly **settings.py**: -```python -REST_FRAMEWORK = { - ... - 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema' -} -``` + REST_FRAMEWORK = { + ... + 'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema' + } You'll still be able to keep using CoreAPI schemas, API docs, and client for the foreseeable future. We'll aim to ensure that the CoreAPI schema generator remains @@ -66,21 +64,19 @@ shortcut. In your `urls.py`: -```python -from rest_framework.schemas import get_schema_view + from rest_framework.schemas import get_schema_view -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'), - # ... -] -``` + 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'), + # ... + ] ### Customization diff --git a/docs/community/3.11-announcement.md b/docs/community/3.11-announcement.md index 83dd636d1..1548e506a 100644 --- a/docs/community/3.11-announcement.md +++ b/docs/community/3.11-announcement.md @@ -41,20 +41,18 @@ include: In this example view operation descriptions for the `get` and `post` methods will be extracted from the class docstring: -```python -class DocStringExampleListView(APIView): -""" -get: A description of my GET operation. -post: A description of my POST operation. -""" - permission_classes = [permissions.IsAuthenticatedOrReadOnly] + 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): - ... + def get(self, request, *args, **kwargs): + ... - def post(self, request, *args, **kwargs): - ... -``` + def post(self, request, *args, **kwargs): + ... ## Validator / Default Context @@ -71,23 +69,19 @@ The `__call__` method should then include an additional `serializer_field` argum Validator implementations will look like this: -```python -class CustomValidator: - requires_context = True + class CustomValidator: + requires_context = True - def __call__(self, value, serializer_field): - ... -``` + def __call__(self, value, serializer_field): + ... Default implementations will look like this: -```python -class CustomDefault: - requires_context = True + class CustomDefault: + requires_context = True - def __call__(self, serializer_field): - ... -``` + def __call__(self, serializer_field): + ... --- diff --git a/docs/community/3.12-announcement.md b/docs/community/3.12-announcement.md index 4a589e39c..b8fbd19e0 100644 --- a/docs/community/3.12-announcement.md +++ b/docs/community/3.12-announcement.md @@ -39,11 +39,9 @@ Method | Path | Tags The tags used for a particular view may also be overridden... -```python -class MyOrders(APIView): - schema = AutoSchema(tags=['users', 'orders']) - ... -``` + class MyOrders(APIView): + schema = AutoSchema(tags=['users', 'orders']) + ... See [the schema documentation](https://www.django-rest-framework.org/api-guide/schemas/#grouping-operations-with-tags) for more information. @@ -66,10 +64,8 @@ The names used for a component default to using the serializer class name, [but may be overridden if needed](https://www.django-rest-framework.org/api-guide/schemas/#components )... -```python -class MyOrders(APIView): - schema = AutoSchema(component_name="OrderDetails") -``` + class MyOrders(APIView): + schema = AutoSchema(component_name="OrderDetails") ## More Public API @@ -111,35 +107,31 @@ The class now supports nested search within `JSONField` and `HStoreField`, using the double underscore notation for traversing which element of the field the search should apply to. -```python -class SitesSearchView(generics.ListAPIView): - """ - An API view to return a list of archaeological sites, optionally filtered - 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'] -``` + class SitesSearchView(generics.ListAPIView): + """ + An API view to return a list of archaeological sites, optionally filtered + 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'] ### Searches against annotate fields Django allows querysets to create additional virtual fields, using the `.annotate` method. We now support searching against annotate fields. -```python -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')) - serializer_class = PublisherSerializer - filter_backends = [filters.SearchFilter] - search_fields = ['avg_rating'] -``` + 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')) + serializer_class = PublisherSerializer + filter_backends = [filters.SearchFilter] + search_fields = ['avg_rating'] --- diff --git a/docs/community/3.13-announcement.md b/docs/community/3.13-announcement.md index e2c1fefa6..ccaed4e3e 100644 --- a/docs/community/3.13-announcement.md +++ b/docs/community/3.13-announcement.md @@ -40,15 +40,11 @@ From REST framework 3.13 onwards, this is now *explicitly enforced*. The most feasible cases where users might be accidentally omitting the keyword arguments are likely in the composite fields, `ListField` and `DictField`. For instance... -```python -aliases = serializers.ListField(serializers.CharField()) -``` + aliases = serializers.ListField(serializers.CharField()) They must now use the more explicit keyword argument style... -```python -aliases = serializers.ListField(child=serializers.CharField()) -``` + aliases = serializers.ListField(child=serializers.CharField()) This change has been made because using positional arguments here *does not* result in the expected behaviour. diff --git a/docs/community/3.5-announcement.md b/docs/community/3.5-announcement.md index 91bfce428..dee048ccc 100644 --- a/docs/community/3.5-announcement.md +++ b/docs/community/3.5-announcement.md @@ -59,20 +59,18 @@ For example, to include a swagger schema to your API, you would do the following * Include the schema view in your URL conf: -```py -from rest_framework.schemas import get_schema_view -from rest_framework_swagger.renderers import OpenAPIRenderer, SwaggerUIRenderer + from rest_framework.schemas import get_schema_view + from rest_framework_swagger.renderers import OpenAPIRenderer, SwaggerUIRenderer -schema_view = get_schema_view( - title='Example API', - renderer_classes=[OpenAPIRenderer, SwaggerUIRenderer] -) + schema_view = get_schema_view( + title='Example API', + renderer_classes=[OpenAPIRenderer, SwaggerUIRenderer] + ) -urlpatterns = [ - path('swagger/', schema_view), - ... -] -``` + urlpatterns = [ + path('swagger/', schema_view), + ... + ] There have been a large number of fixes to the schema generation. These should resolve issues for anyone using the latest version of the `django-rest-swagger` diff --git a/docs/community/3.9-announcement.md b/docs/community/3.9-announcement.md index d673fdd18..beab0bc5d 100644 --- a/docs/community/3.9-announcement.md +++ b/docs/community/3.9-announcement.md @@ -59,28 +59,24 @@ the schema into your repository. Here's an example of adding an OpenAPI schema to the URL conf: -```python -from rest_framework.schemas import get_schema_view -from rest_framework.renderers import JSONOpenAPIRenderer -from django.urls import path + from rest_framework.schemas import get_schema_view + 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] -) + schema_view = get_schema_view( + 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: -```shell -$ python manage.py generateschema --format openapi > schema.yml -``` + $ python manage.py generateschema --format openapi > schema.yml There's lots of different tooling that you can use for working with OpenAPI schemas. One option that we're working on is the [API Star](https://docs.apistar.com/) @@ -88,17 +84,13 @@ command line tool. You can use `apistar` to validate your API schema: -```shell -$ apistar validate --path schema.json --format openapi -✓ Valid OpenAPI schema. -``` + $ apistar validate --path schema.json --format openapi + ✓ Valid OpenAPI schema. Or to build API documentation: -```shell -$ apistar docs --path schema.json --format openapi -✓ Documentation built at "build/index.html". -``` + $ apistar docs --path schema.json --format openapi + ✓ Documentation built at "build/index.html". API Star also includes a [dynamic client library](https://docs.apistar.com/client-library/) that uses an API schema to automatically provide a client library interface for making requests. @@ -109,9 +101,7 @@ You can now compose permission classes using the and/or operators, `&` and `|`. For example... -```python -permission_classes = [IsAuthenticated & (ReadOnly | IsAdminUser)] -``` + permission_classes = [IsAuthenticated & (ReadOnly | IsAdminUser)] If you're using custom permission classes then make sure that you are subclassing from `BasePermission` in order to enable this support. diff --git a/docs/community/release-notes.md b/docs/community/release-notes.md index 887cae3b4..daa7033a5 100644 --- a/docs/community/release-notes.md +++ b/docs/community/release-notes.md @@ -301,12 +301,12 @@ Be sure to upgrade to Python 3 before upgrading to Django REST Framework 3.10. * Deprecate the `Router.get_default_base_name` method in favor of `Router.get_default_basename`. [#5990][gh5990] * Change `CharField` to disallow null bytes. [#6073][gh6073] To revert to the old behavior, subclass `CharField` and remove `ProhibitNullCharactersValidator` from the validators. - ```python - 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)] - ``` + + 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)] + * Add `OpenAPIRenderer` and `generate_schema` management command. [#6229][gh6229] * Add OpenAPIRenderer by default, and add schema docs. [#6233][gh6233] * Allow permissions to be composed [#5753][gh5753] diff --git a/docs/topics/documenting-your-api.md b/docs/topics/documenting-your-api.md index 5eabeee7b..b91d7c979 100644 --- a/docs/topics/documenting-your-api.md +++ b/docs/topics/documenting-your-api.md @@ -25,53 +25,49 @@ Assuming you've followed the example from the schemas documentation for routing a dynamic `SchemaView`, a minimal Django template for using Swagger UI might be this: -```html - - - - Swagger - - - - - -
- - - - -``` + + + + Swagger + + + + + +
+ + + + Save this in your templates folder as `swagger-ui.html`. Then route a `TemplateView` in your project's URL conf: -```python -from django.views.generic import TemplateView + from django.views.generic import TemplateView -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'), -] -``` + 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'), + ] See the [Swagger UI documentation][swagger-ui] for advanced usage. @@ -81,46 +77,42 @@ Assuming you've followed the example from the schemas documentation for routing a dynamic `SchemaView`, a minimal Django template for using ReDoc might be this: -```html - - - - ReDoc - - - - - - - - - - - - -``` + + + + ReDoc + + + + + + + + + + + + Save this in your templates folder as `redoc.html`. Then route a `TemplateView` in your project's URL conf: -```python -from django.views.generic import TemplateView + from django.views.generic import TemplateView -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'), -] -``` + 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'), + ] See the [ReDoc documentation][redoc] for advanced usage.