to respect formatting
+ white-space: pre; /* forces to respect formatting */
}
.main-container {
From 24a938abaadd98b5482bec33defd285625842342 Mon Sep 17 00:00:00 2001
From: Finn Gundlach
Date: Wed, 16 Jun 2021 15:53:29 +0200
Subject: [PATCH 090/154] Update documentation to include Django 3.2 as
supported version (#8037)
---
README.md | 2 +-
docs/index.md | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index ff76a5525d..fce275256e 100644
--- a/README.md
+++ b/README.md
@@ -53,7 +53,7 @@ There is a live example API for testing purposes, [available here][sandbox].
# Requirements
* Python (3.5, 3.6, 3.7, 3.8, 3.9)
-* Django (2.2, 3.0, 3.1)
+* Django (2.2, 3.0, 3.1, 3.2)
We **highly recommend** and only officially support the latest patch release of
each Python and Django series.
diff --git a/docs/index.md b/docs/index.md
index 530813684e..28e3302501 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -84,7 +84,7 @@ continued development by **[signing up for a paid plan][funding]**.
REST framework requires the following:
* Python (3.5, 3.6, 3.7, 3.8, 3.9)
-* Django (2.2, 3.0, 3.1)
+* Django (2.2, 3.0, 3.1, 3.2)
We **highly recommend** and only officially support the latest patch release of
each Python and Django series.
From e92016ac2e926483e05e296558fc3d1ea3279625 Mon Sep 17 00:00:00 2001
From: Adam Johnson
Date: Mon, 21 Jun 2021 11:33:43 +0100
Subject: [PATCH 091/154] Stop ignoring test outcome for Django 3.2 (#7927)
---
requirements/requirements-optionals.txt | 2 +-
setup.py | 1 +
tox.ini | 12 ------------
3 files changed, 2 insertions(+), 13 deletions(-)
diff --git a/requirements/requirements-optionals.txt b/requirements/requirements-optionals.txt
index 4cb0e54f4b..75b9ab4d60 100644
--- a/requirements/requirements-optionals.txt
+++ b/requirements/requirements-optionals.txt
@@ -2,7 +2,7 @@
coreapi==2.3.1
coreschema==0.0.4
django-filter>=2.4.0,<3.0
-django-guardian>=2.3.0,<2.4
+django-guardian>=2.4.0,<2.5
markdown==3.3;python_version>="3.6"
markdown==3.2.2;python_version=="3.5"
psycopg2-binary>=2.8.5,<2.9
diff --git a/setup.py b/setup.py
index e2a1c0222c..5fd4df20db 100755
--- a/setup.py
+++ b/setup.py
@@ -92,6 +92,7 @@ def get_version(package):
'Framework :: Django :: 2.2',
'Framework :: Django :: 3.0',
'Framework :: Django :: 3.1',
+ 'Framework :: Django :: 3.2',
'Intended Audience :: Developers',
'License :: OSI Approved :: BSD License',
'Operating System :: OS Independent',
diff --git a/tox.ini b/tox.ini
index bf4de90d03..f23486a685 100644
--- a/tox.ini
+++ b/tox.ini
@@ -50,18 +50,6 @@ deps =
-rrequirements/requirements-testing.txt
-rrequirements/requirements-documentation.txt
-[testenv:py36-django32]
-ignore_outcome = true
-
-[testenv:py37-django32]
-ignore_outcome = true
-
-[testenv:py38-django32]
-ignore_outcome = true
-
-[testenv:py39-django32]
-ignore_outcome = true
-
[testenv:py38-djangomain]
ignore_outcome = true
From c8a9c856c25a1a360a91d2c7bc11e0dacfb9c3a4 Mon Sep 17 00:00:00 2001
From: Burak Kadir Er
Date: Mon, 28 Jun 2021 14:51:21 +0300
Subject: [PATCH 092/154] fix a small typo (#8060)
---
docs/api-guide/renderers.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md
index 954fb3bb98..7dbc5eee8f 100644
--- a/docs/api-guide/renderers.md
+++ b/docs/api-guide/renderers.md
@@ -105,7 +105,7 @@ The TemplateHTMLRenderer will create a `RequestContext`, using the `response.dat
---
-**Note:** When used with a view that makes use of a serializer the `Response` sent for rendering may not be a dictionay and will need to be wrapped in a dict before returning to allow the TemplateHTMLRenderer to render it. For example:
+**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:
```
response.data = {'results': response.data}
From d2977cff989f9b14f402ecf1e9235ee3d110977b Mon Sep 17 00:00:00 2001
From: Nikita Sobolev
Date: Mon, 28 Jun 2021 15:07:41 +0300
Subject: [PATCH 093/154] Fixes inconsistent headers in `serializer` docs
(#8056)
Some headers were using `.`, some - were not.
Now, all of them are the same with `.`, because it was easier to fix.
---
docs/api-guide/serializers.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/api-guide/serializers.md b/docs/api-guide/serializers.md
index f05fe7e7e9..13c0c87104 100644
--- a/docs/api-guide/serializers.md
+++ b/docs/api-guide/serializers.md
@@ -605,13 +605,13 @@ For `ModelSerializer` this defaults to `PrimaryKeyRelatedField`.
For `HyperlinkedModelSerializer` this defaults to `serializers.HyperlinkedRelatedField`.
-### `serializer_url_field`
+### `.serializer_url_field`
The serializer field class that should be used for any `url` field on the serializer.
Defaults to `serializers.HyperlinkedIdentityField`
-### `serializer_choice_field`
+### `.serializer_choice_field`
The serializer field class that should be used for any choice fields on the serializer.
From 98e56e0327596db352b35fa3b3dc8355dc9bd030 Mon Sep 17 00:00:00 2001
From: Evgeny Panfilov
Date: Thu, 1 Jul 2021 17:04:44 +0300
Subject: [PATCH 094/154] fix empty string as a value for a validated
DecimalField (#8064) (#8067)
---
rest_framework/fields.py | 8 +++++---
tests/test_fields.py | 24 ++++++++++++++++++++++++
2 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/rest_framework/fields.py b/rest_framework/fields.py
index e4be54751d..bedc02b94d 100644
--- a/rest_framework/fields.py
+++ b/rest_framework/fields.py
@@ -1046,6 +1046,11 @@ def __init__(self, max_digits, decimal_places, coerce_to_string=None, max_value=
'Invalid rounding option %s. Valid values for rounding are: %s' % (rounding, valid_roundings))
self.rounding = rounding
+ def validate_empty_values(self, data):
+ if smart_str(data).strip() == '' and self.allow_null:
+ return (True, None)
+ return super().validate_empty_values(data)
+
def to_internal_value(self, data):
"""
Validate that the input is a decimal number and return a Decimal
@@ -1063,9 +1068,6 @@ def to_internal_value(self, data):
try:
value = decimal.Decimal(data)
except decimal.DecimalException:
- if data == '' and self.allow_null:
- return None
-
self.fail('invalid')
if value.is_nan():
diff --git a/tests/test_fields.py b/tests/test_fields.py
index 78a9effb8c..d99ca9c40d 100644
--- a/tests/test_fields.py
+++ b/tests/test_fields.py
@@ -1163,6 +1163,30 @@ class TestMinMaxDecimalField(FieldValues):
)
+class TestAllowEmptyStrDecimalFieldWithValidators(FieldValues):
+ """
+ Check that empty string ('', ' ') is acceptable value for the DecimalField
+ if allow_null=True and there are max/min validators
+ """
+ valid_inputs = {
+ None: None,
+ '': None,
+ ' ': None,
+ ' ': None,
+ 5: Decimal('5'),
+ '0': Decimal('0'),
+ '10': Decimal('10'),
+ }
+ invalid_inputs = {
+ -1: ['Ensure this value is greater than or equal to 0.'],
+ 11: ['Ensure this value is less than or equal to 10.'],
+ }
+ outputs = {
+ None: '',
+ }
+ field = serializers.DecimalField(max_digits=3, decimal_places=1, allow_null=True, min_value=0, max_value=10)
+
+
class TestNoMaxDigitsDecimalField(FieldValues):
field = serializers.DecimalField(
max_value=100, min_value=0,
From b215375125980114482779b36dd825775ef7e482 Mon Sep 17 00:00:00 2001
From: Nikhil Benesch
Date: Fri, 6 Aug 2021 05:10:58 -0400
Subject: [PATCH 095/154] Propagate nullability in ModelSerializer (#8116)
Propagate the nullability of underlying model fields in ModelSerializer
when those fields are marked as read only. This ensures the correct
generation of OpenAPI schemas.
Fix #8041.
---
rest_framework/serializers.py | 5 ++---
tests/schemas/test_openapi.py | 19 +++++++++++++++++++
2 files changed, 21 insertions(+), 3 deletions(-)
diff --git a/rest_framework/serializers.py b/rest_framework/serializers.py
index 49eec82591..9ea57f1aff 100644
--- a/rest_framework/serializers.py
+++ b/rest_framework/serializers.py
@@ -1326,9 +1326,8 @@ def include_extra_kwargs(self, kwargs, extra_kwargs):
"""
if extra_kwargs.get('read_only', False):
for attr in [
- 'required', 'default', 'allow_blank', 'allow_null',
- 'min_length', 'max_length', 'min_value', 'max_value',
- 'validators', 'queryset'
+ 'required', 'default', 'allow_blank', 'min_length',
+ 'max_length', 'min_value', 'max_value', 'validators', 'queryset'
]:
kwargs.pop(attr, None)
diff --git a/tests/schemas/test_openapi.py b/tests/schemas/test_openapi.py
index aef20670e6..daa035a3f3 100644
--- a/tests/schemas/test_openapi.py
+++ b/tests/schemas/test_openapi.py
@@ -2,6 +2,7 @@
import warnings
import pytest
+from django.db import models
from django.test import RequestFactory, TestCase, override_settings
from django.urls import path
from django.utils.translation import gettext_lazy as _
@@ -110,6 +111,24 @@ class Serializer(serializers.Serializer):
assert data['properties']['default_false']['default'] is False, "default must be false"
assert 'default' not in data['properties']['without_default'], "default must not be defined"
+ def test_nullable_fields(self):
+ class Model(models.Model):
+ rw_field = models.CharField(null=True)
+ ro_field = models.CharField(null=True)
+
+ class Serializer(serializers.ModelSerializer):
+ class Meta:
+ model = Model
+ fields = ["rw_field", "ro_field"]
+ read_only_fields = ["ro_field"]
+
+ inspector = AutoSchema()
+
+ data = inspector.map_serializer(Serializer())
+ assert data['properties']['rw_field']['nullable'], "rw_field nullable must be true"
+ assert data['properties']['ro_field']['nullable'], "ro_field nullable must be true"
+ assert data['properties']['ro_field']['readOnly'], "ro_field read_only must be true"
+
@pytest.mark.skipif(uritemplate is None, reason='uritemplate not installed.')
class TestOperationIntrospection(TestCase):
From fdb49314754ff13d91c6eec7ccdb8ece52bea9eb Mon Sep 17 00:00:00 2001
From: Aarni Koskela
Date: Fri, 6 Aug 2021 12:14:52 +0300
Subject: [PATCH 096/154] Make Field constructors keyword-only (#7632)
---
rest_framework/fields.py | 46 ++++++++++++++++++++--------------------
tests/test_fields.py | 5 +++++
2 files changed, 28 insertions(+), 23 deletions(-)
diff --git a/rest_framework/fields.py b/rest_framework/fields.py
index bedc02b94d..5cafed5556 100644
--- a/rest_framework/fields.py
+++ b/rest_framework/fields.py
@@ -320,7 +320,7 @@ class Field:
default_empty_html = empty
initial = None
- def __init__(self, read_only=False, write_only=False,
+ def __init__(self, *, read_only=False, write_only=False,
required=None, default=empty, initial=empty, source=None,
label=None, help_text=None, style=None,
error_messages=None, validators=None, allow_null=False):
@@ -1163,14 +1163,14 @@ class DateTimeField(Field):
}
datetime_parser = datetime.datetime.strptime
- def __init__(self, format=empty, input_formats=None, default_timezone=None, *args, **kwargs):
+ def __init__(self, format=empty, input_formats=None, default_timezone=None, **kwargs):
if format is not empty:
self.format = format
if input_formats is not None:
self.input_formats = input_formats
if default_timezone is not None:
self.timezone = default_timezone
- super().__init__(*args, **kwargs)
+ super().__init__(**kwargs)
def enforce_timezone(self, value):
"""
@@ -1249,12 +1249,12 @@ class DateField(Field):
}
datetime_parser = datetime.datetime.strptime
- def __init__(self, format=empty, input_formats=None, *args, **kwargs):
+ def __init__(self, format=empty, input_formats=None, **kwargs):
if format is not empty:
self.format = format
if input_formats is not None:
self.input_formats = input_formats
- super().__init__(*args, **kwargs)
+ super().__init__(**kwargs)
def to_internal_value(self, value):
input_formats = getattr(self, 'input_formats', api_settings.DATE_INPUT_FORMATS)
@@ -1315,12 +1315,12 @@ class TimeField(Field):
}
datetime_parser = datetime.datetime.strptime
- def __init__(self, format=empty, input_formats=None, *args, **kwargs):
+ def __init__(self, format=empty, input_formats=None, **kwargs):
if format is not empty:
self.format = format
if input_formats is not None:
self.input_formats = input_formats
- super().__init__(*args, **kwargs)
+ super().__init__(**kwargs)
def to_internal_value(self, value):
input_formats = getattr(self, 'input_formats', api_settings.TIME_INPUT_FORMATS)
@@ -1470,9 +1470,9 @@ class MultipleChoiceField(ChoiceField):
}
default_empty_html = []
- def __init__(self, *args, **kwargs):
+ def __init__(self, **kwargs):
self.allow_empty = kwargs.pop('allow_empty', True)
- super().__init__(*args, **kwargs)
+ super().__init__(**kwargs)
def get_value(self, dictionary):
if self.field_name not in dictionary:
@@ -1529,12 +1529,12 @@ class FileField(Field):
'max_length': _('Ensure this filename has at most {max_length} characters (it has {length}).'),
}
- def __init__(self, *args, **kwargs):
+ def __init__(self, **kwargs):
self.max_length = kwargs.pop('max_length', None)
self.allow_empty_file = kwargs.pop('allow_empty_file', False)
if 'use_url' in kwargs:
self.use_url = kwargs.pop('use_url')
- super().__init__(*args, **kwargs)
+ super().__init__(**kwargs)
def to_internal_value(self, data):
try:
@@ -1578,9 +1578,9 @@ class ImageField(FileField):
),
}
- def __init__(self, *args, **kwargs):
+ def __init__(self, **kwargs):
self._DjangoImageField = kwargs.pop('_DjangoImageField', DjangoImageField)
- super().__init__(*args, **kwargs)
+ super().__init__(**kwargs)
def to_internal_value(self, data):
# Image validation is a bit grungy, so we'll just outright
@@ -1595,8 +1595,8 @@ def to_internal_value(self, data):
# Composite field types...
class _UnvalidatedField(Field):
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
+ def __init__(self, **kwargs):
+ super().__init__(**kwargs)
self.allow_blank = True
self.allow_null = True
@@ -1617,7 +1617,7 @@ class ListField(Field):
'max_length': _('Ensure this field has no more than {max_length} elements.')
}
- def __init__(self, *args, **kwargs):
+ def __init__(self, **kwargs):
self.child = kwargs.pop('child', copy.deepcopy(self.child))
self.allow_empty = kwargs.pop('allow_empty', True)
self.max_length = kwargs.pop('max_length', None)
@@ -1629,7 +1629,7 @@ def __init__(self, *args, **kwargs):
"Remove `source=` from the field declaration."
)
- super().__init__(*args, **kwargs)
+ super().__init__(**kwargs)
self.child.bind(field_name='', parent=self)
if self.max_length is not None:
message = lazy_format(self.error_messages['max_length'], max_length=self.max_length)
@@ -1694,7 +1694,7 @@ class DictField(Field):
'empty': _('This dictionary may not be empty.'),
}
- def __init__(self, *args, **kwargs):
+ def __init__(self, **kwargs):
self.child = kwargs.pop('child', copy.deepcopy(self.child))
self.allow_empty = kwargs.pop('allow_empty', True)
@@ -1704,7 +1704,7 @@ def __init__(self, *args, **kwargs):
"Remove `source=` from the field declaration."
)
- super().__init__(*args, **kwargs)
+ super().__init__(**kwargs)
self.child.bind(field_name='', parent=self)
def get_value(self, dictionary):
@@ -1753,8 +1753,8 @@ def run_child_validation(self, data):
class HStoreField(DictField):
child = CharField(allow_blank=True, allow_null=True)
- def __init__(self, *args, **kwargs):
- super().__init__(*args, **kwargs)
+ def __init__(self, **kwargs):
+ super().__init__(**kwargs)
assert isinstance(self.child, CharField), (
"The `child` argument must be an instance of `CharField`, "
"as the hstore extension stores values as strings."
@@ -1769,11 +1769,11 @@ class JSONField(Field):
# Workaround for isinstance calls when importing the field isn't possible
_is_jsonfield = True
- def __init__(self, *args, **kwargs):
+ def __init__(self, **kwargs):
self.binary = kwargs.pop('binary', False)
self.encoder = kwargs.pop('encoder', None)
self.decoder = kwargs.pop('decoder', None)
- super().__init__(*args, **kwargs)
+ super().__init__(**kwargs)
def get_value(self, dictionary):
if html.is_html_input(dictionary) and self.field_name in dictionary:
diff --git a/tests/test_fields.py b/tests/test_fields.py
index d99ca9c40d..2d4cc44ae0 100644
--- a/tests/test_fields.py
+++ b/tests/test_fields.py
@@ -2010,6 +2010,11 @@ def test_collection_types_are_invalid_input(self):
field.to_internal_value(input_value)
assert exc_info.value.detail == ['Expected a list of items but got type "dict".']
+ def test_constructor_misuse_raises(self):
+ # Test that `ListField` can only be instantiated with keyword arguments
+ with pytest.raises(TypeError):
+ serializers.ListField(serializers.CharField())
+
class TestNestedListField(FieldValues):
"""
From 2942590ee3d3596683405dcdb1017e1833f5cb02 Mon Sep 17 00:00:00 2001
From: Ma77heus <58952630+MattheusHenrique@users.noreply.github.com>
Date: Fri, 6 Aug 2021 12:39:58 -0300
Subject: [PATCH 097/154] fix: broken cite (#8086)
Co-authored-by: MattheusHenrique
---
docs/api-guide/renderers.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/api-guide/renderers.md b/docs/api-guide/renderers.md
index 7dbc5eee8f..f13b7ba946 100644
--- a/docs/api-guide/renderers.md
+++ b/docs/api-guide/renderers.md
@@ -528,7 +528,7 @@ Comma-separated values are a plain-text tabular data format, that can be easily
[Rest Framework Latex] provides a renderer that outputs PDFs using Laulatex. It is maintained by [Pebble (S/F Software)][mypebble].
-[cite]: https://docs.djangoproject.com/en/stable/stable/template-response/#the-rendering-process
+[cite]: https://docs.djangoproject.com/en/stable/ref/template-response/#the-rendering-process
[conneg]: content-negotiation.md
[html-and-forms]: ../topics/html-and-forms.md
[browser-accept-headers]: http://www.gethifi.com/blog/browser-rest-http-accept-headers
From cba24464e8f63377627f3016df88ee74d11a817d Mon Sep 17 00:00:00 2001
From: Paul Wayper
Date: Sat, 7 Aug 2021 01:45:15 +1000
Subject: [PATCH 098/154] Botbot has been acquired, all paths now point to
startupresources (#8050)
Signed-off-by: Paul Wayper
---
docs/index.md | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/docs/index.md b/docs/index.md
index 28e3302501..ccbaf73731 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -186,7 +186,7 @@ Framework.
## Support
-For support please see the [REST framework discussion group][group], try the `#restframework` channel on `irc.freenode.net`, search [the IRC archives][botbot], or raise a question on [Stack Overflow][stack-overflow], making sure to include the ['django-rest-framework'][django-rest-framework-tag] tag.
+For support please see the [REST framework discussion group][group], try the `#restframework` channel on `irc.freenode.net`, or raise a question on [Stack Overflow][stack-overflow], making sure to include the ['django-rest-framework'][django-rest-framework-tag] tag.
For priority support please sign up for a [professional or premium sponsorship plan](https://fund.django-rest-framework.org/topics/funding/).
@@ -257,7 +257,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
[funding]: community/funding.md
[group]: https://groups.google.com/forum/?fromgroups#!forum/django-rest-framework
-[botbot]: https://botbot.me/freenode/restframework/
[stack-overflow]: https://stackoverflow.com/
[django-rest-framework-tag]: https://stackoverflow.com/questions/tagged/django-rest-framework
[security-mail]: mailto:rest-framework-security@googlegroups.com
From c4404f3d5d2df2a5c7450517b48c4e6dfeb3c89e Mon Sep 17 00:00:00 2001
From: Paul Wayper
Date: Sat, 7 Aug 2021 01:46:26 +1000
Subject: [PATCH 099/154] We now use Libera.chat rather than Freenode for IRC
(#8049)
Signed-off-by: Paul Wayper
Co-authored-by: Tom Christie
---
README.md | 2 +-
docs/index.md | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index fce275256e..b8d8ca61b1 100644
--- a/README.md
+++ b/README.md
@@ -168,7 +168,7 @@ Or to create a new user:
Full documentation for the project is available at [https://www.django-rest-framework.org/][docs].
-For questions and support, use the [REST framework discussion group][group], or `#restframework` on freenode IRC.
+For questions and support, use the [REST framework discussion group][group], or `#restframework` on libera.chat IRC.
You may also want to [follow the author on Twitter][twitter].
diff --git a/docs/index.md b/docs/index.md
index ccbaf73731..641800b93c 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -186,7 +186,7 @@ Framework.
## Support
-For support please see the [REST framework discussion group][group], try the `#restframework` channel on `irc.freenode.net`, or raise a question on [Stack Overflow][stack-overflow], making sure to include the ['django-rest-framework'][django-rest-framework-tag] tag.
+For support please see the [REST framework discussion group][group], try the `#restframework` channel on `irc.libera.chat`, or raise a question on [Stack Overflow][stack-overflow], making sure to include the ['django-rest-framework'][django-rest-framework-tag] tag.
For priority support please sign up for a [professional or premium sponsorship plan](https://fund.django-rest-framework.org/topics/funding/).
From b824b33dc3a3facad3ef2b41fbe02ab2a7578bc3 Mon Sep 17 00:00:00 2001
From: Thomas Grainger
Date: Fri, 6 Aug 2021 16:46:57 +0100
Subject: [PATCH 100/154] add changelog project_url (#8085)
---
setup.py | 1 +
1 file changed, 1 insertion(+)
diff --git a/setup.py b/setup.py
index 5fd4df20db..d755a00fe2 100755
--- a/setup.py
+++ b/setup.py
@@ -109,6 +109,7 @@ def get_version(package):
project_urls={
'Funding': 'https://fund.django-rest-framework.org/topics/funding/',
'Source': 'https://github.com/encode/django-rest-framework',
+ 'Changelog': 'https://www.django-rest-framework.org/community/release-notes/',
},
)
From e95e91ccf2065cbf474892b73ebd5790e5a4ae14 Mon Sep 17 00:00:00 2001
From: Ben Hampson <77866043+Ben-Hampson@users.noreply.github.com>
Date: Fri, 6 Aug 2021 17:49:41 +0200
Subject: [PATCH 101/154] Use correct link for httpie (#8005)
Before it was linking to a fork of a fork of httpie. I've changed it to the right URL.
---
docs/tutorial/1-serialization.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/tutorial/1-serialization.md b/docs/tutorial/1-serialization.md
index 85d8676b1d..908b7474a0 100644
--- a/docs/tutorial/1-serialization.md
+++ b/docs/tutorial/1-serialization.md
@@ -374,5 +374,5 @@ We'll see how we can start to improve things in [part 2 of the tutorial][tut-2].
[sandbox]: https://restframework.herokuapp.com/
[venv]: https://docs.python.org/3/library/venv.html
[tut-2]: 2-requests-and-responses.md
-[httpie]: https://github.com/jakubroztocil/httpie#installation
+[httpie]: https://github.com/httpie/httpie#installation
[curl]: https://curl.haxx.se/
From cdd53c7de912d5868c96f4e3883df248a3e6341d Mon Sep 17 00:00:00 2001
From: juliangeissler <81534590+juliangeissler@users.noreply.github.com>
Date: Sun, 8 Aug 2021 15:45:00 +0200
Subject: [PATCH 102/154] Update Tutorial - Relationships & Hyperlinked APIs
(#7950)
unnecessary import, because it is already added in the previous section
---
docs/tutorial/5-relationships-and-hyperlinked-apis.md | 1 -
1 file changed, 1 deletion(-)
diff --git a/docs/tutorial/5-relationships-and-hyperlinked-apis.md b/docs/tutorial/5-relationships-and-hyperlinked-apis.md
index b0f3380859..f999fdf507 100644
--- a/docs/tutorial/5-relationships-and-hyperlinked-apis.md
+++ b/docs/tutorial/5-relationships-and-hyperlinked-apis.md
@@ -31,7 +31,6 @@ The other thing we need to consider when creating the code highlight view is tha
Instead of using a concrete generic view, we'll use the base class for representing instances, and create our own `.get()` method. In your `snippets/views.py` add:
from rest_framework import renderers
- from rest_framework.response import Response
class SnippetHighlight(generics.GenericAPIView):
queryset = Snippet.objects.all()
From c5d9144aef1144825942ddffe0a6af23102ef44a Mon Sep 17 00:00:00 2001
From: Mark <33526445+mark-gold@users.noreply.github.com>
Date: Wed, 11 Aug 2021 13:30:09 +0300
Subject: [PATCH 103/154] fix typo (#8122)
Co-authored-by: mgold
---
docs/api-guide/validators.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/api-guide/validators.md b/docs/api-guide/validators.md
index 4451489d4d..76dcb0d541 100644
--- a/docs/api-guide/validators.md
+++ b/docs/api-guide/validators.md
@@ -238,7 +238,7 @@ In the case of update operations on *nested* serializers there's no way of
applying this exclusion, because the instance is not available.
Again, you'll probably want to explicitly remove the validator from the
-serializer class, and write the code the for the validation constraint
+serializer class, and write the code for the validation constraint
explicitly, in a `.validate()` method, or in the view.
## Debugging complex cases
From c927053d4b99ada6b3fd5d70c6536554ff5fe8c0 Mon Sep 17 00:00:00 2001
From: jefcolbi
Date: Tue, 31 Aug 2021 12:51:47 +0100
Subject: [PATCH 104/154] Replacing django-rest-auth with dj-rest-auth (#8146)
---
docs/community/third-party-packages.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/community/third-party-packages.md b/docs/community/third-party-packages.md
index e53fc3d50c..933244a6a9 100644
--- a/docs/community/third-party-packages.md
+++ b/docs/community/third-party-packages.md
@@ -54,7 +54,7 @@ To submit new content, [open an issue][drf-create-issue] or [create a pull reque
* [hawkrest][hawkrest] - Provides Hawk HTTP Authorization.
* [djangorestframework-httpsignature][djangorestframework-httpsignature] - Provides an easy to use HTTP Signature Authentication mechanism.
* [djoser][djoser] - Provides a set of views to handle basic actions such as registration, login, logout, password reset and account activation.
-* [django-rest-auth][django-rest-auth] - Provides a set of REST API endpoints for registration, authentication (including social media authentication), password reset, retrieve and update user details, etc.
+* [dj-rest-auth][dj-rest-auth] - Provides a set of REST API endpoints for registration, authentication (including social media authentication), password reset, retrieve and update user details, etc.
* [drf-oidc-auth][drf-oidc-auth] - Implements OpenID Connect token authentication for DRF.
* [drfpasswordless][drfpasswordless] - Adds (Medium, Square Cash inspired) passwordless logins and signups via email and mobile numbers.
* [django-rest-authemail][django-rest-authemail] - Provides a RESTful API for user signup and authentication using email addresses.
@@ -193,7 +193,7 @@ To submit new content, [open an issue][drf-create-issue] or [create a pull reque
[gaiarestframework]: https://github.com/AppsFuel/gaiarestframework
[drf-extensions]: https://github.com/chibisov/drf-extensions
[ember-django-adapter]: https://github.com/dustinfarris/ember-django-adapter
-[django-rest-auth]: https://github.com/Tivix/django-rest-auth/
+[dj-rest-auth]: https://github.com/iMerica/dj-rest-auth
[django-versatileimagefield]: https://github.com/WGBH/django-versatileimagefield
[django-versatileimagefield-drf-docs]:https://django-versatileimagefield.readthedocs.io/en/latest/drf_integration.html
[drf-tracking]: https://github.com/aschn/drf-tracking
From 88666629a70f5c3fbe31e11aecd9817338de9c92 Mon Sep 17 00:00:00 2001
From: Asif Saif Uddin
Date: Tue, 31 Aug 2021 18:56:08 +0600
Subject: [PATCH 105/154] stop testing django 3.0 as its EOL (#8136)
---
tox.ini | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/tox.ini b/tox.ini
index f23486a685..25f8418219 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,7 +1,6 @@
[tox]
envlist =
{py35,py36,py37}-django22,
- {py36,py37,py38}-django30,
{py36,py37,py38,py39}-django31,
{py36,py37,py38,py39}-django32,
{py38,py39}-djangomain,
@@ -10,7 +9,6 @@ envlist =
[travis:env]
DJANGO =
2.2: django22
- 3.0: django30
3.1: django31
3.2: django32
main: djangomain
@@ -23,9 +21,8 @@ setenv =
PYTHONWARNINGS=once
deps =
django22: Django>=2.2,<3.0
- django30: Django>=3.0,<3.1
django31: Django>=3.1,<3.2
- django32: Django>=3.2a1,<4.0
+ django32: Django>=3.2,<4.0
djangomain: https://github.com/django/django/archive/main.tar.gz
-rrequirements/requirements-testing.txt
-rrequirements/requirements-optionals.txt
From 6b392a46ea025148a24ce665e9c18e4386dde8fa Mon Sep 17 00:00:00 2001
From: Aditya Mitra <55396651+aditya-mitra@users.noreply.github.com>
Date: Tue, 31 Aug 2021 18:27:02 +0530
Subject: [PATCH 106/154] [FIX] Typo in api-guide/authentication (#8144)
---
docs/api-guide/authentication.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md
index 60544079f1..57bbaeb679 100644
--- a/docs/api-guide/authentication.md
+++ b/docs/api-guide/authentication.md
@@ -13,7 +13,7 @@ Authentication is the mechanism of associating an incoming request with a set of
REST framework provides several authentication schemes out of the box, and also allows you to implement custom schemes.
-Authentication is always run at the very start of the view, before the permission and throttling checks occur, and before any other code is allowed to proceed.
+Authentication always runs at the very start of the view, before the permission and throttling checks occur, and before any other code is allowed to proceed.
The `request.user` property will typically be set to an instance of the `contrib.auth` package's `User` class.
From 4632b5daaed5a71a1be3e7d412a7f9a2e5520b90 Mon Sep 17 00:00:00 2001
From: Ryan Nowakowski
Date: Tue, 31 Aug 2021 08:18:49 -0500
Subject: [PATCH 107/154] Fix subtitle of schemas for filtering (#8145)
Fix a likely copy/paste error
---
docs/api-guide/filtering.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/api-guide/filtering.md b/docs/api-guide/filtering.md
index 478e3bcf95..3541388ca2 100644
--- a/docs/api-guide/filtering.md
+++ b/docs/api-guide/filtering.md
@@ -335,7 +335,7 @@ Generic filters may also present an interface in the browsable API. To do so you
The method should return a rendered HTML string.
-## Pagination & schemas
+## Filtering & schemas
You can also make the filter controls available to the schema autogeneration
that REST framework provides, by implementing a `get_schema_fields()` method. This method should have the following signature:
From cb206e4701dd67f859c015bea111d0e77e364c4a Mon Sep 17 00:00:00 2001
From: Juan Benitez
Date: Fri, 3 Sep 2021 07:00:23 -0500
Subject: [PATCH 108/154] fix: change View class to Throttle class on
SimpleRateThrottle Docstring (#8147)
---
rest_framework/throttling.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rest_framework/throttling.py b/rest_framework/throttling.py
index 0ba2ba66b1..e262b886bc 100644
--- a/rest_framework/throttling.py
+++ b/rest_framework/throttling.py
@@ -52,7 +52,7 @@ class SimpleRateThrottle(BaseThrottle):
A simple cache implementation, that only requires `.get_cache_key()`
to be overridden.
- The rate (requests / seconds) is set by a `rate` attribute on the View
+ The rate (requests / seconds) is set by a `rate` attribute on the Throttle
class. The attribute is a string of the form 'number_of_requests/period'.
Period should be one of: ('s', 'sec', 'm', 'min', 'h', 'hour', 'd', 'day')
From 96001c5de61b5fe7c083bdd8e5810105e3575014 Mon Sep 17 00:00:00 2001
From: Anthony Randall
Date: Fri, 3 Sep 2021 06:23:19 -0600
Subject: [PATCH 109/154] Added an article - implementing rest apis with
embedded privacy from doordash engineering blog (#7956)
* Update tutorials-and-resources.md
* Update tutorials-and-resources.md
---
docs/community/tutorials-and-resources.md | 2 ++
1 file changed, 2 insertions(+)
diff --git a/docs/community/tutorials-and-resources.md b/docs/community/tutorials-and-resources.md
index dae292f50c..23faf79128 100644
--- a/docs/community/tutorials-and-resources.md
+++ b/docs/community/tutorials-and-resources.md
@@ -76,6 +76,7 @@ There are a wide range of resources available for learning and using Django REST
* [Chatbot Using Django REST Framework + api.ai + Slack — Part 1/3][chatbot-using-drf-part1]
* [New Django Admin with DRF and EmberJS... What are the News?][new-django-admin-with-drf-and-emberjs]
* [Blog posts about Django REST Framework][medium-django-rest-framework]
+* [Implementing Rest APIs With Embedded Privacy][doordash-implementing-rest-apis]
### Documentations
* [Classy Django REST Framework][cdrf.co]
@@ -128,3 +129,4 @@ Want your Django REST Framework talk/tutorial/article to be added to our website
[anna-email]: mailto:anna@django-rest-framework.org
[pycon-us-2017]: https://www.youtube.com/watch?v=Rk6MHZdust4
[django-rest-react-valentinog]: https://www.valentinog.com/blog/tutorial-api-django-rest-react/
+[doordash-implementing-rest-apis]: https://doordash.engineering/2013/10/07/implementing-rest-apis-with-embedded-privacy/
From 655e803adfb19b8cb5b94a4895f1baffed55a958 Mon Sep 17 00:00:00 2001
From: Peter Uittenbroek
Date: Fri, 3 Sep 2021 15:37:03 +0200
Subject: [PATCH 110/154] #7157: Fix RemoteUserAuthentication calling django
authenticate with request argument (#7158)
---
rest_framework/authentication.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/rest_framework/authentication.py b/rest_framework/authentication.py
index 9111007c09..382abf1580 100644
--- a/rest_framework/authentication.py
+++ b/rest_framework/authentication.py
@@ -227,6 +227,6 @@ class RemoteUserAuthentication(BaseAuthentication):
header = "REMOTE_USER"
def authenticate(self, request):
- user = authenticate(remote_user=request.META.get(self.header))
+ user = authenticate(request=request, remote_user=request.META.get(self.header))
if user and user.is_active:
return (user, None)
From 9716b1b6b7779543c134856e59f1c1393963e46f Mon Sep 17 00:00:00 2001
From: Ivan Trushin <33528037+WannaFight@users.noreply.github.com>
Date: Mon, 6 Sep 2021 14:18:13 +0300
Subject: [PATCH 111/154] Fix arguments (#7995)
`path()` has no argument `namespace`, it has `name` argument
---
docs/tutorial/quickstart.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/tutorial/quickstart.md b/docs/tutorial/quickstart.md
index ee839790f1..e19577f617 100644
--- a/docs/tutorial/quickstart.md
+++ b/docs/tutorial/quickstart.md
@@ -126,7 +126,7 @@ Okay, now let's wire up the API URLs. On to `tutorial/urls.py`...
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
path('', include(router.urls)),
- path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
+ path('api-auth/', include('rest_framework.urls', name='rest_framework'))
]
Because we're using viewsets instead of views, we can automatically generate the URL conf for our API, by simply registering the viewsets with a router class.
From 9ce541e90990307e06da1b7f5a2576406366a5e5 Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Mon, 6 Sep 2021 12:19:20 +0100
Subject: [PATCH 112/154] Revert "Fix arguments (#7995)" (#8156)
This reverts commit 9716b1b6b7779543c134856e59f1c1393963e46f.
---
docs/tutorial/quickstart.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/tutorial/quickstart.md b/docs/tutorial/quickstart.md
index e19577f617..ee839790f1 100644
--- a/docs/tutorial/quickstart.md
+++ b/docs/tutorial/quickstart.md
@@ -126,7 +126,7 @@ Okay, now let's wire up the API URLs. On to `tutorial/urls.py`...
# Additionally, we include login URLs for the browsable API.
urlpatterns = [
path('', include(router.urls)),
- path('api-auth/', include('rest_framework.urls', name='rest_framework'))
+ path('api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]
Because we're using viewsets instead of views, we can automatically generate the URL conf for our API, by simply registering the viewsets with a router class.
From 73f3325f80a381d1d62ab1b84956295963f445ed Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Fri, 10 Sep 2021 11:32:27 +0100
Subject: [PATCH 113/154] Update stream.io link (#8161)
---
README.md | 2 +-
docs/index.md | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index b8d8ca61b1..e3bcc2a1c2 100644
--- a/README.md
+++ b/README.md
@@ -197,7 +197,7 @@ Please see the [security policy][security-policy].
[bitio-img]: https://raw.githubusercontent.com/encode/django-rest-framework/master/docs/img/premium/bitio-readme.png
[sentry-url]: https://getsentry.com/welcome/
-[stream-url]: https://getstream.io/try-the-api/?utm_source=drf&utm_medium=banner&utm_campaign=drf
+[stream-url]: https://getstream.io/?utm_source=drf&utm_medium=sponsorship&utm_content=developer
[rollbar-url]: https://rollbar.com/?utm_source=django&utm_medium=sponsorship&utm_campaign=freetrial
[esg-url]: https://software.esg-usa.com/
[retool-url]: https://retool.com/?utm_source=djangorest&utm_medium=sponsorship
diff --git a/docs/index.md b/docs/index.md
index 641800b93c..9b667c6691 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -75,7 +75,7 @@ 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=drf&utm_medium=banner&utm_campaign=drf), [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), and [bit.io](https://bit.io/jobs?utm_source=DRF&utm_medium=sponsor&utm_campaign=DRF_sponsorship).*
+*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=drf&utm_medium=sponsorship&utm_content=developer), [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), and [bit.io](https://bit.io/jobs?utm_source=DRF&utm_medium=sponsor&utm_campaign=DRF_sponsorship).*
---
From 761f56ef4025543e9cf39346d25641305e7d957d Mon Sep 17 00:00:00 2001
From: Tom Christie
Date: Fri, 10 Sep 2021 14:45:06 +0100
Subject: [PATCH 114/154] Update stream.io link
---
docs/index.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/docs/index.md b/docs/index.md
index 9b667c6691..f000d2e093 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -67,7 +67,7 @@ continued development by **[signing up for a paid plan][funding]**.