Skip to content

Commit b8f8817

Browse files
committed
Merge branch 'main' into jsonencoder_ipaddress
2 parents d291d7f + ade172e commit b8f8817

File tree

86 files changed

+1997
-1258
lines changed

Some content is hidden

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

86 files changed

+1997
-1258
lines changed

.github/ISSUE_TEMPLATE/config.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
blank_issues_enabled: false
2+
contact_links:
3+
- name: Discussions
4+
url: https://github.com/encode/django-rest-framework/discussions
5+
about: >
6+
The "Discussions" forum is where you want to start. 💖
7+
Please note that at this point in its lifespan, we consider Django REST framework to be feature-complete.

.github/workflows/main.yml

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name: CI
33
on:
44
push:
55
branches:
6-
- master
6+
- main
77
pull_request:
88

99
jobs:
@@ -14,18 +14,19 @@ jobs:
1414
strategy:
1515
matrix:
1616
python-version:
17-
- '3.9'
1817
- '3.10'
1918
- '3.11'
2019
- '3.12'
2120
- '3.13'
21+
- '3.14'
2222

2323
steps:
24-
- uses: actions/checkout@v4
24+
- uses: actions/checkout@v5
2525

26-
- uses: actions/setup-python@v5
26+
- uses: actions/setup-python@v6
2727
with:
2828
python-version: ${{ matrix.python-version }}
29+
allow-prereleases: true
2930
cache: 'pip'
3031
cache-dependency-path: 'requirements/*.txt'
3132

@@ -39,7 +40,7 @@ jobs:
3940
run: tox run -f py$(echo ${{ matrix.python-version }} | tr -d . | cut -f 1 -d '-')
4041

4142
- name: Run extra tox targets
42-
if: ${{ matrix.python-version == '3.9' }}
43+
if: ${{ matrix.python-version == '3.13' }}
4344
run: |
4445
tox -e base,dist,docs
4546
@@ -52,11 +53,11 @@ jobs:
5253
name: Test documentation links
5354
runs-on: ubuntu-24.04
5455
steps:
55-
- uses: actions/checkout@v4
56+
- uses: actions/checkout@v5
5657

57-
- uses: actions/setup-python@v5
58+
- uses: actions/setup-python@v6
5859
with:
59-
python-version: '3.9'
60+
python-version: '3.13'
6061

6162
- name: Install dependencies
6263
run: pip install -r requirements/requirements-documentation.txt
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
name: mkdocs
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
paths:
8+
- docs/**
9+
- docs_theme/**
10+
- requirements/requirements-documentation.txt
11+
- mkdocs.yml
12+
- .github/workflows/mkdocs-deploy.yml
13+
14+
jobs:
15+
deploy:
16+
runs-on: ubuntu-latest
17+
environment: github-pages
18+
permissions:
19+
contents: write
20+
concurrency:
21+
group: ${{ github.workflow }}-${{ github.ref }}
22+
steps:
23+
- uses: actions/checkout@v5
24+
- run: git fetch --no-tags --prune --depth=1 origin gh-pages
25+
- uses: actions/setup-python@v6
26+
with:
27+
python-version: 3.x
28+
- run: pip install -r requirements/requirements-documentation.txt
29+
- run: mkdocs gh-deploy

.github/workflows/pre-commit.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,19 @@ name: pre-commit
33
on:
44
push:
55
branches:
6-
- master
6+
- main
77
pull_request:
88

99
jobs:
1010
pre-commit:
1111
runs-on: ubuntu-latest
1212

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

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

.pre-commit-config.yaml

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,49 @@
11
repos:
22
- repo: https://github.com/pre-commit/pre-commit-hooks
3-
rev: v4.5.0
3+
rev: v6.0.0
44
hooks:
55
- id: check-added-large-files
66
- id: check-case-conflict
77
- id: check-json
88
- id: check-merge-conflict
99
- id: check-symlinks
1010
- id: check-toml
11-
- repo: https://github.com/pycqa/isort
12-
rev: 5.13.2
11+
- repo: https://github.com/PyCQA/isort
12+
rev: 7.0.0
1313
hooks:
1414
- id: isort
1515
- repo: https://github.com/PyCQA/flake8
16-
rev: 7.0.0
16+
rev: 7.3.0
1717
hooks:
1818
- id: flake8
1919
additional_dependencies:
2020
- flake8-tidy-imports
2121
- repo: https://github.com/adamchainz/blacken-docs
22-
rev: 1.16.0
22+
rev: 1.20.0
2323
hooks:
2424
- id: blacken-docs
25-
exclude: ^(?!docs).*$
2625
additional_dependencies:
27-
- black==23.1.0
26+
- black==25.9.0
2827
- repo: https://github.com/codespell-project/codespell
2928
# Configuration for codespell is in .codespellrc
30-
rev: v2.2.6
29+
rev: v2.4.1
3130
hooks:
3231
- id: codespell
32+
args: [
33+
"--builtin", "clear,rare,code,names,en-GB_to_en-US",
34+
"--ignore-words", "codespell-ignore-words.txt",
35+
"--skip", "*.css",
36+
]
3337
exclude: locale|kickstarter-announcement.md|coreapi-0.1.1.js
34-
38+
additional_dependencies:
39+
# python doesn't come with a toml parser prior to 3.11
40+
- "tomli; python_version < '3.11'"
3541
- repo: https://github.com/asottile/pyupgrade
36-
rev: v3.19.1
42+
rev: v3.21.0
3743
hooks:
3844
- id: pyupgrade
39-
args: ["--py39-plus", "--keep-percent-format"]
45+
args: ["--py310-plus", "--keep-percent-format"]
46+
- repo: https://github.com/tox-dev/pyproject-fmt
47+
rev: v2.11.0
48+
hooks:
49+
- id: pyproject-fmt

CONTRIBUTING.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22

33
At this point in its lifespan we consider Django REST framework to be essentially feature-complete. We may accept pull requests that track the continued development of Django versions, but would prefer not to accept new features or code formatting changes.
44

5+
Apart from minor documentation changes, the [GitHub discussions page](https://github.com/encode/django-rest-framework/discussions) should generally be your starting point. Please only open a pull request if you've been recommended to do so **after discussion**.
6+
57
The [Contributing guide in the documentation](https://www.django-rest-framework.org/community/contributing/) gives some more information on our process and code of conduct.

README.md

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Some reasons you might want to use REST framework:
5454

5555
# Requirements
5656

57-
* Python 3.9+
57+
* Python 3.10+
5858
* Django 4.2, 5.0, 5.1, 5.2
5959

6060
We **highly recommend** and only officially support the latest patch release of
@@ -67,10 +67,11 @@ Install using `pip`...
6767
pip install djangorestframework
6868

6969
Add `'rest_framework'` to your `INSTALLED_APPS` setting.
70+
7071
```python
7172
INSTALLED_APPS = [
72-
...
73-
'rest_framework',
73+
# ...
74+
"rest_framework",
7475
]
7576
```
7677

@@ -99,7 +100,7 @@ from rest_framework import routers, serializers, viewsets
99100
class UserSerializer(serializers.HyperlinkedModelSerializer):
100101
class Meta:
101102
model = User
102-
fields = ['url', 'username', 'email', 'is_staff']
103+
fields = ["url", "username", "email", "is_staff"]
103104

104105

105106
# ViewSets define the view behavior.
@@ -110,13 +111,13 @@ class UserViewSet(viewsets.ModelViewSet):
110111

111112
# Routers provide a way of automatically determining the URL conf.
112113
router = routers.DefaultRouter()
113-
router.register(r'users', UserViewSet)
114+
router.register(r"users", UserViewSet)
114115

115116
# Wire up our API using automatic URL routing.
116117
# Additionally, we include login URLs for the browsable API.
117118
urlpatterns = [
118-
path('', include(router.urls)),
119-
path('api-auth/', include('rest_framework.urls', namespace='rest_framework')),
119+
path("", include(router.urls)),
120+
path("api-auth/", include("rest_framework.urls", namespace="rest_framework")),
120121
]
121122
```
122123

@@ -126,15 +127,15 @@ Add the following to your `settings.py` module:
126127

127128
```python
128129
INSTALLED_APPS = [
129-
... # Make sure to include the default installed apps here.
130-
'rest_framework',
130+
# ... make sure to include the default installed apps here.
131+
"rest_framework",
131132
]
132133

133134
REST_FRAMEWORK = {
134135
# Use Django's standard `django.contrib.auth` permissions,
135136
# or allow read-only access for unauthenticated users.
136-
'DEFAULT_PERMISSION_CLASSES': [
137-
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly',
137+
"DEFAULT_PERMISSION_CLASSES": [
138+
"rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly",
138139
]
139140
}
140141
```
@@ -179,25 +180,25 @@ Please see the [security policy][security-policy].
179180

180181
[build-status-image]: https://github.com/encode/django-rest-framework/actions/workflows/main.yml/badge.svg
181182
[build-status]: https://github.com/encode/django-rest-framework/actions/workflows/main.yml
182-
[coverage-status-image]: https://img.shields.io/codecov/c/github/encode/django-rest-framework/master.svg
183-
[codecov]: https://codecov.io/github/encode/django-rest-framework?branch=master
183+
[coverage-status-image]: https://img.shields.io/codecov/c/github/encode/django-rest-framework/main.svg
184+
[codecov]: https://codecov.io/github/encode/django-rest-framework?branch=main
184185
[pypi-version]: https://img.shields.io/pypi/v/djangorestframework.svg
185186
[pypi]: https://pypi.org/project/djangorestframework/
186187
[group]: https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework
187188

188189
[funding]: https://fund.django-rest-framework.org/topics/funding/
189190
[sponsors]: https://fund.django-rest-framework.org/topics/funding/#our-sponsors
190191

191-
[sentry-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/sentry-readme.png
192-
[stream-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/stream-readme.png
193-
[spacinov-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/spacinov-readme.png
194-
[retool-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/retool-readme.png
195-
[bitio-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/bitio-readme.png
196-
[posthog-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/posthog-readme.png
197-
[cryptapi-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/cryptapi-readme.png
198-
[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
192+
[sentry-img]: https://raw.githubusercontent.com/encode/django-rest-framework/main/docs/img/premium/sentry-readme.png
193+
[stream-img]: https://raw.githubusercontent.com/encode/django-rest-framework/main/docs/img/premium/stream-readme.png
194+
[spacinov-img]: https://raw.githubusercontent.com/encode/django-rest-framework/main/docs/img/premium/spacinov-readme.png
195+
[retool-img]: https://raw.githubusercontent.com/encode/django-rest-framework/main/docs/img/premium/retool-readme.png
196+
[bitio-img]: https://raw.githubusercontent.com/encode/django-rest-framework/main/docs/img/premium/bitio-readme.png
197+
[posthog-img]: https://raw.githubusercontent.com/encode/django-rest-framework/main/docs/img/premium/posthog-readme.png
198+
[cryptapi-img]: https://raw.githubusercontent.com/encode/django-rest-framework/main/docs/img/premium/cryptapi-readme.png
199+
[fezto-img]: https://raw.githubusercontent.com/encode/django-rest-framework/main/docs/img/premium/fezto-readme.png
200+
[svix-img]: https://raw.githubusercontent.com/encode/django-rest-framework/main/docs/img/premium/svix-premium.png
201+
[zuplo-img]: https://raw.githubusercontent.com/encode/django-rest-framework/main/docs/img/premium/zuplo-readme.png
201202

202203
[sentry-url]: https://getsentry.com/welcome/
203204
[stream-url]: https://getstream.io/?utm_source=DjangoRESTFramework&utm_medium=Webpage_Logo_Ad&utm_content=Developer&utm_campaign=DjangoRESTFramework_Jan2022_HomePage

codespell-ignore-words.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Tim
2+
assertIn
3+
IAM
4+
endcode
5+
deque
6+
thead

docs/api-guide/authentication.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ JSON Web Token is a fairly new standard which can be used for token-based authen
416416

417417
## Hawk HTTP Authentication
418418

419-
The [HawkREST][hawkrest] library builds on the [Mohawk][mohawk] library to let you work with [Hawk][hawk] signed requests and responses in your API. [Hawk][hawk] lets two parties securely communicate with each other using messages signed by a shared key. It is based on [HTTP MAC access authentication][mac] (which was based on parts of [OAuth 1.0][oauth-1.0a]).
419+
The [HawkREST][hawkrest] library builds on the [Mohawk][mohawk] library to let you work with [Hawk][hawk] signed requests and responses in your API. [Hawk][hawk] let's two parties securely communicate with each other using messages signed by a shared key. It is based on [HTTP MAC access authentication][mac] (which was based on parts of [OAuth 1.0][oauth-1.0a]).
420420

421421
## HTTP Signature Authentication
422422

@@ -426,6 +426,11 @@ HTTP Signature (currently a [IETF draft][http-signature-ietf-draft]) provides a
426426

427427
[Djoser][djoser] library provides a set of views to handle basic actions such as registration, login, logout, password reset and account activation. The package works with a custom user model and uses token-based authentication. This is a ready to use REST implementation of the Django authentication system.
428428

429+
## DRF Auth Kit
430+
431+
[DRF Auth Kit][drf-auth-kit] library provides a modern REST authentication solution with JWT cookies, social login, multi-factor authentication, and comprehensive user management. The package offers full type safety, automatic OpenAPI schema generation with DRF Spectacular. It supports multiple authentication types (JWT, DRF Token, or Custom) and includes built-in internationalization for 50+ languages.
432+
433+
429434
## django-rest-auth / dj-rest-auth
430435

431436
This library provides a set of REST API endpoints for registration, authentication (including social media authentication), password reset, retrieve and update user details, etc. By having these API endpoints, your client apps such as AngularJS, iOS, Android, and others can communicate to your Django backend site independently via REST APIs for user management.
@@ -454,7 +459,7 @@ There are currently two forks of this project.
454459

455460
More information can be found in the [Documentation](https://django-rest-durin.readthedocs.io/en/latest/index.html).
456461

457-
## django-pyoidc
462+
## django-pyoidc
458463

459464
[dango-pyoidc][django_pyoidc] adds support for OpenID Connect (OIDC) authentication. This allows you to delegate user management to an Identity Provider, which can be used to implement Single-Sign-On (SSO). It provides support for most uses-cases, such as customizing how token info are mapped to user models, using OIDC audiences for access control, etc.
460465

@@ -497,4 +502,5 @@ More information can be found in the [Documentation](https://django-pyoidc.readt
497502
[django-rest-authemail]: https://github.com/celiao/django-rest-authemail
498503
[django-rest-durin]: https://github.com/eshaan7/django-rest-durin
499504
[login-required-middleware]: https://docs.djangoproject.com/en/stable/ref/middleware/#django.contrib.auth.middleware.LoginRequiredMiddleware
500-
[django-pyoidc] : https://github.com/makinacorpus/django_pyoidc
505+
[django-pyoidc]: https://github.com/makinacorpus/django_pyoidc
506+
[drf-auth-kit]: https://github.com/huynguyengl99/drf-auth-kit

docs/api-guide/fields.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ The `allow_null` option is also available for string fields, although its usage
180180

181181
## EmailField
182182

183-
A text representation, validates the text to be a valid e-mail address.
183+
A text representation, validates the text to be a valid email address.
184184

185185
Corresponds to `django.db.models.fields.EmailField`
186186

@@ -377,13 +377,16 @@ A Duration representation.
377377
Corresponds to `django.db.models.fields.DurationField`
378378

379379
The `validated_data` for these fields will contain a `datetime.timedelta` instance.
380-
The representation is a string following this format `'[DD] [HH:[MM:]]ss[.uuuuuu]'`.
381380

382-
**Signature:** `DurationField(max_value=None, min_value=None)`
381+
**Signature:** `DurationField(format=api_settings.DURATION_FORMAT, max_value=None, min_value=None)`
383382

383+
* `format` - A string representing the output format. If not specified, this defaults to the same value as the `DURATION_FORMAT` settings key, which will be `'django'` unless set. Formats are described below. Setting this value to `None` indicates that Python `timedelta` objects should be returned by `to_representation`. In this case the date encoding will be determined by the renderer.
384384
* `max_value` Validate that the duration provided is no greater than this value.
385385
* `min_value` Validate that the duration provided is no less than this value.
386386

387+
#### `DurationField` formats
388+
Format may either be the special string `'iso-8601'`, which indicates that [ISO 8601][iso8601] style intervals should be used (eg `'P4DT1H15M20S'`), or `'django'` which indicates that Django interval format `'[DD] [HH:[MM:]]ss[.uuuuuu]'` should be used (eg: `'4 1:15:20'`).
389+
387390
---
388391

389392
# Choice selection fields
@@ -759,7 +762,7 @@ suitable for updating our target object. With `source='*'`, the return from
759762
('y_coordinate', 4),
760763
('x_coordinate', 3)])
761764

762-
For completeness lets do the same thing again but with the nested serializer
765+
For completeness let's do the same thing again but with the nested serializer
763766
approach suggested above:
764767

765768
class NestedCoordinateSerializer(serializers.Serializer):

0 commit comments

Comments
 (0)