diff --git a/README.md b/README.md index bf4016751..e6e43047e 100644 --- a/README.md +++ b/README.md @@ -21,14 +21,14 @@ The initial aim is to provide a single full-time position on REST framework. [![][sentry-img]][sentry-url] [![][stream-img]][stream-url] -[![][rollbar-img]][rollbar-url] -[![][esg-img]][esg-url] +[![][spacinov-img]][spacinov-url] [![][retool-img]][retool-url] [![][bitio-img]][bitio-url] [![][posthog-img]][posthog-url] [![][cryptapi-img]][cryptapi-url] +[![][fezto-img]][fezto-url] -Many thanks to all our [wonderful sponsors][sponsors], and in particular to our premium backers, [Sentry][sentry-url], [Stream][stream-url], [Rollbar][rollbar-url], [ESG][esg-url], [Retool][retool-url], [bit.io][bitio-url], [PostHog][posthog-url], and [CryptAPI][cryptapi-url]. +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]. --- @@ -55,7 +55,7 @@ There is a live example API for testing purposes, [available here][sandbox]. # Requirements * Python (3.6, 3.7, 3.8, 3.9, 3.10) -* Django (2.2, 3.0, 3.1, 3.2, 4.0) +* Django (2.2, 3.0, 3.1, 3.2, 4.0, 4.1) We **highly recommend** and only officially support the latest patch release of each Python and Django series. @@ -194,21 +194,21 @@ Please see the [security policy][security-policy]. [sentry-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/sentry-readme.png [stream-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/stream-readme.png -[rollbar-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/rollbar-readme.png -[esg-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/esg-readme.png +[spacinov-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/spacinov-readme.png [retool-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/retool-readme.png [bitio-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/bitio-readme.png [posthog-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/posthog-readme.png [cryptapi-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/cryptapi-readme.png +[fezto-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/fezto-readme.png [sentry-url]: https://getsentry.com/welcome/ [stream-url]: https://getstream.io/?utm_source=DjangoRESTFramework&utm_medium=Webpage_Logo_Ad&utm_content=Developer&utm_campaign=DjangoRESTFramework_Jan2022_HomePage -[rollbar-url]: https://rollbar.com/?utm_source=django&utm_medium=sponsorship&utm_campaign=freetrial -[esg-url]: https://software.esg-usa.com/ +[spacinov-url]: https://www.spacinov.com/ [retool-url]: https://retool.com/?utm_source=djangorest&utm_medium=sponsorship [bitio-url]: https://bit.io/jobs?utm_source=DRF&utm_medium=sponsor&utm_campaign=DRF_sponsorship [posthog-url]: https://posthog.com?utm_source=drf&utm_medium=sponsorship&utm_campaign=open-source-sponsorship [cryptapi-url]: https://cryptapi.io +[fezto-url]: https://www.fezto.xyz/?utm_source=DjangoRESTFramework [oauth1-section]: https://www.django-rest-framework.org/api-guide/authentication/#django-rest-framework-oauth [oauth2-section]: https://www.django-rest-framework.org/api-guide/authentication/#django-oauth-toolkit diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md index 2f23e1718..fca9374d0 100644 --- a/docs/api-guide/authentication.md +++ b/docs/api-guide/authentication.md @@ -120,6 +120,14 @@ Unauthenticated responses that are denied permission will result in an `HTTP 401 ## TokenAuthentication +--- + +**Note:** The token authentication provided by Django REST framework is a fairly simple implementation. + +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. + +--- + 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. To use the `TokenAuthentication` scheme you'll need to [configure the authentication classes](#setting-the-authentication-scheme) to include `TokenAuthentication`, and additionally include `rest_framework.authtoken` in your `INSTALLED_APPS` setting: @@ -129,11 +137,9 @@ To use the `TokenAuthentication` scheme you'll need to [configure the authentica 'rest_framework.authtoken' ] ---- +Make sure to run `manage.py migrate` after changing your settings. -**Note:** Make sure to run `manage.py migrate` after changing your settings. The `rest_framework.authtoken` app provides Django database migrations. - ---- +The `rest_framework.authtoken` app provides Django database migrations. You'll also need to create tokens for your users. @@ -146,7 +152,7 @@ For clients to authenticate, the token key should be included in the `Authorizat Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b -**Note:** If you want to use a different keyword in the header, such as `Bearer`, simply subclass `TokenAuthentication` and set the `keyword` class variable. +*If you want to use a different keyword in the header, such as `Bearer`, simply subclass `TokenAuthentication` and set the `keyword` class variable.* If successfully authenticated, `TokenAuthentication` provides the following credentials. @@ -355,6 +361,10 @@ The following example will authenticate any incoming request as the user given b The following third-party packages are also available. +## django-rest-knox + +[Django-rest-knox][django-rest-knox] library provides models and views to handle token-based authentication in a more secure and extensible way than the built-in TokenAuthentication scheme - with Single Page Applications and Mobile clients in mind. It provides per-client tokens, and views to generate them when provided some other authentication (usually basic authentication), to delete the token (providing a server enforced logout) and to delete all tokens (logs out all clients that a user is logged into). + ## Django OAuth Toolkit The [Django OAuth Toolkit][django-oauth-toolkit] package provides OAuth 2.0 support and works with Python 3.4+. The package is maintained by [jazzband][jazzband] and uses the excellent [OAuthLib][oauthlib]. The package is well documented, and well supported and is currently our **recommended package for OAuth 2.0 support**. @@ -422,11 +432,7 @@ There are currently two forks of this project. ## drf-social-oauth2 -[Drf-social-oauth2][drf-social-oauth2] is a framework that helps you authenticate with major social oauth2 vendors, such as Facebook, Google, Twitter, Orcid, etc. It generates tokens in a JWTed way with an easy setup. - -## django-rest-knox - -[Django-rest-knox][django-rest-knox] library provides models and views to handle token-based authentication in a more secure and extensible way than the built-in TokenAuthentication scheme - with Single Page Applications and Mobile clients in mind. It provides per-client tokens, and views to generate them when provided some other authentication (usually basic authentication), to delete the token (providing a server enforced logout) and to delete all tokens (logs out all clients that a user is logged into). +[Drf-social-oauth2][drf-social-oauth2] is a framework that helps you authenticate with major social oauth2 vendors, such as Facebook, Google, Twitter, Orcid, etc. It generates tokens in a JWTed way with an easy setup. ## drfpasswordless diff --git a/docs/community/third-party-packages.md b/docs/community/third-party-packages.md index 7551cff36..9513b13d1 100644 --- a/docs/community/third-party-packages.md +++ b/docs/community/third-party-packages.md @@ -148,6 +148,7 @@ To submit new content, [open an issue][drf-create-issue] or [create a pull reque * [django-elasticsearch-dsl-drf][django-elasticsearch-dsl-drf] - Integrate Elasticsearch DSL with Django REST framework. Package provides views, serializers, filter backends, pagination and other handy add-ons. * [django-api-client][django-api-client] - DRF client that groups the Endpoint response, for use in CBVs and FBV as if you were working with Django's Native Models.. * [fast-drf] - A model based library for making API development faster and easier. +* [django-requestlogs] - Providing middleware and other helpers for audit logging for REST framework. * [drf-standardized-errors][drf-standardized-errors] - DRF exception handler to standardize error responses for all API endpoints. [cite]: http://www.software-ecosystems.com/Software_Ecosystems/Ecosystems.html @@ -238,4 +239,5 @@ To submit new content, [open an issue][drf-create-issue] or [create a pull reque [graphwrap]: https://github.com/PaulGilmartin/graph_wrap [rest-framework-actions]: https://github.com/AlexisMunera98/rest-framework-actions [fast-drf]: https://github.com/iashraful/fast-drf +[django-requestlogs]: https://github.com/Raekkeri/django-requestlogs [drf-standardized-errors]: https://github.com/ghazi-git/drf-standardized-errors diff --git a/docs/img/premium/bitio-readme.png b/docs/img/premium/bitio-readme.png index c47118cc6..d5d6259e6 100644 Binary files a/docs/img/premium/bitio-readme.png and b/docs/img/premium/bitio-readme.png differ diff --git a/docs/img/premium/cryptapi-readme.png b/docs/img/premium/cryptapi-readme.png index 163f6a9ea..10839b13b 100644 Binary files a/docs/img/premium/cryptapi-readme.png and b/docs/img/premium/cryptapi-readme.png differ diff --git a/docs/img/premium/fezto-readme.png b/docs/img/premium/fezto-readme.png new file mode 100644 index 000000000..7cc3be6e6 Binary files /dev/null and b/docs/img/premium/fezto-readme.png differ diff --git a/docs/img/premium/posthog-readme.png b/docs/img/premium/posthog-readme.png index 9ca8b0ecf..0fc09f0b8 100644 Binary files a/docs/img/premium/posthog-readme.png and b/docs/img/premium/posthog-readme.png differ diff --git a/docs/img/premium/retool-readme.png b/docs/img/premium/retool-readme.png index 56adba04d..971563427 100644 Binary files a/docs/img/premium/retool-readme.png and b/docs/img/premium/retool-readme.png differ diff --git a/docs/img/premium/sentry-readme.png b/docs/img/premium/sentry-readme.png index 420e8ee87..3c8858aca 100644 Binary files a/docs/img/premium/sentry-readme.png and b/docs/img/premium/sentry-readme.png differ diff --git a/docs/img/premium/spacinov-readme.png b/docs/img/premium/spacinov-readme.png new file mode 100644 index 000000000..20e925211 Binary files /dev/null and b/docs/img/premium/spacinov-readme.png differ diff --git a/docs/img/premium/stream-readme.png b/docs/img/premium/stream-readme.png index 15da6ba71..a6a7317b7 100644 Binary files a/docs/img/premium/stream-readme.png and b/docs/img/premium/stream-readme.png differ diff --git a/docs/index.md b/docs/index.md index e58f24df8..2f44fae9a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -68,16 +68,16 @@ continued development by **[signing up for a paid plan][funding]**.
-*Many thanks to all our [wonderful sponsors][sponsors], and in particular to our premium backers, [Sentry](https://getsentry.com/welcome/), [Stream](https://getstream.io/?utm_source=DjangoRESTFramework&utm_medium=Webpage_Logo_Ad&utm_content=Developer&utm_campaign=DjangoRESTFramework_Jan2022_HomePage), [ESG](https://software.esg-usa.com/), [Rollbar](https://rollbar.com/?utm_source=django&utm_medium=sponsorship&utm_campaign=freetrial), [Cadre](https://cadre.com), [Kloudless](https://hubs.ly/H0f30Lf0), [Lights On Software](https://lightsonsoftware.com), [Retool](https://retool.com/?utm_source=djangorest&utm_medium=sponsorship), [bit.io](https://bit.io/jobs?utm_source=DRF&utm_medium=sponsor&utm_campaign=DRF_sponsorship), [PostHog](https://posthog.com?utm_source=DRF&utm_medium=sponsor&utm_campaign=DRF_sponsorship), and [CryptAPI](https://cryptapi.io).* +*Many thanks to all our [wonderful sponsors][sponsors], and in particular to our premium backers, [Sentry](https://getsentry.com/welcome/), [Stream](https://getstream.io/?utm_source=DjangoRESTFramework&utm_medium=Webpage_Logo_Ad&utm_content=Developer&utm_campaign=DjangoRESTFramework_Jan2022_HomePage), [Spacinov](https://www.spacinov.com/), [Retool](https://retool.com/?utm_source=djangorest&utm_medium=sponsorship), [bit.io](https://bit.io/jobs?utm_source=DRF&utm_medium=sponsor&utm_campaign=DRF_sponsorship), [PostHog](https://posthog.com?utm_source=DRF&utm_medium=sponsor&utm_campaign=DRF_sponsorship), [CryptAPI](https://cryptapi.io), and [FEZTO](https://www.fezto.xyz/?utm_source=DjangoRESTFramework).* --- @@ -86,7 +86,7 @@ continued development by **[signing up for a paid plan][funding]**. REST framework requires the following: * Python (3.6, 3.7, 3.8, 3.9, 3.10) -* Django (2.2, 3.0, 3.1, 3.2, 4.0) +* Django (2.2, 3.0, 3.1, 3.2, 4.0, 4.1) We **highly recommend** and only officially support the latest patch release of each Python and Django series. diff --git a/requirements/requirements-documentation.txt b/requirements/requirements-documentation.txt index ad4928730..cf2dc26e8 100644 --- a/requirements/requirements-documentation.txt +++ b/requirements/requirements-documentation.txt @@ -1,2 +1,3 @@ # MkDocs to build our documentation. mkdocs>=1.1.2,<1.2 +jinja2>=2.10,<3.1.0 # contextfilter has been renamed diff --git a/rest_framework/fields.py b/rest_framework/fields.py index d7e7816ce..8d02b3206 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -27,7 +27,6 @@ from django.utils.duration import duration_string from django.utils.encoding import is_protected_type, smart_str from django.utils.formats import localize_input, sanitize_separators from django.utils.ipv6 import clean_ipv6_address -from django.utils.timezone import utc from django.utils.translation import gettext_lazy as _ from pytz.exceptions import InvalidTimeError @@ -1190,7 +1189,7 @@ class DateTimeField(Field): except InvalidTimeError: self.fail('make_aware', timezone=field_timezone) elif (field_timezone is None) and timezone.is_aware(value): - return timezone.make_naive(value, utc) + return timezone.make_naive(value, datetime.timezone.utc) return value def default_timezone(self): diff --git a/setup.py b/setup.py index 3c3761c86..cb6708c6e 100755 --- a/setup.py +++ b/setup.py @@ -94,6 +94,7 @@ setup( 'Framework :: Django :: 3.1', 'Framework :: Django :: 3.2', 'Framework :: Django :: 4.0', + 'Framework :: Django :: 4.1', 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', 'Operating System :: OS Independent', diff --git a/tests/test_encoders.py b/tests/test_encoders.py index c104dd5a5..953e5564b 100644 --- a/tests/test_encoders.py +++ b/tests/test_encoders.py @@ -1,15 +1,16 @@ -from datetime import date, datetime, timedelta +from datetime import date, datetime, timedelta, timezone from decimal import Decimal from uuid import uuid4 import pytest from django.test import TestCase -from django.utils.timezone import utc from rest_framework.compat import coreapi from rest_framework.utils.encoders import JSONEncoder from rest_framework.utils.serializer_helpers import ReturnList +utc = timezone.utc + class MockList: def tolist(self): diff --git a/tests/test_fields.py b/tests/test_fields.py index 7a5304a82..ec121c822 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -9,7 +9,7 @@ import pytz from django.core.exceptions import ValidationError as DjangoValidationError from django.http import QueryDict from django.test import TestCase, override_settings -from django.utils.timezone import activate, deactivate, override, utc +from django.utils.timezone import activate, deactivate, override import rest_framework from rest_framework import exceptions, serializers @@ -17,6 +17,8 @@ from rest_framework.fields import ( BuiltinSignatureError, DjangoImageField, is_simple_callable ) +utc = datetime.timezone.utc + # Tests for helper functions. # --------------------------- diff --git a/tests/test_model_serializer.py b/tests/test_model_serializer.py index 7da1b41ae..abb4830d1 100644 --- a/tests/test_model_serializer.py +++ b/tests/test_model_serializer.py @@ -12,6 +12,7 @@ import sys import tempfile from collections import OrderedDict +import django import pytest from django.core.exceptions import ImproperlyConfigured from django.core.serializers.json import DjangoJSONEncoder @@ -452,11 +453,14 @@ class TestPosgresFieldsMapping(TestCase): model = ArrayFieldModel fields = ['array_field', 'array_field_with_blank'] + validators = "" + if django.VERSION < (4, 1): + validators = ", validators=[