mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-12-16 14:44:01 +03:00
Style notes using admonition in the documentation
https://python-markdown.github.io/extensions/admonition/
This commit is contained in:
parent
3a70eb2ff6
commit
1c1f1dee87
|
|
@ -34,13 +34,11 @@ If the requested view was only configured with renderers for `YAML` and `HTML`,
|
|||
|
||||
For more information on the `HTTP Accept` header, see [RFC 2616][accept-header]
|
||||
|
||||
---
|
||||
|
||||
**Note**: "q" values are not taken into account by REST framework when determining preference. The use of "q" values negatively impacts caching, and in the author's opinion they are an unnecessary and overcomplicated approach to content negotiation.
|
||||
!!! note
|
||||
"q" values are not taken into account by REST framework when determining preference. The use of "q" values negatively impacts caching, and in the author's opinion they are an unnecessary and overcomplicated approach to content negotiation.
|
||||
|
||||
This is a valid approach as the HTTP spec deliberately underspecifies how a server should weight server-based preferences against client-based preferences.
|
||||
|
||||
---
|
||||
This is a valid approach as the HTTP spec deliberately underspecifies how a server should weight server-based preferences against client-based preferences.
|
||||
|
||||
# Custom content negotiation
|
||||
|
||||
|
|
|
|||
|
|
@ -17,15 +17,12 @@ REST framework includes a number of built-in Parser classes, that allow you to a
|
|||
|
||||
The set of valid parsers for a view is always defined as a list of classes. When `request.data` is accessed, REST framework will examine the `Content-Type` header on the incoming request, and determine which parser to use to parse the request content.
|
||||
|
||||
---
|
||||
!!! note
|
||||
When developing client applications always remember to make sure you're setting the `Content-Type` header when sending data in an HTTP request.
|
||||
|
||||
**Note**: When developing client applications always remember to make sure you're setting the `Content-Type` header when sending data in an HTTP request.
|
||||
If you don't set the content type, most clients will default to using `'application/x-www-form-urlencoded'`, which may not be what you wanted.
|
||||
|
||||
If you don't set the content type, most clients will default to using `'application/x-www-form-urlencoded'`, which may not be what you wanted.
|
||||
|
||||
As an example, if you are sending `json` encoded data using jQuery with the [.ajax() method][jquery-ajax], you should make sure to include the `contentType: 'application/json'` setting.
|
||||
|
||||
---
|
||||
As an example, if you are sending `json` encoded data using jQuery with the [.ajax() method][jquery-ajax], you should make sure to include the `contentType: 'application/json'` setting.
|
||||
|
||||
## Setting the parsers
|
||||
|
||||
|
|
|
|||
|
|
@ -51,18 +51,15 @@ For example:
|
|||
self.check_object_permissions(self.request, obj)
|
||||
return obj
|
||||
|
||||
---
|
||||
!!! note
|
||||
With the exception of `DjangoObjectPermissions`, the provided
|
||||
permission classes in `rest_framework.permissions` **do not** implement the
|
||||
methods necessary to check object permissions.
|
||||
|
||||
**Note**: With the exception of `DjangoObjectPermissions`, the provided
|
||||
permission classes in `rest_framework.permissions` **do not** implement the
|
||||
methods necessary to check object permissions.
|
||||
|
||||
If you wish to use the provided permission classes in order to check object
|
||||
permissions, **you must** subclass them and implement the
|
||||
`has_object_permission()` method described in the [_Custom
|
||||
permissions_](#custom-permissions) section (below).
|
||||
|
||||
---
|
||||
If you wish to use the provided permission classes in order to check object
|
||||
permissions, **you must** subclass them and implement the
|
||||
`has_object_permission()` method described in the [_Custom
|
||||
permissions_](#custom-permissions) section (below).
|
||||
|
||||
#### Limitations of object level permissions
|
||||
|
||||
|
|
@ -118,7 +115,8 @@ Or, if you're using the `@api_view` decorator with function based views.
|
|||
}
|
||||
return Response(content)
|
||||
|
||||
__Note:__ when you set new permission classes via the class attribute or decorators you're telling the view to ignore the default list set in the __settings.py__ file.
|
||||
!!! note
|
||||
When you set new permission classes via the class attribute or decorators you're telling the view to ignore the default list set in the ``settings.py`` file.
|
||||
|
||||
Provided they inherit from `rest_framework.permissions.BasePermission`, permissions can be composed using standard Python bitwise operators. For example, `IsAuthenticatedOrReadOnly` could be written:
|
||||
|
||||
|
|
@ -131,7 +129,7 @@ Provided they inherit from `rest_framework.permissions.BasePermission`, permissi
|
|||
return request.method in SAFE_METHODS
|
||||
|
||||
class ExampleView(APIView):
|
||||
permission_classes = [IsAuthenticated|ReadOnly]
|
||||
permission_classes = [IsAuthenticated | ReadOnly]
|
||||
|
||||
def get(self, request, format=None):
|
||||
content = {
|
||||
|
|
@ -139,9 +137,8 @@ Provided they inherit from `rest_framework.permissions.BasePermission`, permissi
|
|||
}
|
||||
return Response(content)
|
||||
|
||||
__Note:__ it supports & (and), | (or) and ~ (not).
|
||||
|
||||
---
|
||||
!!! note
|
||||
Composition of permissions supports `&` (and), `|` (or) and `~` (not) operators.
|
||||
|
||||
# API Reference
|
||||
|
||||
|
|
@ -185,7 +182,7 @@ To use custom model permissions, override `DjangoModelPermissions` and set the `
|
|||
|
||||
Similar to `DjangoModelPermissions`, but also allows unauthenticated users to have read-only access to the API.
|
||||
|
||||
## DjangoObjectPermissions
|
||||
## DjangoObjectPermissions
|
||||
|
||||
This permission class ties into Django's standard [object permissions framework][objectpermissions] that allows per-object permissions on models. In order to use this permission class, you'll also need to add a permission backend that supports object-level permissions, such as [django-guardian][guardian].
|
||||
|
||||
|
|
@ -199,11 +196,8 @@ Note that `DjangoObjectPermissions` **does not** require the `django-guardian` p
|
|||
|
||||
As with `DjangoModelPermissions` you can use custom model permissions by overriding `DjangoObjectPermissions` and setting the `.perms_map` property. Refer to the source code for details.
|
||||
|
||||
---
|
||||
|
||||
**Note**: If you need object level `view` permissions for `GET`, `HEAD` and `OPTIONS` requests and are using django-guardian for your object-level permissions backend, you'll want to consider using the `DjangoObjectPermissionsFilter` class provided by the [`djangorestframework-guardian` package][django-rest-framework-guardian]. It ensures that list endpoints only return results including objects for which the user has appropriate view permissions.
|
||||
|
||||
---
|
||||
!!! note
|
||||
If you need object level `view` permissions for `GET`, `HEAD` and `OPTIONS` requests and are using django-guardian for your object-level permissions backend, you'll want to consider using the `DjangoObjectPermissionsFilter` class provided by the [`djangorestframework-guardian` package][django-rest-framework-guardian]. It ensures that list endpoints only return results including objects for which the user has appropriate view permissions.
|
||||
|
||||
# Custom permissions
|
||||
|
||||
|
|
@ -221,11 +215,8 @@ If you need to test if a request is a read operation or a write operation, you s
|
|||
else:
|
||||
# Check permissions for write request
|
||||
|
||||
---
|
||||
|
||||
**Note**: The instance-level `has_object_permission` method will only be called if the view-level `has_permission` checks have already passed. Also note that in order for the instance-level checks to run, the view code should explicitly call `.check_object_permissions(request, obj)`. If you are using the generic views then this will be handled for you by default. (Function-based views will need to check object permissions explicitly, raising `PermissionDenied` on failure.)
|
||||
|
||||
---
|
||||
!!! note
|
||||
The instance-level `has_object_permission` method will only be called if the view-level `has_permission` checks have already passed. Also note that in order for the instance-level checks to run, the view code should explicitly call `.check_object_permissions(request, obj)`. If you are using the generic views then this will be handled for you by default. (Function-based views will need to check object permissions explicitly, raising `PermissionDenied` on failure.)
|
||||
|
||||
Custom permissions will raise a `PermissionDenied` exception if the test fails. To change the error message associated with the exception, implement a `message` attribute directly on your custom permission. Otherwise the `default_detail` attribute from `PermissionDenied` will be used. Similarly, to change the code identifier associated with the exception, implement a `code` attribute directly on your custom permission - otherwise the `default_code` attribute from `PermissionDenied` will be used.
|
||||
|
||||
|
|
|
|||
|
|
@ -183,15 +183,12 @@ Would serialize to a representation like this:
|
|||
|
||||
By default this field is read-write, although you can change this behavior using the `read_only` flag.
|
||||
|
||||
---
|
||||
!!! note
|
||||
This field is designed for objects that map to a URL that accepts a single URL keyword argument, as set using the `lookup_field` and `lookup_url_kwarg` arguments.
|
||||
|
||||
**Note**: This field is designed for objects that map to a URL that accepts a single URL keyword argument, as set using the `lookup_field` and `lookup_url_kwarg` arguments.
|
||||
This is suitable for URLs that contain a single primary key or slug argument as part of the URL.
|
||||
|
||||
This is suitable for URLs that contain a single primary key or slug argument as part of the URL.
|
||||
|
||||
If you require more complex hyperlinked representation you'll need to customize the field, as described in the [custom hyperlinked fields](#custom-hyperlinked-fields) section, below.
|
||||
|
||||
---
|
||||
If you require more complex hyperlinked representation you'll need to customize the field, as described in the [custom hyperlinked fields](#custom-hyperlinked-fields) section, below.
|
||||
|
||||
**Arguments**:
|
||||
|
||||
|
|
|
|||
|
|
@ -202,13 +202,16 @@ This renderer is suitable for CRUD-style web APIs that should also present a use
|
|||
|
||||
Note that views that have nested or list serializers for their input won't work well with the `AdminRenderer`, as the HTML forms are unable to properly support them.
|
||||
|
||||
**Note**: The `AdminRenderer` is only able to include links to detail pages when a properly configured `URL_FIELD_NAME` (`url` by default) attribute is present in the data. For `HyperlinkedModelSerializer` this will be the case, but for `ModelSerializer` or plain `Serializer` classes you'll need to make sure to include the field explicitly. For example here we use models `get_absolute_url` method:
|
||||
!!! note
|
||||
The `AdminRenderer` is only able to include links to detail pages when a properly configured `URL_FIELD_NAME` (`url` by default) attribute is present in the data. For `HyperlinkedModelSerializer` this will be the case, but for `ModelSerializer` or plain `Serializer` classes you'll need to make sure to include the field explicitly.
|
||||
|
||||
class AccountSerializer(serializers.ModelSerializer):
|
||||
url = serializers.CharField(source='get_absolute_url', read_only=True)
|
||||
For example here we use models `get_absolute_url` method:
|
||||
|
||||
class Meta:
|
||||
model = Account
|
||||
class AccountSerializer(serializers.ModelSerializer):
|
||||
url = serializers.CharField(source='get_absolute_url', read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = Account
|
||||
|
||||
|
||||
**.media_type**: `text/html`
|
||||
|
|
@ -390,9 +393,8 @@ Exceptions raised and handled by an HTML renderer will attempt to render using o
|
|||
|
||||
Templates will render with a `RequestContext` which includes the `status_code` and `details` keys.
|
||||
|
||||
**Note**: If `DEBUG=True`, Django's standard traceback error page will be displayed instead of rendering the HTTP status code and text.
|
||||
|
||||
---
|
||||
!!! note
|
||||
If `DEBUG=True`, Django's standard traceback error page will be displayed instead of rendering the HTTP status code and text.
|
||||
|
||||
# Third party packages
|
||||
|
||||
|
|
|
|||
|
|
@ -40,17 +40,14 @@ The example above would generate the following URL patterns:
|
|||
* URL pattern: `^accounts/$` Name: `'account-list'`
|
||||
* URL pattern: `^accounts/{pk}/$` Name: `'account-detail'`
|
||||
|
||||
---
|
||||
!!! note
|
||||
The `basename` argument is used to specify the initial part of the view name pattern. In the example above, that's the `user` or `account` part.
|
||||
|
||||
**Note**: The `basename` argument is used to specify the initial part of the view name pattern. In the example above, that's the `user` or `account` part.
|
||||
Typically you won't *need* to specify the `basename` argument, but if you have a viewset where you've defined a custom `get_queryset` method, then the viewset may not have a `.queryset` attribute set. If you try to register that viewset you'll see an error like this:
|
||||
|
||||
Typically you won't *need* to specify the `basename` argument, but if you have a viewset where you've defined a custom `get_queryset` method, then the viewset may not have a `.queryset` attribute set. If you try to register that viewset you'll see an error like this:
|
||||
'basename' argument not specified, and could not automatically determine the name from the viewset, as it does not have a '.queryset' attribute.
|
||||
|
||||
'basename' argument not specified, and could not automatically determine the name from the viewset, as it does not have a '.queryset' attribute.
|
||||
|
||||
This means you'll need to explicitly set the `basename` argument when registering the viewset, as it could not be automatically determined from the model name.
|
||||
|
||||
---
|
||||
This means you'll need to explicitly set the `basename` argument when registering the viewset, as it could not be automatically determined from the model name.
|
||||
|
||||
### Using `include` with routers
|
||||
|
||||
|
|
@ -91,16 +88,13 @@ Or both an application and instance namespace:
|
|||
|
||||
See Django's [URL namespaces docs][url-namespace-docs] and the [`include` API reference][include-api-reference] for more details.
|
||||
|
||||
---
|
||||
|
||||
**Note**: If using namespacing with hyperlinked serializers you'll also need to ensure that any `view_name` parameters
|
||||
on the serializers correctly reflect the namespace. In the examples above you'd need to include a parameter such as
|
||||
`view_name='app_name:user-detail'` for serializer fields hyperlinked to the user detail view.
|
||||
|
||||
The automatic `view_name` generation uses a pattern like `%(model_name)-detail`. Unless your models names actually clash
|
||||
you may be better off **not** namespacing your Django REST Framework views when using hyperlinked serializers.
|
||||
|
||||
---
|
||||
!!! note
|
||||
If using namespacing with hyperlinked serializers you'll also need to ensure that any `view_name` parameters
|
||||
on the serializers correctly reflect the namespace. In the examples above you'd need to include a parameter such as
|
||||
`view_name='app_name:user-detail'` for serializer fields hyperlinked to the user detail view.
|
||||
|
||||
The automatic `view_name` generation uses a pattern like `%(model_name)-detail`. Unless your models names actually clash
|
||||
you may be better off **not** namespacing your Django REST Framework views when using hyperlinked serializers.
|
||||
|
||||
### Routing for extra actions
|
||||
|
||||
|
|
|
|||
|
|
@ -238,15 +238,12 @@ operation = auto_schema.get_operation(...)
|
|||
In compiling the schema, `SchemaGenerator` calls `get_components()` and
|
||||
`get_operation()` for each view, allowed method, and path.
|
||||
|
||||
----
|
||||
|
||||
**Note**: The automatic introspection of components, and many operation
|
||||
parameters relies on the relevant attributes and methods of
|
||||
`GenericAPIView`: `get_serializer()`, `pagination_class`, `filter_backends`,
|
||||
etc. For basic `APIView` subclasses, default introspection is essentially limited to
|
||||
the URL kwarg path parameters for this reason.
|
||||
|
||||
----
|
||||
!!! note
|
||||
The automatic introspection of components, and many operation
|
||||
parameters relies on the relevant attributes and methods of
|
||||
`GenericAPIView`: `get_serializer()`, `pagination_class`, `filter_backends`,
|
||||
etc. For basic `APIView` subclasses, default introspection is essentially limited to
|
||||
the URL kwarg path parameters for this reason.
|
||||
|
||||
`AutoSchema` encapsulates the view introspection needed for schema generation.
|
||||
Because of this all the schema generation logic is kept in a single place,
|
||||
|
|
|
|||
|
|
@ -542,20 +542,16 @@ This option should be a list or tuple of field names, and is declared as follows
|
|||
|
||||
Model fields which have `editable=False` set, and `AutoField` fields will be set to read-only by default, and do not need to be added to the `read_only_fields` option.
|
||||
|
||||
---
|
||||
!!! note
|
||||
There is a special-case where a read-only field is part of a `unique_together` constraint at the model level. In this case the field is required by the serializer class in order to validate the constraint, but should also not be editable by the user.
|
||||
|
||||
**Note**: There is a special-case where a read-only field is part of a `unique_together` constraint at the model level. In this case the field is required by the serializer class in order to validate the constraint, but should also not be editable by the user.
|
||||
The right way to deal with this is to specify the field explicitly on the serializer, providing both the `read_only=True` and `default=…` keyword arguments.
|
||||
|
||||
The right way to deal with this is to specify the field explicitly on the serializer, providing both the `read_only=True` and `default=…` keyword arguments.
|
||||
One example of this is a read-only relation to the currently authenticated `User` which is `unique_together` with another identifier. In this case you would declare the user field like so:
|
||||
|
||||
One example of this is a read-only relation to the currently authenticated `User` which is `unique_together` with another identifier. In this case you would declare the user field like so:
|
||||
|
||||
user = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault())
|
||||
|
||||
Please review the [Validators Documentation](/api-guide/validators/) for details on the [UniqueTogetherValidator](/api-guide/validators/#uniquetogethervalidator) and [CurrentUserDefault](/api-guide/validators/#currentuserdefault) classes.
|
||||
|
||||
---
|
||||
user = serializers.PrimaryKeyRelatedField(read_only=True, default=serializers.CurrentUserDefault())
|
||||
|
||||
Please review the [Validators Documentation](/api-guide/validators/) for details on the [UniqueTogetherValidator](/api-guide/validators/#uniquetogethervalidator) and [CurrentUserDefault](/api-guide/validators/#currentuserdefault) classes.
|
||||
|
||||
## Additional keyword arguments
|
||||
|
||||
|
|
|
|||
|
|
@ -90,36 +90,32 @@ For example, when forcibly authenticating using a token, you might do something
|
|||
request = factory.get('/accounts/django-superstars/')
|
||||
force_authenticate(request, user=user, token=user.auth_token)
|
||||
|
||||
---
|
||||
!!! note
|
||||
`force_authenticate` directly sets `request.user` to the in-memory `user` instance. If you are reusing the same `user` instance across multiple tests that update the saved `user` state, you may need to call [`refresh_from_db()`][refresh_from_db_docs] between tests.
|
||||
|
||||
**Note**: `force_authenticate` directly sets `request.user` to the in-memory `user` instance. If you are reusing the same `user` instance across multiple tests that update the saved `user` state, you may need to call [`refresh_from_db()`][refresh_from_db_docs] between tests.
|
||||
!!! note
|
||||
When using `APIRequestFactory`, the object that is returned is Django's standard `HttpRequest`, and not REST framework's `Request` object, which is only generated once the view is called.
|
||||
|
||||
---
|
||||
|
||||
**Note**: When using `APIRequestFactory`, the object that is returned is Django's standard `HttpRequest`, and not REST framework's `Request` object, which is only generated once the view is called.
|
||||
|
||||
This means that setting attributes directly on the request object may not always have the effect you expect. For example, setting `.token` directly will have no effect, and setting `.user` directly will only work if session authentication is being used.
|
||||
|
||||
# Request will only authenticate if `SessionAuthentication` is in use.
|
||||
request = factory.get('/accounts/django-superstars/')
|
||||
request.user = user
|
||||
response = view(request)
|
||||
|
||||
If you want to test a request involving the REST framework’s 'Request' object, you’ll need to manually transform it first:
|
||||
|
||||
class DummyView(APIView):
|
||||
...
|
||||
|
||||
factory = APIRequestFactory()
|
||||
request = factory.get('/', {'demo': 'test'})
|
||||
drf_request = DummyView().initialize_request(request)
|
||||
assert drf_request.query_params == {'demo': ['test']}
|
||||
|
||||
request = factory.post('/', {'example': 'test'})
|
||||
drf_request = DummyView().initialize_request(request)
|
||||
assert drf_request.data.get('example') == 'test'
|
||||
|
||||
---
|
||||
This means that setting attributes directly on the request object may not always have the effect you expect. For example, setting `.token` directly will have no effect, and setting `.user` directly will only work if session authentication is being used.
|
||||
|
||||
# Request will only authenticate if `SessionAuthentication` is in use.
|
||||
request = factory.get('/accounts/django-superstars/')
|
||||
request.user = user
|
||||
response = view(request)
|
||||
|
||||
If you want to test a request involving the REST framework’s 'Request' object, you’ll need to manually transform it first:
|
||||
|
||||
class DummyView(APIView):
|
||||
...
|
||||
|
||||
factory = APIRequestFactory()
|
||||
request = factory.get('/', {'demo': 'test'})
|
||||
drf_request = DummyView().initialize_request(request)
|
||||
assert drf_request.query_params == {'demo': ['test']}
|
||||
|
||||
request = factory.post('/', {'example': 'test'})
|
||||
drf_request = DummyView().initialize_request(request)
|
||||
assert drf_request.data.get('example') == 'test'
|
||||
|
||||
## Forcing CSRF validation
|
||||
|
||||
|
|
@ -127,11 +123,8 @@ By default, requests created with `APIRequestFactory` will not have CSRF validat
|
|||
|
||||
factory = APIRequestFactory(enforce_csrf_checks=True)
|
||||
|
||||
---
|
||||
|
||||
**Note**: It's worth noting that Django's standard `RequestFactory` doesn't need to include this option, because when using regular Django the CSRF validation takes place in middleware, which is not run when testing views directly. When using REST framework, CSRF validation takes place inside the view, so the request factory needs to disable view-level CSRF checks.
|
||||
|
||||
---
|
||||
!!! note
|
||||
It's worth noting that Django's standard `RequestFactory` doesn't need to include this option, because when using regular Django the CSRF validation takes place in middleware, which is not run when testing views directly. When using REST framework, CSRF validation takes place inside the view, so the request factory needs to disable view-level CSRF checks.
|
||||
|
||||
# APIClient
|
||||
|
||||
|
|
|
|||
|
|
@ -101,11 +101,8 @@ The validator should be applied to *serializer classes*, like so:
|
|||
)
|
||||
]
|
||||
|
||||
---
|
||||
|
||||
**Note**: The `UniqueTogetherValidator` class always imposes an implicit constraint that all the fields it applies to are always treated as required. Fields with `default` values are an exception to this as they always supply a value even when omitted from user input.
|
||||
|
||||
---
|
||||
!!! note
|
||||
The `UniqueTogetherValidator` class always imposes an implicit constraint that all the fields it applies to are always treated as required. Fields with `default` values are an exception to this as they always supply a value even when omitted from user input.
|
||||
|
||||
## UniqueForDateValidator
|
||||
|
||||
|
|
@ -158,17 +155,11 @@ If you want the date field to be entirely hidden from the user, then use `Hidden
|
|||
|
||||
published = serializers.HiddenField(default=timezone.now)
|
||||
|
||||
---
|
||||
!!! note
|
||||
The `UniqueFor<Range>Validator` classes impose an implicit constraint that the fields they are applied to are always treated as required. Fields with `default` values are an exception to this as they always supply a value even when omitted from user input.
|
||||
|
||||
**Note**: The `UniqueFor<Range>Validator` classes impose an implicit constraint that the fields they are applied to are always treated as required. Fields with `default` values are an exception to this as they always supply a value even when omitted from user input.
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
**Note:** `HiddenField()` does not appear in `partial=True` serializer (when making `PATCH` request).
|
||||
|
||||
---
|
||||
!!! note
|
||||
`HiddenField()` does not appear in `partial=True` serializer (when making `PATCH` request).
|
||||
|
||||
# Advanced field defaults
|
||||
|
||||
|
|
|
|||
|
|
@ -45,11 +45,8 @@ For example:
|
|||
usernames = [user.username for user in User.objects.all()]
|
||||
return Response(usernames)
|
||||
|
||||
---
|
||||
|
||||
**Note**: The full methods, attributes on, and relations between Django REST Framework's `APIView`, `GenericAPIView`, various `Mixins`, and `Viewsets` can be initially complex. In addition to the documentation here, the [Classy Django REST Framework][classy-drf] resource provides a browsable reference, with full methods and attributes, for each of Django REST Framework's class-based views.
|
||||
|
||||
---
|
||||
!!! note
|
||||
The full methods, attributes on, and relations between Django REST Framework's `APIView`, `GenericAPIView`, various `Mixins`, and `Viewsets` can be initially complex. In addition to the documentation here, the [Classy Django REST Framework][classy-drf] resource provides a browsable reference, with full methods and attributes, for each of Django REST Framework's class-based views.
|
||||
|
||||
|
||||
## API policy attributes
|
||||
|
|
|
|||
|
|
@ -131,7 +131,8 @@ You may inspect these attributes to adjust behavior based on the current action.
|
|||
permission_classes = [IsAdminUser]
|
||||
return [permission() for permission in permission_classes]
|
||||
|
||||
**Note**: the `action` attribute is not available in the `get_parsers`, `get_authenticators` and `get_content_negotiator` methods, as it is set _after_ they are called in the framework lifecycle. If you override one of these methods and try to access the `action` attribute in them, you will get an `AttributeError` error.
|
||||
!!! note
|
||||
The `action` attribute is not available in the `get_parsers`, `get_authenticators` and `get_content_negotiator` methods, as it is set _after_ they are called in the framework lifecycle. If you override one of these methods and try to access the `action` attribute in them, you will get an `AttributeError` error.
|
||||
|
||||
## Marking extra actions for routing
|
||||
|
||||
|
|
|
|||
|
|
@ -6,11 +6,8 @@ This tutorial will cover creating a simple pastebin code highlighting Web API.
|
|||
|
||||
The tutorial is fairly in-depth, so you should probably get a cookie and a cup of your favorite brew before getting started. If you just want a quick overview, you should head over to the [quickstart] documentation instead.
|
||||
|
||||
---
|
||||
|
||||
**Note**: The code for this tutorial is available in the [encode/rest-framework-tutorial][repo] repository on GitHub. Feel free to clone the repository and see the code in action.
|
||||
|
||||
---
|
||||
!!! note
|
||||
The code for this tutorial is available in the [encode/rest-framework-tutorial][repo] repository on GitHub. Feel free to clone the repository and see the code in action.
|
||||
|
||||
## Setting up a new environment
|
||||
|
||||
|
|
|
|||
|
|
@ -135,7 +135,8 @@ Now that snippets are associated with the user that created them, let's update o
|
|||
owner = serializers.ReadOnlyField(source="owner.username")
|
||||
```
|
||||
|
||||
**Note**: Make sure you also add `'owner',` to the list of fields in the inner `Meta` class.
|
||||
!!! note
|
||||
Make sure you also add `'owner',` to the list of fields in the inner `Meta` class.
|
||||
|
||||
This field is doing something quite interesting. The `source` argument controls which attribute is used to populate a field, and can point at any attribute on the serialized instance. It can also take the dotted notation shown above, in which case it will traverse the given attributes, in a similar way as it is used with Django's template language.
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user