mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-11-04 09:57:55 +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
 | 
			
		||||
    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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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)
 | 
			
		||||
```
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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.
 | 
			
		||||
 | 
			
		||||
```python
 | 
			
		||||
    @action(detail=True, methods=['put'], name='Change Password')
 | 
			
		||||
    def password(self, request, pk=None):
 | 
			
		||||
        """Update 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."""
 | 
			
		||||
        ...
 | 
			
		||||
 | 
			
		||||
@password.mapping.delete
 | 
			
		||||
def delete_password(self, request, pk=None):
 | 
			
		||||
    """Delete the user's password."""
 | 
			
		||||
    ...
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## 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:
 | 
			
		||||
 | 
			
		||||
```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'
 | 
			
		||||
```
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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",
 | 
			
		||||
    ),
 | 
			
		||||
    # ...
 | 
			
		||||
]
 | 
			
		||||
```
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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"]
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -306,7 +306,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]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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",
 | 
			
		||||
    ),
 | 
			
		||||
]
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user