Skip to content

Commit 43f411c

Browse files
committed
Handle more notes and add "Tip" admonition styles
1 parent 1c1f1de commit 43f411c

File tree

13 files changed

+107
-150
lines changed

13 files changed

+107
-150
lines changed

docs/api-guide/authentication.md

Lines changed: 12 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,10 @@ The `request.user` property will typically be set to an instance of the `contrib
1919

2020
The `request.auth` property is used for any additional authentication information, for example, it may be used to represent an authentication token that the request was signed with.
2121

22-
---
23-
24-
**Note:** Don't forget that **authentication by itself won't allow or disallow an incoming request**, it simply identifies the credentials that the request was made with.
22+
!!! note
23+
Don't forget that **authentication by itself won't allow or disallow an incoming request**, it simply identifies the credentials that the request was made with.
2524

26-
For information on how to set up the permission policies for your API please see the [permissions documentation][permission].
27-
28-
---
25+
For information on how to set up the permission policies for your API please see the [permissions documentation][permission].
2926

3027
## How authentication is determined
3128

@@ -122,17 +119,15 @@ Unauthenticated responses that are denied permission will result in an `HTTP 401
122119

123120
WWW-Authenticate: Basic realm="api"
124121

125-
**Note:** If you use `BasicAuthentication` in production you must ensure that your API is only available over `https`. You should also ensure that your API clients will always re-request the username and password at login, and will never store those details to persistent storage.
122+
!!! note
123+
If you use `BasicAuthentication` in production you must ensure that your API is only available over `https`. You should also ensure that your API clients will always re-request the username and password at login, and will never store those details to persistent storage.
126124

127125
## TokenAuthentication
128126

129-
---
130-
131-
**Note:** The token authentication provided by Django REST framework is a fairly simple implementation.
127+
!!! note
128+
The token authentication provided by Django REST framework is a fairly simple implementation.
132129

133-
For an implementation which allows more than one token per user, has some tighter security implementation details, and supports token expiry, please see the [Django REST Knox][django-rest-knox] third party package.
134-
135-
---
130+
For an implementation which allows more than one token per user, has some tighter security implementation details, and supports token expiry, please see the [Django REST Knox][django-rest-knox] third party package.
136131

137132
This authentication scheme uses a simple token-based HTTP Authentication scheme. Token authentication is appropriate for client-server setups, such as native desktop and mobile clients.
138133

@@ -173,11 +168,8 @@ The `curl` command line tool may be useful for testing token authenticated APIs.
173168

174169
curl -X GET http://127.0.0.1:8000/api/example/ -H 'Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b'
175170

176-
---
177-
178-
**Note:** If you use `TokenAuthentication` in production you must ensure that your API is only available over `https`.
179-
180-
---
171+
!!! note
172+
If you use `TokenAuthentication` in production you must ensure that your API is only available over `https`.
181173

182174
### Generating Tokens
183175

@@ -335,11 +327,8 @@ You *may* also override the `.authenticate_header(self, request)` method. If im
335327

336328
If the `.authenticate_header()` method is not overridden, the authentication scheme will return `HTTP 403 Forbidden` responses when an unauthenticated request is denied access.
337329

338-
---
339-
340-
**Note:** When your custom authenticator is invoked by the request object's `.user` or `.auth` properties, you may see an `AttributeError` re-raised as a `WrappedAttributeError`. This is necessary to prevent the original exception from being suppressed by the outer property access. Python will not recognize that the `AttributeError` originates from your custom authenticator and will instead assume that the request object does not have a `.user` or `.auth` property. These errors should be fixed or otherwise handled by your authenticator.
341-
342-
---
330+
!!! note
331+
When your custom authenticator is invoked by the request object's `.user` or `.auth` properties, you may see an `AttributeError` re-raised as a `WrappedAttributeError`. This is necessary to prevent the original exception from being suppressed by the outer property access. Python will not recognize that the `AttributeError` originates from your custom authenticator and will instead assume that the request object does not have a `.user` or `.auth` property. These errors should be fixed or otherwise handled by your authenticator.
343332

344333
## Example
345334

docs/api-guide/caching.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ def get_user_list(request):
8282
```
8383

8484

85-
**NOTE:** The [`cache_page`][page] decorator only caches the
86-
`GET` and `HEAD` responses with status 200.
85+
!!! note
86+
The [`cache_page`][page] decorator only caches the `GET` and `HEAD` responses with status 200.
8787

8888
[page]: https://docs.djangoproject.com/en/stable/topics/cache/#the-per-view-cache
8989
[cookie]: https://docs.djangoproject.com/en/stable/topics/http/decorators/#django.views.decorators.vary.vary_on_cookie

docs/api-guide/fields.md

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,8 @@ source:
1111
1212
Serializer fields handle converting between primitive values and internal datatypes. They also deal with validating input values, as well as retrieving and setting the values from their parent objects.
1313

14-
---
15-
16-
**Note:** The serializer fields are declared in `fields.py`, but by convention you should import them using `from rest_framework import serializers` and refer to fields as `serializers.<FieldName>`.
17-
18-
---
14+
!!! note
15+
The serializer fields are declared in `fields.py`, but by convention you should import them using `from rest_framework import serializers` and refer to fields as `serializers.<FieldName>`.
1916

2017
## Core arguments
2118

@@ -565,11 +562,8 @@ The `HiddenField` class is usually only needed if you have some validation that
565562

566563
For further examples on `HiddenField` see the [validators](validators.md) documentation.
567564

568-
---
569-
570-
**Note:** `HiddenField()` does not appear in `partial=True` serializer (when making `PATCH` request).
571-
572-
---
565+
!!! note
566+
`HiddenField()` does not appear in `partial=True` serializer (when making `PATCH` request).
573567

574568
## ModelField
575569

docs/api-guide/generic-views.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,11 +96,8 @@ For example:
9696
user = self.request.user
9797
return user.accounts.all()
9898

99-
---
100-
101-
**Note:** If the `serializer_class` used in the generic view spans orm relations, leading to an n+1 problem, you could optimize your queryset in this method using `select_related` and `prefetch_related`. To get more information about n+1 problem and use cases of the mentioned methods refer to related section in [django documentation][django-docs-select-related].
102-
103-
---
99+
!!! note
100+
If the `serializer_class` used in the generic view spans orm relations, leading to an n+1 problem, you could optimize your queryset in this method using `select_related` and `prefetch_related`. To get more information about n+1 problem and use cases of the mentioned methods refer to related section in [django documentation][django-docs-select-related].
104101

105102
### Avoiding N+1 Queries
106103

docs/api-guide/relations.md

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -11,42 +11,36 @@ source:
1111
1212
Relational fields are used to represent model relationships. They can be applied to `ForeignKey`, `ManyToManyField` and `OneToOneField` relationships, as well as to reverse relationships, and custom relationships such as `GenericForeignKey`.
1313

14-
---
15-
16-
**Note:** The relational fields are declared in `relations.py`, but by convention you should import them from the `serializers` module, using `from rest_framework import serializers` and refer to fields as `serializers.<FieldName>`.
17-
18-
---
19-
20-
---
21-
22-
**Note:** REST Framework does not attempt to automatically optimize querysets passed to serializers in terms of `select_related` and `prefetch_related` since it would be too much magic. A serializer with a field spanning an orm relation through its source attribute could require an additional database hit to fetch related objects from the database. It is the programmer's responsibility to optimize queries to avoid additional database hits which could occur while using such a serializer.
23-
24-
For example, the following serializer would lead to a database hit each time evaluating the tracks field if it is not prefetched:
25-
26-
class AlbumSerializer(serializers.ModelSerializer):
27-
tracks = serializers.SlugRelatedField(
28-
many=True,
29-
read_only=True,
30-
slug_field='title'
31-
)
32-
33-
class Meta:
34-
model = Album
35-
fields = ['album_name', 'artist', 'tracks']
36-
37-
# For each album object, tracks should be fetched from database
38-
qs = Album.objects.all()
39-
print(AlbumSerializer(qs, many=True).data)
40-
41-
If `AlbumSerializer` is used to serialize a fairly large queryset with `many=True` then it could be a serious performance problem. Optimizing the queryset passed to `AlbumSerializer` with:
42-
43-
qs = Album.objects.prefetch_related('tracks')
44-
# No additional database hits required
45-
print(AlbumSerializer(qs, many=True).data)
46-
47-
would solve the issue.
14+
!!! note
15+
The relational fields are declared in `relations.py`, but by convention you should import them from the `serializers` module, using `from rest_framework import serializers` and refer to fields as `serializers.<FieldName>`.
4816

49-
---
17+
!!! note
18+
REST Framework does not attempt to automatically optimize querysets passed to serializers in terms of `select_related` and `prefetch_related` since it would be too much magic. A serializer with a field spanning an orm relation through its source attribute could require an additional database hit to fetch related objects from the database. It is the programmer's responsibility to optimize queries to avoid additional database hits which could occur while using such a serializer.
19+
20+
For example, the following serializer would lead to a database hit each time evaluating the tracks field if it is not prefetched:
21+
22+
class AlbumSerializer(serializers.ModelSerializer):
23+
tracks = serializers.SlugRelatedField(
24+
many=True,
25+
read_only=True,
26+
slug_field='title'
27+
)
28+
29+
class Meta:
30+
model = Album
31+
fields = ['album_name', 'artist', 'tracks']
32+
33+
# For each album object, tracks should be fetched from database
34+
qs = Album.objects.all()
35+
print(AlbumSerializer(qs, many=True).data)
36+
37+
If `AlbumSerializer` is used to serialize a fairly large queryset with `many=True` then it could be a serious performance problem. Optimizing the queryset passed to `AlbumSerializer` with:
38+
39+
qs = Album.objects.prefetch_related('tracks')
40+
# No additional database hits required
41+
print(AlbumSerializer(qs, many=True).data)
42+
43+
would solve the issue.
5044

5145
#### Inspecting relationships.
5246

docs/api-guide/renderers.md

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,10 @@ Unlike other renderers, the data passed to the `Response` does not need to be se
103103

104104
The TemplateHTMLRenderer will create a `RequestContext`, using the `response.data` as the context dict, and determine a template name to use to render the context.
105105

106-
---
107-
108-
**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:
109-
110-
```
111-
response.data = {'results': response.data}
112-
```
106+
!!! note
107+
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:
113108

114-
---
109+
response.data = {'results': response.data}
115110

116111
The template name is determined by (in order of preference):
117112

docs/api-guide/requests.md

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,10 @@ The `APIView` class or `@api_view` decorator will ensure that this property is a
3939

4040
You won't typically need to access this property.
4141

42-
---
43-
44-
**Note:** If a client sends malformed content, then accessing `request.data` may raise a `ParseError`. By default REST framework's `APIView` class or `@api_view` decorator will catch the error and return a `400 Bad Request` response.
42+
!!! note
43+
If a client sends malformed content, then accessing `request.data` may raise a `ParseError`. By default REST framework's `APIView` class or `@api_view` decorator will catch the error and return a `400 Bad Request` response.
4544

46-
If a client sends a request with a content-type that cannot be parsed then a `UnsupportedMediaType` exception will be raised, which by default will be caught and return a `415 Unsupported Media Type` response.
47-
48-
---
45+
If a client sends a request with a content-type that cannot be parsed then a `UnsupportedMediaType` exception will be raised, which by default will be caught and return a `415 Unsupported Media Type` response.
4946

5047
# Content negotiation
5148

@@ -91,11 +88,8 @@ The `APIView` class or `@api_view` decorator will ensure that this property is a
9188

9289
You won't typically need to access this property.
9390

94-
---
95-
96-
**Note:** You may see a `WrappedAttributeError` raised when calling the `.user` or `.auth` properties. These errors originate from an authenticator as a standard `AttributeError`, however it's necessary that they be re-raised as a different exception type in order to prevent them from being suppressed by the outer property access. Python will not recognize that the `AttributeError` originates from the authenticator and will instead assume that the request object does not have a `.user` or `.auth` property. The authenticator will need to be fixed.
97-
98-
---
91+
!!! note
92+
You may see a `WrappedAttributeError` raised when calling the `.user` or `.auth` properties. These errors originate from an authenticator as a standard `AttributeError`, however it's necessary that they be re-raised as a different exception type in order to prevent them from being suppressed by the outer property access. Python will not recognize that the `AttributeError` originates from the authenticator and will instead assume that the request object does not have a `.user` or `.auth` property. The authenticator will need to be fixed.
9993

10094
# Browser enhancements
10195

docs/api-guide/serializers.md

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -192,11 +192,8 @@ Your `validate_<field_name>` methods should return the validated value or raise
192192
raise serializers.ValidationError("Blog post is not about Django")
193193
return value
194194

195-
---
196-
197-
**Note:** If your `<field_name>` is declared on your serializer with the parameter `required=False` then this validation step will not take place if the field is not included.
198-
199-
---
195+
!!! note
196+
If your `<field_name>` is declared on your serializer with the parameter `required=False` then this validation step will not take place if the field is not included.
200197

201198
#### Object-level validation
202199

docs/api-guide/validators.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ If you want the date field to be entirely hidden from the user, then use `Hidden
166166
Validators that are applied across multiple fields in the serializer can sometimes require a field input that should not be provided by the API client, but that *is* available as input to the validator.
167167
For this purposes use `HiddenField`. This field will be present in `validated_data` but *will not* be used in the serializer output representation.
168168

169-
**Note:** Using a `read_only=True` field is excluded from writable fields so it won't use a `default=…` argument. Look [3.8 announcement](https://www.django-rest-framework.org/community/3.8-announcement/#altered-the-behavior-of-read_only-plus-default-on-field).
169+
!!! note
170+
Using a `read_only=True` field is excluded from writable fields so it won't use a `default=…` argument. Look [3.8 announcement](https://www.django-rest-framework.org/community/3.8-announcement/#altered-the-behavior-of-read_only-plus-default-on-field).
170171

171172
REST framework includes a couple of defaults that may be useful in this context.
172173

docs/community/contributing.md

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -81,32 +81,29 @@ To run the tests, clone the repository, and then:
8181
# Run the tests
8282
./runtests.py
8383

84-
---
85-
86-
**Note:** if your tests require access to the database, do not forget to inherit from `django.test.TestCase` or use the `@pytest.mark.django_db()` decorator.
87-
88-
For example, with TestCase:
89-
90-
from django.test import TestCase
91-
92-
class MyDatabaseTest(TestCase):
93-
def test_something(self):
94-
# Your test code here
95-
pass
96-
97-
Or with decorator:
98-
99-
import pytest
100-
101-
@pytest.mark.django_db()
102-
class MyDatabaseTest:
103-
def test_something(self):
104-
# Your test code here
105-
pass
106-
107-
You can reuse existing models defined in `tests/models.py` for your tests.
108-
109-
---
84+
!!! tip
85+
If your tests require access to the database, do not forget to inherit from `django.test.TestCase` or use the `@pytest.mark.django_db()` decorator.
86+
87+
For example, with TestCase:
88+
89+
from django.test import TestCase
90+
91+
class MyDatabaseTest(TestCase):
92+
def test_something(self):
93+
# Your test code here
94+
pass
95+
96+
Or with decorator:
97+
98+
import pytest
99+
100+
@pytest.mark.django_db()
101+
class MyDatabaseTest:
102+
def test_something(self):
103+
# Your test code here
104+
pass
105+
106+
You can reuse existing models defined in `tests/models.py` for your tests.
110107

111108
### Test options
112109

@@ -133,7 +130,8 @@ Shorter form to run the tests for a given test method.
133130
./runtests.py test_this_method
134131

135132

136-
Note: The test case and test method matching is fuzzy and will sometimes run other tests that contain a partial string match to the given command line input.
133+
!!! note
134+
The test case and test method matching is fuzzy and will sometimes run other tests that contain a partial string match to the given command line input.
137135

138136
### Running against multiple environments
139137

@@ -225,13 +223,12 @@ Linking in this style means you'll be able to click the hyperlink in your Markdo
225223

226224
##### 3. Notes
227225

228-
If you want to draw attention to a note or warning, use a pair of enclosing lines, like so:
229-
230-
---
226+
If you want to draw attention to a note or warning, use an [admonition], like so:
231227

232-
**Note:** A useful documentation note.
228+
!!! note
229+
A useful documentation note.
233230

234-
---
231+
The documentation theme styles `info`, `warning`, `tip` and `danger` admonition types, but more could be added if the need arise.
235232

236233

237234
[cite]: https://www.w3.org/People/Berners-Lee/FAQ.html
@@ -247,3 +244,4 @@ If you want to draw attention to a note or warning, use a pair of enclosing line
247244
[mou]: http://mouapp.com/
248245
[repo]: https://github.com/encode/django-rest-framework
249246
[how-to-fork]: https://help.github.com/articles/fork-a-repo/
247+
[admonition]: https://python-markdown.github.io/extensions/admonition/

0 commit comments

Comments
 (0)