mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-07-28 00:49:49 +03:00
Merge branch 'master' of https://github.com/encode/django-rest-framework
This commit is contained in:
commit
b887b14b60
|
@ -17,11 +17,16 @@ other cache decorators such as [`cache_page`][page] and
|
|||
[`vary_on_cookie`][cookie].
|
||||
|
||||
```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
|
||||
|
||||
from rest_framework.response import Response
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework import viewsets
|
||||
|
||||
class UserViewSet(viewsets.Viewset):
|
||||
|
||||
class UserViewSet(viewsets.ViewSet):
|
||||
|
||||
# Cache requested url for each user for 2 hours
|
||||
@method_decorator(cache_page(60*60*2))
|
||||
|
@ -32,6 +37,7 @@ class UserViewSet(viewsets.Viewset):
|
|||
}
|
||||
return Response(content)
|
||||
|
||||
|
||||
class PostView(APIView):
|
||||
|
||||
# Cache page for the requested url
|
||||
|
|
|
@ -713,7 +713,7 @@ the coordinate pair:
|
|||
fields = ['label', 'coordinates']
|
||||
|
||||
Note that this example doesn't handle validation. Partly for that reason, in a
|
||||
real project, the coordinate nesting might be better handled with a nested serialiser
|
||||
real project, the coordinate nesting might be better handled with a nested serializer
|
||||
using `source='*'`, with two `IntegerField` instances, each with their own `source`
|
||||
pointing to the relevant field.
|
||||
|
||||
|
@ -746,7 +746,7 @@ suitable for updating our target object. With `source='*'`, the return from
|
|||
('y_coordinate', 4),
|
||||
('x_coordinate', 3)])
|
||||
|
||||
For completeness lets do the same thing again but with the nested serialiser
|
||||
For completeness lets do the same thing again but with the nested serializer
|
||||
approach suggested above:
|
||||
|
||||
class NestedCoordinateSerializer(serializers.Serializer):
|
||||
|
@ -768,14 +768,14 @@ declarations. It's our `NestedCoordinateSerializer` that takes `source='*'`.
|
|||
Our new `DataPointSerializer` exhibits the same behaviour as the custom field
|
||||
approach.
|
||||
|
||||
Serialising:
|
||||
Serializing:
|
||||
|
||||
>>> out_serializer = DataPointSerializer(instance)
|
||||
>>> out_serializer.data
|
||||
ReturnDict([('label', 'testing'),
|
||||
('coordinates', OrderedDict([('x', 1), ('y', 2)]))])
|
||||
|
||||
Deserialising:
|
||||
Deserializing:
|
||||
|
||||
>>> in_serializer = DataPointSerializer(data=data)
|
||||
>>> in_serializer.is_valid()
|
||||
|
@ -802,8 +802,8 @@ But we also get the built-in validation for free:
|
|||
{'x': ['A valid integer is required.'],
|
||||
'y': ['A valid integer is required.']})])
|
||||
|
||||
For this reason, the nested serialiser approach would be the first to try. You
|
||||
would use the custom field approach when the nested serialiser becomes infeasible
|
||||
For this reason, the nested serializer approach would be the first to try. You
|
||||
would use the custom field approach when the nested serializer becomes infeasible
|
||||
or overly complex.
|
||||
|
||||
|
||||
|
|
|
@ -378,10 +378,6 @@ If you need to generic PUT-as-create behavior you may want to include something
|
|||
|
||||
The following third party packages provide additional generic view implementations.
|
||||
|
||||
## Django REST Framework bulk
|
||||
|
||||
The [django-rest-framework-bulk package][django-rest-framework-bulk] implements generic view mixins as well as some common concrete generic views to allow to apply bulk operations via API requests.
|
||||
|
||||
## Django Rest Multiple Models
|
||||
|
||||
[Django Rest Multiple Models][django-rest-multiple-models] provides a generic view (and mixin) for sending multiple serialized models and/or querysets via a single API request.
|
||||
|
@ -394,5 +390,4 @@ The [django-rest-framework-bulk package][django-rest-framework-bulk] implements
|
|||
[RetrieveModelMixin]: #retrievemodelmixin
|
||||
[UpdateModelMixin]: #updatemodelmixin
|
||||
[DestroyModelMixin]: #destroymodelmixin
|
||||
[django-rest-framework-bulk]: https://github.com/miki725/django-rest-framework-bulk
|
||||
[django-rest-multiple-models]: https://github.com/MattBroach/DjangoRestMultipleModels
|
||||
|
|
|
@ -49,7 +49,7 @@ If a client sends a request with a content-type that cannot be parsed then a `Un
|
|||
|
||||
# Content negotiation
|
||||
|
||||
The request exposes some properties that allow you to determine the result of the content negotiation stage. This allows you to implement behaviour such as selecting a different serialisation schemes for different media types.
|
||||
The request exposes some properties that allow you to determine the result of the content negotiation stage. This allows you to implement behaviour such as selecting a different serialization schemes for different media types.
|
||||
|
||||
## .accepted_renderer
|
||||
|
||||
|
|
|
@ -115,7 +115,6 @@ The `get_schema_view()` helper takes the following keyword arguments:
|
|||
* `renderer_classes`: May be used to pass the set of renderer classes that can
|
||||
be used to render the API root endpoint.
|
||||
|
||||
|
||||
## Customizing Schema Generation
|
||||
|
||||
You may customize schema generation at the level of the schema as a whole, or
|
||||
|
@ -155,7 +154,7 @@ Returns a dictionary that represents the OpenAPI schema:
|
|||
The `request` argument is optional, and may be used if you want to apply
|
||||
per-user permissions to the resulting schema generation.
|
||||
|
||||
This is a good point to override if you want to customise the generated
|
||||
This is a good point to override if you want to customize the generated
|
||||
dictionary, for example to add custom
|
||||
[specification extensions][openapi-specification-extensions].
|
||||
|
||||
|
@ -177,21 +176,20 @@ for each view, allowed method, and path.
|
|||
**Note**: For basic `APIView` subclasses, default introspection is essentially
|
||||
limited to the URL kwarg path parameters. For `GenericAPIView`
|
||||
subclasses, which includes all the provided class based views, `AutoSchema` will
|
||||
attempt to introspect serialiser, pagination and filter fields, as well as
|
||||
attempt to introspect serializer, pagination and filter fields, as well as
|
||||
provide richer path field descriptions. (The key hooks here are the relevant
|
||||
`GenericAPIView` attributes and methods: `get_serializer`, `pagination_class`,
|
||||
`filter_backends` and so on.)
|
||||
|
||||
---
|
||||
|
||||
In order to customise the operation generation, you should provide an `AutoSchema` subclass, overriding `get_operation()` as you need:
|
||||
|
||||
In order to customize the operation generation, you should provide an `AutoSchema` subclass, overriding `get_operation()` as you need:
|
||||
|
||||
from rest_framework.views import APIView
|
||||
from rest_framework.schemas.openapi import AutoSchema
|
||||
|
||||
class CustomSchema(AutoSchema):
|
||||
def get_link(...):
|
||||
def get_operation(...):
|
||||
# Implement custom introspection here (or in other sub-methods)
|
||||
|
||||
class CustomView(APIView):
|
||||
|
@ -219,4 +217,4 @@ project you may adjust `settings.DEFAULT_SCHEMA_CLASS` appropriately.
|
|||
|
||||
[openapi]: https://github.com/OAI/OpenAPI-Specification
|
||||
[openapi-specification-extensions]: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#specification-extensions
|
||||
[openapi-operation]: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#operationObject
|
||||
[openapi-operation]: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.2.md#operationObject
|
||||
|
|
|
@ -222,11 +222,11 @@ Be sure to upgrade to Python 3 before upgrading to Django REST Framework 3.10.
|
|||
def perform_create(self, serializer):
|
||||
serializer.save(owner=self.request.user)
|
||||
|
||||
Alternatively you may override `save()` or `create()` or `update()` on the serialiser as appropriate.
|
||||
Alternatively you may override `save()` or `create()` or `update()` on the serializer as appropriate.
|
||||
|
||||
* Correct allow_null behaviour when required=False [#5888][gh5888]
|
||||
|
||||
Without an explicit `default`, `allow_null` implies a default of `null` for outgoing serialisation. Previously such
|
||||
Without an explicit `default`, `allow_null` implies a default of `null` for outgoing serialization. Previously such
|
||||
fields were being skipped when read-only or otherwise not required.
|
||||
|
||||
**Possible backwards compatibility break** if you were relying on such fields being excluded from the outgoing
|
||||
|
@ -464,7 +464,7 @@ Be sure to upgrade to Python 3 before upgrading to Django REST Framework 3.10.
|
|||
* Deprecated `exclude_from_schema` on `APIView` and `api_view` decorator. Set `schema = None` or `@schema(None)` as appropriate. [#5422][gh5422]
|
||||
* Timezone-aware `DateTimeField`s now respect active or default `timezone` during serialization, instead of always using UTC. [#5435][gh5435]
|
||||
|
||||
Resolves inconsistency whereby instances were serialised with supplied datetime for `create` but UTC for `retrieve`. [#3732][gh3732]
|
||||
Resolves inconsistency whereby instances were serialized with supplied datetime for `create` but UTC for `retrieve`. [#3732][gh3732]
|
||||
|
||||
**Possible backwards compatibility break** if you were relying on datetime strings being UTC. Have client interpret datetimes or [set default or active timezone (docs)][djangodocs-set-timezone] to UTC if needed.
|
||||
|
||||
|
|
|
@ -222,7 +222,6 @@ To submit new content, [open an issue][drf-create-issue] or [create a pull reque
|
|||
|
||||
### Views
|
||||
|
||||
* [djangorestframework-bulk][djangorestframework-bulk] - Implements generic view mixins as well as some common concrete generic views to allow to apply bulk operations via API requests.
|
||||
* [django-rest-multiple-models][django-rest-multiple-models] - Provides a generic view (and mixin) for sending multiple serialized models and/or querysets via a single API request.
|
||||
|
||||
### Routers
|
||||
|
@ -254,7 +253,7 @@ To submit new content, [open an issue][drf-create-issue] or [create a pull reque
|
|||
### Misc
|
||||
|
||||
* [cookiecutter-django-rest][cookiecutter-django-rest] - A cookiecutter template that takes care of the setup and configuration so you can focus on making your REST apis awesome.
|
||||
* [djangorestrelationalhyperlink][djangorestrelationalhyperlink] - A hyperlinked serialiser that can can be used to alter relationships via hyperlinks, but otherwise like a hyperlink model serializer.
|
||||
* [djangorestrelationalhyperlink][djangorestrelationalhyperlink] - A hyperlinked serializer that can can be used to alter relationships via hyperlinks, but otherwise like a hyperlink model serializer.
|
||||
* [django-rest-swagger][django-rest-swagger] - An API documentation generator for Swagger UI.
|
||||
* [django-rest-framework-proxy][django-rest-framework-proxy] - Proxy to redirect incoming request to another API server.
|
||||
* [gaiarestframework][gaiarestframework] - Utils for django-rest-framework
|
||||
|
@ -305,7 +304,6 @@ To submit new content, [open an issue][drf-create-issue] or [create a pull reque
|
|||
[djangorestframework-hstore]: https://github.com/djangonauts/django-rest-framework-hstore
|
||||
[drf-compound-fields]: https://github.com/estebistec/drf-compound-fields
|
||||
[django-extra-fields]: https://github.com/Hipo/drf-extra-fields
|
||||
[djangorestframework-bulk]: https://github.com/miki725/django-rest-framework-bulk
|
||||
[django-rest-multiple-models]: https://github.com/MattBroach/DjangoRestMultipleModels
|
||||
[drf-nested-routers]: https://github.com/alanjds/drf-nested-routers
|
||||
[wq.db.rest]: https://wq.io/docs/about-rest
|
||||
|
|
|
@ -191,7 +191,7 @@ each view, allowed method and path.)
|
|||
**Note**: For basic `APIView` subclasses, default introspection is essentially
|
||||
limited to the URL kwarg path parameters. For `GenericAPIView`
|
||||
subclasses, which includes all the provided class based views, `AutoSchema` will
|
||||
attempt to introspect serialiser, pagination and filter fields, as well as
|
||||
attempt to introspect serializer, pagination and filter fields, as well as
|
||||
provide richer path field descriptions. (The key hooks here are the relevant
|
||||
`GenericAPIView` attributes and methods: `get_serializer`, `pagination_class`,
|
||||
`filter_backends` and so on.)
|
||||
|
|
|
@ -10,7 +10,7 @@ ______ _____ _____ _____ __
|
|||
__title__ = 'Django REST framework'
|
||||
__version__ = '3.10.3'
|
||||
__author__ = 'Tom Christie'
|
||||
__license__ = 'BSD 2-Clause'
|
||||
__license__ = 'BSD 3-Clause'
|
||||
__copyright__ = 'Copyright 2011-2019 Encode OSS Ltd'
|
||||
|
||||
# Version synonym
|
||||
|
|
|
@ -209,7 +209,7 @@ class AutoSchema(ViewInspector):
|
|||
if not is_list_view(path, method, view):
|
||||
return []
|
||||
|
||||
paginator = self._get_pagninator()
|
||||
paginator = self._get_paginator()
|
||||
if not paginator:
|
||||
return []
|
||||
|
||||
|
@ -344,6 +344,7 @@ class AutoSchema(ViewInspector):
|
|||
serializers.BooleanField: 'boolean',
|
||||
serializers.JSONField: 'object',
|
||||
serializers.DictField: 'object',
|
||||
serializers.HStoreField: 'object',
|
||||
}
|
||||
return {'type': FIELD_CLASS_SCHEMA_TYPE.get(field.__class__, 'string')}
|
||||
|
||||
|
@ -429,7 +430,7 @@ class AutoSchema(ViewInspector):
|
|||
schema['maximum'] = int(digits * '9') + 1
|
||||
schema['minimum'] = -schema['maximum']
|
||||
|
||||
def _get_pagninator(self):
|
||||
def _get_paginator(self):
|
||||
pagination_class = getattr(self.view, 'pagination_class', None)
|
||||
if pagination_class:
|
||||
return pagination_class()
|
||||
|
@ -502,7 +503,7 @@ class AutoSchema(ViewInspector):
|
|||
'type': 'array',
|
||||
'items': item_schema,
|
||||
}
|
||||
paginator = self._get_pagninator()
|
||||
paginator = self._get_paginator()
|
||||
if paginator:
|
||||
response_schema = paginator.get_paginated_response_schema(response_schema)
|
||||
else:
|
||||
|
|
|
@ -462,6 +462,22 @@ class TestOperationIntrospection(TestCase):
|
|||
assert properties['date']['format'] == 'date'
|
||||
assert properties['datetime']['format'] == 'date-time'
|
||||
|
||||
def test_serializer_hstorefield(self):
|
||||
path = '/'
|
||||
method = 'GET'
|
||||
view = create_view(
|
||||
views.ExampleGenericAPIView,
|
||||
method,
|
||||
create_request(path),
|
||||
)
|
||||
inspector = AutoSchema()
|
||||
inspector.view = view
|
||||
|
||||
responses = inspector._get_responses(path, method)
|
||||
response_schema = responses['200']['content']['application/json']['schema']
|
||||
properties = response_schema['items']['properties']
|
||||
assert properties['hstore']['type'] == 'object'
|
||||
|
||||
def test_serializer_validators(self):
|
||||
path = '/'
|
||||
method = 'GET'
|
||||
|
|
|
@ -33,6 +33,7 @@ class ExampleDetailView(APIView):
|
|||
class ExampleSerializer(serializers.Serializer):
|
||||
date = serializers.DateField()
|
||||
datetime = serializers.DateTimeField()
|
||||
hstore = serializers.HStoreField()
|
||||
|
||||
|
||||
class ExampleGenericAPIView(generics.GenericAPIView):
|
||||
|
|
|
@ -555,7 +555,7 @@ class TestDefaultOutput:
|
|||
bar = serializers.CharField(source='foo.bar', allow_null=True)
|
||||
optional = serializers.CharField(required=False, allow_null=True)
|
||||
|
||||
# allow_null=True should imply default=None when serialising:
|
||||
# allow_null=True should imply default=None when serializing:
|
||||
assert Serializer({'foo': None}).data == {'foo': None, 'bar': None, 'optional': None, }
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user