Skip to content

Commit 456a1fe

Browse files
Merge branch 'encode:master' into add-max-page-setting-for-pagination
2 parents 40735f2 + f113ab6 commit 456a1fe

File tree

106 files changed

+1730
-1983
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

106 files changed

+1730
-1983
lines changed

.github/ISSUE_TEMPLATE/1-issue.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ about: Please only raise an issue if you've been advised to do so after discussi
55

66
## Checklist
77

8+
<!--
9+
Note: REST framework is considered feature-complete. New functionality should be implemented outside the core REST framework. For details, please check the docs: https://www.django-rest-framework.org/community/third-party-packages/#about-third-party-packages
10+
-->
11+
812
- [ ] Raised initially as discussion #...
9-
- [ ] This cannot be dealt with as a third party library. (We prefer new functionality to be [in the form of third party libraries](https://www.django-rest-framework.org/community/third-party-packages/#about-third-party-packages) where possible.)
13+
- [ ] This is not a feature request suitable for implementation outside this project. Please elaborate what it is:
14+
- [ ] compatibility fix for new Django/Python version ...
15+
- [ ] other type of bug fix
16+
- [ ] other type of improvement that does not touch existing code or change existing behavior (e.g. wrapper for new Django field)
1017
- [ ] I have reduced the issue to the simplest possible case.

.github/dependabot.yml

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Keep GitHub Actions up to date with GitHub's Dependabot...
2+
# https://docs.github.com/en/code-security/dependabot/working-with-dependabot/keeping-your-actions-up-to-date-with-dependabot
3+
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#package-ecosystem
4+
version: 2
5+
updates:
6+
- package-ecosystem: github-actions
7+
directory: /
8+
groups:
9+
github-actions:
10+
patterns:
11+
- "*" # Group all Action updates into a single larger pull request
12+
schedule:
13+
interval: weekly

.github/workflows/main.yml

+4-14
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,16 @@ jobs:
1414
strategy:
1515
matrix:
1616
python-version:
17-
- '3.6'
18-
- '3.7'
1917
- '3.8'
2018
- '3.9'
2119
- '3.10'
2220
- '3.11'
21+
- '3.12'
2322

2423
steps:
2524
- uses: actions/checkout@v4
2625

27-
- uses: actions/setup-python@v4
26+
- uses: actions/setup-python@v5
2827
with:
2928
python-version: ${{ matrix.python-version }}
3029
cache: 'pip'
@@ -36,18 +35,9 @@ jobs:
3635
- name: Install dependencies
3736
run: python -m pip install --upgrade codecov tox
3837

39-
- name: Install tox-py
40-
if: ${{ matrix.python-version == '3.6' }}
41-
run: python -m pip install --upgrade tox-py
42-
4338
- name: Run tox targets for ${{ matrix.python-version }}
44-
if: ${{ matrix.python-version != '3.6' }}
4539
run: tox run -f py$(echo ${{ matrix.python-version }} | tr -d .)
4640

47-
- name: Run tox targets for ${{ matrix.python-version }}
48-
if: ${{ matrix.python-version == '3.6' }}
49-
run: tox --py current
50-
5141
- name: Run extra tox targets
5242
if: ${{ matrix.python-version == '3.9' }}
5343
run: |
@@ -61,9 +51,9 @@ jobs:
6151
name: Test documentation links
6252
runs-on: ubuntu-22.04
6353
steps:
64-
- uses: actions/checkout@v3
54+
- uses: actions/checkout@v4
6555

66-
- uses: actions/setup-python@v4
56+
- uses: actions/setup-python@v5
6757
with:
6858
python-version: '3.9'
6959

.github/workflows/pre-commit.yml

+3-5
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,12 @@ jobs:
1111
runs-on: ubuntu-latest
1212

1313
steps:
14-
- uses: actions/checkout@v3
14+
- uses: actions/checkout@v4
1515
with:
1616
fetch-depth: 0
1717

18-
- uses: actions/setup-python@v4
18+
- uses: actions/setup-python@v5
1919
with:
2020
python-version: "3.10"
2121

22-
- uses: pre-commit/[email protected]
23-
with:
24-
token: ${{ secrets.GITHUB_TOKEN }}
22+
- uses: pre-commit/[email protected]

.pre-commit-config.yaml

+16-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
repos:
22
- repo: https://github.com/pre-commit/pre-commit-hooks
3-
rev: v3.4.0
3+
rev: v4.5.0
44
hooks:
55
- id: check-added-large-files
66
- id: check-case-conflict
@@ -9,12 +9,25 @@ repos:
99
- id: check-symlinks
1010
- id: check-toml
1111
- repo: https://github.com/pycqa/isort
12-
rev: 5.12.0
12+
rev: 5.13.2
1313
hooks:
1414
- id: isort
1515
- repo: https://github.com/PyCQA/flake8
16-
rev: 3.9.0
16+
rev: 7.0.0
1717
hooks:
1818
- id: flake8
1919
additional_dependencies:
2020
- flake8-tidy-imports
21+
- repo: https://github.com/adamchainz/blacken-docs
22+
rev: 1.16.0
23+
hooks:
24+
- id: blacken-docs
25+
exclude: ^(?!docs).*$
26+
additional_dependencies:
27+
- black==23.1.0
28+
- repo: https://github.com/codespell-project/codespell
29+
# Configuration for codespell is in .codespellrc
30+
rev: v2.2.6
31+
hooks:
32+
- id: codespell
33+
exclude: locale|kickstarter-announcement.md|coreapi-0.1.1.js

PULL_REQUEST_TEMPLATE.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
*Note*: Before submitting this pull request, please review our [contributing guidelines](https://www.django-rest-framework.org/community/contributing/#pull-requests).
1+
*Note*: Before submitting a code change, please review our [contributing guidelines](https://www.django-rest-framework.org/community/contributing/#pull-requests).
22

33
## Description
44

README.md

+10-10
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@ The initial aim is to provide a single full-time position on REST framework.
2727
[![][posthog-img]][posthog-url]
2828
[![][cryptapi-img]][cryptapi-url]
2929
[![][fezto-img]][fezto-url]
30+
[![][svix-img]][svix-url]
31+
[![][zuplo-img]][zuplo-url]
3032

31-
Many thanks to all our [wonderful sponsors][sponsors], and in particular to our premium backers, [Sentry][sentry-url], [Stream][stream-url], [Spacinov][spacinov-url], [Retool][retool-url], [bit.io][bitio-url], [PostHog][posthog-url], [CryptAPI][cryptapi-url], and [FEZTO][fezto-url].
33+
Many thanks to all our [wonderful sponsors][sponsors], and in particular to our premium backers, [Sentry][sentry-url], [Stream][stream-url], [Spacinov][spacinov-url], [Retool][retool-url], [bit.io][bitio-url], [PostHog][posthog-url], [CryptAPI][cryptapi-url], [FEZTO][fezto-url], [Svix][svix-url], and [Zuplo][zuplo-url].
3234

3335
---
3436

@@ -38,14 +40,12 @@ Django REST framework is a powerful and flexible toolkit for building Web APIs.
3840

3941
Some reasons you might want to use REST framework:
4042

41-
* The [Web browsable API][sandbox] is a huge usability win for your developers.
43+
* The Web browsable API is a huge usability win for your developers.
4244
* [Authentication policies][authentication] including optional packages for [OAuth1a][oauth1-section] and [OAuth2][oauth2-section].
4345
* [Serialization][serializers] that supports both [ORM][modelserializer-section] and [non-ORM][serializer-section] data sources.
4446
* Customizable all the way down - just use [regular function-based views][functionview-section] if you don't need the [more][generic-views] [powerful][viewsets] [features][routers].
4547
* [Extensive documentation][docs], and [great community support][group].
4648

47-
There is a live example API for testing purposes, [available here][sandbox].
48-
4949
**Below**: *Screenshot from the browsable API*
5050

5151
![Screenshot][image]
@@ -54,8 +54,8 @@ There is a live example API for testing purposes, [available here][sandbox].
5454

5555
# Requirements
5656

57-
* Python 3.6+
58-
* Django 4.2, 4.1, 4.0, 3.2, 3.1, 3.0
57+
* Python 3.8+
58+
* Django 5.0, 4.2
5959

6060
We **highly recommend** and only officially support the latest patch release of
6161
each Python and Django series.
@@ -173,8 +173,6 @@ Full documentation for the project is available at [https://www.django-rest-fram
173173

174174
For questions and support, use the [REST framework discussion group][group], or `#restframework` on libera.chat IRC.
175175

176-
You may also want to [follow the author on Twitter][twitter].
177-
178176
# Security
179177

180178
Please see the [security policy][security-policy].
@@ -185,9 +183,7 @@ Please see the [security policy][security-policy].
185183
[codecov]: https://codecov.io/github/encode/django-rest-framework?branch=master
186184
[pypi-version]: https://img.shields.io/pypi/v/djangorestframework.svg
187185
[pypi]: https://pypi.org/project/djangorestframework/
188-
[twitter]: https://twitter.com/starletdreaming
189186
[group]: https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework
190-
[sandbox]: https://restframework.herokuapp.com/
191187

192188
[funding]: https://fund.django-rest-framework.org/topics/funding/
193189
[sponsors]: https://fund.django-rest-framework.org/topics/funding/#our-sponsors
@@ -200,6 +196,8 @@ Please see the [security policy][security-policy].
200196
[posthog-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/posthog-readme.png
201197
[cryptapi-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/cryptapi-readme.png
202198
[fezto-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/fezto-readme.png
199+
[svix-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/svix-premium.png
200+
[zuplo-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/zuplo-readme.png
203201

204202
[sentry-url]: https://getsentry.com/welcome/
205203
[stream-url]: https://getstream.io/?utm_source=DjangoRESTFramework&utm_medium=Webpage_Logo_Ad&utm_content=Developer&utm_campaign=DjangoRESTFramework_Jan2022_HomePage
@@ -209,6 +207,8 @@ Please see the [security policy][security-policy].
209207
[posthog-url]: https://posthog.com?utm_source=drf&utm_medium=sponsorship&utm_campaign=open-source-sponsorship
210208
[cryptapi-url]: https://cryptapi.io
211209
[fezto-url]: https://www.fezto.xyz/?utm_source=DjangoRESTFramework
210+
[svix-url]: https://www.svix.com/?utm_source=django-REST&utm_medium=sponsorship
211+
[zuplo-url]: https://zuplo.link/django-gh
212212

213213
[oauth1-section]: https://www.django-rest-framework.org/api-guide/authentication/#django-rest-framework-oauth
214214
[oauth2-section]: https://www.django-rest-framework.org/api-guide/authentication/#django-oauth-toolkit

docs/api-guide/authentication.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -454,7 +454,7 @@ More information can be found in the [Documentation](https://django-rest-durin.r
454454
[basicauth]: https://tools.ietf.org/html/rfc2617
455455
[permission]: permissions.md
456456
[throttling]: throttling.md
457-
[csrf-ajax]: https://docs.djangoproject.com/en/stable/ref/csrf/#ajax
457+
[csrf-ajax]: https://docs.djangoproject.com/en/stable/howto/csrf/#using-csrf-protection-with-ajax
458458
[mod_wsgi_official]: https://modwsgi.readthedocs.io/en/develop/configuration-directives/WSGIPassAuthorization.html
459459
[django-oauth-toolkit-getting-started]: https://django-oauth-toolkit.readthedocs.io/en/latest/rest-framework/getting_started.html
460460
[django-rest-framework-oauth]: https://jpadilla.github.io/django-rest-framework-oauth/

docs/api-guide/caching.md

+31-8
Original file line numberDiff line numberDiff line change
@@ -28,37 +28,60 @@ from rest_framework import viewsets
2828

2929
class UserViewSet(viewsets.ViewSet):
3030
# With cookie: cache requested url for each user for 2 hours
31-
@method_decorator(cache_page(60*60*2))
31+
@method_decorator(cache_page(60 * 60 * 2))
3232
@method_decorator(vary_on_cookie)
3333
def list(self, request, format=None):
3434
content = {
35-
'user_feed': request.user.get_user_feed()
35+
"user_feed": request.user.get_user_feed(),
3636
}
3737
return Response(content)
3838

3939

4040
class ProfileView(APIView):
4141
# With auth: cache requested url for each user for 2 hours
42-
@method_decorator(cache_page(60*60*2))
43-
@method_decorator(vary_on_headers("Authorization",))
42+
@method_decorator(cache_page(60 * 60 * 2))
43+
@method_decorator(vary_on_headers("Authorization"))
4444
def get(self, request, format=None):
4545
content = {
46-
'user_feed': request.user.get_user_feed()
46+
"user_feed": request.user.get_user_feed(),
4747
}
4848
return Response(content)
4949

5050

5151
class PostView(APIView):
5252
# Cache page for the requested url
53-
@method_decorator(cache_page(60*60*2))
53+
@method_decorator(cache_page(60 * 60 * 2))
5454
def get(self, request, format=None):
5555
content = {
56-
'title': 'Post title',
57-
'body': 'Post content'
56+
"title": "Post title",
57+
"body": "Post content",
5858
}
5959
return Response(content)
6060
```
6161

62+
63+
## Using cache with @api_view decorator
64+
65+
When using @api_view decorator, the Django-provided method-based cache decorators such as [`cache_page`][page],
66+
[`vary_on_cookie`][cookie] and [`vary_on_headers`][headers] can be called directly.
67+
68+
```python
69+
from django.views.decorators.cache import cache_page
70+
from django.views.decorators.vary import vary_on_cookie
71+
72+
from rest_framework.decorators import api_view
73+
from rest_framework.response import Response
74+
75+
76+
@cache_page(60 * 15)
77+
@vary_on_cookie
78+
@api_view(["GET"])
79+
def get_user_list(request):
80+
content = {"user_feed": request.user.get_user_feed()}
81+
return Response(content)
82+
```
83+
84+
6285
**NOTE:** The [`cache_page`][page] decorator only caches the
6386
`GET` and `HEAD` responses with status 200.
6487

docs/api-guide/fields.md

+1-9
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,6 @@ When serializing the instance, default will be used if the object attribute or d
6868

6969
Note that setting a `default` value implies that the field is not required. Including both the `default` and `required` keyword arguments is invalid and will raise an error.
7070

71-
Notes regarding default value propagation from model to serializer:
72-
73-
All the default values from model will pass as default to the serializer and the options method.
74-
75-
If the default is callable then it will be propagated to & evaluated every time in the serializer but not in options method.
76-
77-
If the value for given field is not given then default value will be present in the serializer and available in serializer's methods. Specified validation on given field will be evaluated on default value as that field will be present in the serializer.
78-
7971
### `allow_null`
8072

8173
Normally an error will be raised if `None` is passed to a serializer field. Set this keyword argument to `True` if `None` should be considered a valid value.
@@ -303,7 +295,7 @@ Corresponds to `django.db.models.fields.DecimalField`.
303295
* `min_value` Validate that the number provided is no less than this value.
304296
* `localize` Set to `True` to enable localization of input and output based on the current locale. This will also force `coerce_to_string` to `True`. Defaults to `False`. Note that data formatting is enabled if you have set `USE_L10N=True` in your settings file.
305297
* `rounding` Sets the rounding mode used when quantizing to the configured precision. Valid values are [`decimal` module rounding modes][python-decimal-rounding-modes]. Defaults to `None`.
306-
* `normalize_output` Will normalize the decimal value when serialized. This will strip all trailing zeroes and change the value's precision to the minimum required precision to be able to represent the value without loosing data. Defaults to `False`.
298+
* `normalize_output` Will normalize the decimal value when serialized. This will strip all trailing zeroes and change the value's precision to the minimum required precision to be able to represent the value without losing data. Defaults to `False`.
307299

308300
#### Example usage
309301

docs/api-guide/permissions.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,11 @@ This permission is suitable if you want to your API to allow read permissions to
173173

174174
This permission class ties into Django's standard `django.contrib.auth` [model permissions][contribauth]. This permission must only be applied to views that have a `.queryset` property or `get_queryset()` method. Authorization will only be granted if the user *is authenticated* and has the *relevant model permissions* assigned. The appropriate model is determined by checking `get_queryset().model` or `queryset.model`.
175175

176-
* `GET` requests require the user to have the `view` or `change` permission on the model
177176
* `POST` requests require the user to have the `add` permission on the model.
178177
* `PUT` and `PATCH` requests require the user to have the `change` permission on the model.
179178
* `DELETE` requests require the user to have the `delete` permission on the model.
180179

181-
The default behaviour can also be overridden to support custom model permissions.
180+
The default behavior can also be overridden to support custom model permissions. For example, you might want to include a `view` model permission for `GET` requests.
182181

183182
To use custom model permissions, override `DjangoModelPermissions` and set the `.perms_map` property. Refer to the source code for details.
184183

docs/api-guide/renderers.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ By default this will include the following keys: `view`, `request`, `response`,
283283

284284
The following is an example plaintext renderer that will return a response with the `data` parameter as the content of the response.
285285

286-
from django.utils.encoding import smart_text
286+
from django.utils.encoding import smart_str
287287
from rest_framework import renderers
288288

289289

@@ -292,7 +292,7 @@ The following is an example plaintext renderer that will return a response with
292292
format = 'txt'
293293

294294
def render(self, data, accepted_media_type=None, renderer_context=None):
295-
return smart_text(data, encoding=self.charset)
295+
return smart_str(data, encoding=self.charset)
296296

297297
## Setting the character set
298298

0 commit comments

Comments
 (0)