mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-11-04 09:57:55 +03:00 
			
		
		
		
	Version 3.14.0 proposal (#8599)
* Version 3.14.0 * Update docs/community/release-notes.md to use proper links. Co-authored-by: Adam Johnson <me@adamj.eu> * Add community announcement page for version 3.14 * Remove deprecated NullBooleanField. * Change openapi _get_reference removal to 3.15 This deprecation was never released in the 3.13.x series and therefore can't be removed at the same time the replacement is released. * Removing deprecated openapi methods. Co-authored-by: Adam Johnson <me@adamj.eu>
This commit is contained in:
		
							parent
							
								
									51f1aff162
								
							
						
					
					
						commit
						b658915846
					
				| 
						 | 
				
			
			@ -159,14 +159,6 @@ Corresponds to `django.db.models.fields.BooleanField`.
 | 
			
		|||
 | 
			
		||||
**Signature:** `BooleanField()`
 | 
			
		||||
 | 
			
		||||
## NullBooleanField
 | 
			
		||||
 | 
			
		||||
A boolean representation that also accepts `None` as a valid value.
 | 
			
		||||
 | 
			
		||||
Corresponds to `django.db.models.fields.NullBooleanField`.
 | 
			
		||||
 | 
			
		||||
**Signature:** `NullBooleanField()`
 | 
			
		||||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
# String fields
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										62
									
								
								docs/community/3.14-announcement.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								docs/community/3.14-announcement.md
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,62 @@
 | 
			
		|||
<style>
 | 
			
		||||
.promo li a {
 | 
			
		||||
    float: left;
 | 
			
		||||
    width: 130px;
 | 
			
		||||
    height: 20px;
 | 
			
		||||
    text-align: center;
 | 
			
		||||
    margin: 10px 30px;
 | 
			
		||||
    padding: 150px 0 0 0;
 | 
			
		||||
    background-position: 0 50%;
 | 
			
		||||
    background-size: 130px auto;
 | 
			
		||||
    background-repeat: no-repeat;
 | 
			
		||||
    font-size: 120%;
 | 
			
		||||
    color: black;
 | 
			
		||||
}
 | 
			
		||||
.promo li {
 | 
			
		||||
    list-style: none;
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
 | 
			
		||||
# Django REST framework 3.14
 | 
			
		||||
 | 
			
		||||
## Django 4.1 support
 | 
			
		||||
 | 
			
		||||
The latest release now fully supports Django 4.1.
 | 
			
		||||
 | 
			
		||||
Our requirements are now:
 | 
			
		||||
 | 
			
		||||
* Python 3.6+
 | 
			
		||||
* Django 4.1, 4.0, 3.2, 3.1, 2.2 (LTS)
 | 
			
		||||
 | 
			
		||||
## `raise_exceptions` argument for `is_valid` is now keyword-only.
 | 
			
		||||
 | 
			
		||||
Calling `serializer_instance.is_valid(True)` is no longer acceptable syntax.
 | 
			
		||||
If you'd like to use the `raise_exceptions` argument, you must use it as a
 | 
			
		||||
keyword argument.
 | 
			
		||||
 | 
			
		||||
See Pull Request [#7952](https://github.com/encode/django-rest-framework/pull/7952) for more details.
 | 
			
		||||
 | 
			
		||||
## `ManyRelatedField` supports returning the default when the source attribute doesn't exist.
 | 
			
		||||
 | 
			
		||||
Previously, if you used a serializer field with `many=True` with a dot notated source field
 | 
			
		||||
that didn't exist, it would raise an `AttributeError`. Now it will return the default or be
 | 
			
		||||
skipped depending on the other arguments.
 | 
			
		||||
 | 
			
		||||
See Pull Request [#7574](https://github.com/encode/django-rest-framework/pull/7574) for more details.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
## Make Open API `get_reference` public.
 | 
			
		||||
 | 
			
		||||
Returns a reference to the serializer component. This may be useful if you override `get_schema()`.
 | 
			
		||||
 | 
			
		||||
## Change semantic of OR of two permission classes.
 | 
			
		||||
 | 
			
		||||
When OR-ing two permissions, the request has to pass either class's `has_permission() and has_object_permission()`.
 | 
			
		||||
 | 
			
		||||
Previously, both class's `has_permission()` was ignored when OR-ing two permissions together.
 | 
			
		||||
 | 
			
		||||
See Pull Request [#7522](https://github.com/encode/django-rest-framework/pull/7522) for more details.
 | 
			
		||||
 | 
			
		||||
## Minor fixes and improvements
 | 
			
		||||
 | 
			
		||||
There are a number of minor fixes and improvements in this release. See the [release notes](release-notes.md) page for a complete listing.
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +34,23 @@ You can determine your currently installed version using `pip show`:
 | 
			
		|||
 | 
			
		||||
---
 | 
			
		||||
 | 
			
		||||
## 3.14.x series
 | 
			
		||||
 | 
			
		||||
### 3.14.0
 | 
			
		||||
 | 
			
		||||
Date: 10th August 2022
 | 
			
		||||
 | 
			
		||||
* Enforce `is_valid(raise_exception=False)` as a keyword-only argument. [[#7952](https://github.com/encode/django-rest-framework/pull/7952)]
 | 
			
		||||
* Django 4.1 compatability. [[#8591](https://github.com/encode/django-rest-framework/pull/8591)]
 | 
			
		||||
* Stop calling `set_context` on Validators. [[#8589](https://github.com/encode/django-rest-framework/pull/8589)]
 | 
			
		||||
* Return `NotImplemented` from `ErrorDetails.__ne__`. [[#8538](https://github.com/encode/django-rest-framework/pull/8538)]
 | 
			
		||||
* Don't evaluate `DateTimeField.default_timezone` when a custom timezone is set. [[#8531](https://github.com/encode/django-rest-framework/pull/8531)]
 | 
			
		||||
* Make relative URLs clickable in Browseable API. [[#8464](https://github.com/encode/django-rest-framework/pull/8464)]
 | 
			
		||||
* Support `ManyRelatedField` falling back to the default value when the attribute specified by dot notation doesn't exist. Matches `ManyRelatedField.get_attribute` to `Field.get_attribute`. [[#7574](https://github.com/encode/django-rest-framework/pull/7574)]
 | 
			
		||||
* Make `schemas.openapi.get_reference` public. [[#7515](https://github.com/encode/django-rest-framework/pull/7515)]
 | 
			
		||||
* Make `ReturnDict` support `dict` union operators on Python 3.9 and later. [[#8302](https://github.com/encode/django-rest-framework/pull/8302)]
 | 
			
		||||
* Update throttling to check if `request.user` is set before checking if the user is authenticated. [[#8370](https://github.com/encode/django-rest-framework/pull/8370)]
 | 
			
		||||
 | 
			
		||||
## 3.13.x series
 | 
			
		||||
 | 
			
		||||
### 3.13.1
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,7 @@ ______ _____ _____ _____    __
 | 
			
		|||
import django
 | 
			
		||||
 | 
			
		||||
__title__ = 'Django REST framework'
 | 
			
		||||
__version__ = '3.13.1'
 | 
			
		||||
__version__ = '3.14.0'
 | 
			
		||||
__author__ = 'Tom Christie'
 | 
			
		||||
__license__ = 'BSD 3-Clause'
 | 
			
		||||
__copyright__ = 'Copyright 2011-2019 Encode OSS Ltd'
 | 
			
		||||
| 
						 | 
				
			
			@ -35,3 +35,7 @@ class RemovedInDRF313Warning(DeprecationWarning):
 | 
			
		|||
 | 
			
		||||
class RemovedInDRF314Warning(PendingDeprecationWarning):
 | 
			
		||||
    pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class RemovedInDRF315Warning(PendingDeprecationWarning):
 | 
			
		||||
    pass
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,6 @@ import functools
 | 
			
		|||
import inspect
 | 
			
		||||
import re
 | 
			
		||||
import uuid
 | 
			
		||||
import warnings
 | 
			
		||||
from collections import OrderedDict
 | 
			
		||||
from collections.abc import Mapping
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -30,7 +29,7 @@ from django.utils.ipv6 import clean_ipv6_address
 | 
			
		|||
from django.utils.translation import gettext_lazy as _
 | 
			
		||||
from pytz.exceptions import InvalidTimeError
 | 
			
		||||
 | 
			
		||||
from rest_framework import ISO_8601, RemovedInDRF314Warning
 | 
			
		||||
from rest_framework import ISO_8601
 | 
			
		||||
from rest_framework.exceptions import ErrorDetail, ValidationError
 | 
			
		||||
from rest_framework.settings import api_settings
 | 
			
		||||
from rest_framework.utils import html, humanize_datetime, json, representation
 | 
			
		||||
| 
						 | 
				
			
			@ -712,23 +711,6 @@ class BooleanField(Field):
 | 
			
		|||
        return bool(value)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class NullBooleanField(BooleanField):
 | 
			
		||||
    initial = None
 | 
			
		||||
 | 
			
		||||
    def __init__(self, **kwargs):
 | 
			
		||||
        warnings.warn(
 | 
			
		||||
            "The `NullBooleanField` is deprecated and will be removed starting "
 | 
			
		||||
            "with 3.14. Instead use the `BooleanField` field and set "
 | 
			
		||||
            "`allow_null=True` which does the same thing.",
 | 
			
		||||
            RemovedInDRF314Warning, stacklevel=2
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        assert 'allow_null' not in kwargs, '`allow_null` is not a valid option.'
 | 
			
		||||
        kwargs['allow_null'] = True
 | 
			
		||||
 | 
			
		||||
        super().__init__(**kwargs)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# String types...
 | 
			
		||||
 | 
			
		||||
class CharField(Field):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,7 +36,6 @@ class SimpleMetadata(BaseMetadata):
 | 
			
		|||
    label_lookup = ClassLookupDict({
 | 
			
		||||
        serializers.Field: 'field',
 | 
			
		||||
        serializers.BooleanField: 'boolean',
 | 
			
		||||
        serializers.NullBooleanField: 'boolean',
 | 
			
		||||
        serializers.CharField: 'string',
 | 
			
		||||
        serializers.UUIDField: 'string',
 | 
			
		||||
        serializers.URLField: 'url',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,7 +13,7 @@ from django.db import models
 | 
			
		|||
from django.utils.encoding import force_str
 | 
			
		||||
 | 
			
		||||
from rest_framework import (
 | 
			
		||||
    RemovedInDRF314Warning, exceptions, renderers, serializers
 | 
			
		||||
    RemovedInDRF315Warning, exceptions, renderers, serializers
 | 
			
		||||
)
 | 
			
		||||
from rest_framework.compat import uritemplate
 | 
			
		||||
from rest_framework.fields import _UnvalidatedField, empty
 | 
			
		||||
| 
						 | 
				
			
			@ -713,106 +713,10 @@ class AutoSchema(ViewInspector):
 | 
			
		|||
 | 
			
		||||
        return [path.split('/')[0].replace('_', '-')]
 | 
			
		||||
 | 
			
		||||
    def _get_path_parameters(self, path, method):
 | 
			
		||||
        warnings.warn(
 | 
			
		||||
            "Method `_get_path_parameters()` has been renamed to `get_path_parameters()`. "
 | 
			
		||||
            "The old name will be removed in DRF v3.14.",
 | 
			
		||||
            RemovedInDRF314Warning, stacklevel=2
 | 
			
		||||
        )
 | 
			
		||||
        return self.get_path_parameters(path, method)
 | 
			
		||||
 | 
			
		||||
    def _get_filter_parameters(self, path, method):
 | 
			
		||||
        warnings.warn(
 | 
			
		||||
            "Method `_get_filter_parameters()` has been renamed to `get_filter_parameters()`. "
 | 
			
		||||
            "The old name will be removed in DRF v3.14.",
 | 
			
		||||
            RemovedInDRF314Warning, stacklevel=2
 | 
			
		||||
        )
 | 
			
		||||
        return self.get_filter_parameters(path, method)
 | 
			
		||||
 | 
			
		||||
    def _get_responses(self, path, method):
 | 
			
		||||
        warnings.warn(
 | 
			
		||||
            "Method `_get_responses()` has been renamed to `get_responses()`. "
 | 
			
		||||
            "The old name will be removed in DRF v3.14.",
 | 
			
		||||
            RemovedInDRF314Warning, stacklevel=2
 | 
			
		||||
        )
 | 
			
		||||
        return self.get_responses(path, method)
 | 
			
		||||
 | 
			
		||||
    def _get_request_body(self, path, method):
 | 
			
		||||
        warnings.warn(
 | 
			
		||||
            "Method `_get_request_body()` has been renamed to `get_request_body()`. "
 | 
			
		||||
            "The old name will be removed in DRF v3.14.",
 | 
			
		||||
            RemovedInDRF314Warning, stacklevel=2
 | 
			
		||||
        )
 | 
			
		||||
        return self.get_request_body(path, method)
 | 
			
		||||
 | 
			
		||||
    def _get_serializer(self, path, method):
 | 
			
		||||
        warnings.warn(
 | 
			
		||||
            "Method `_get_serializer()` has been renamed to `get_serializer()`. "
 | 
			
		||||
            "The old name will be removed in DRF v3.14.",
 | 
			
		||||
            RemovedInDRF314Warning, stacklevel=2
 | 
			
		||||
        )
 | 
			
		||||
        return self.get_serializer(path, method)
 | 
			
		||||
 | 
			
		||||
    def _get_paginator(self):
 | 
			
		||||
        warnings.warn(
 | 
			
		||||
            "Method `_get_paginator()` has been renamed to `get_paginator()`. "
 | 
			
		||||
            "The old name will be removed in DRF v3.14.",
 | 
			
		||||
            RemovedInDRF314Warning, stacklevel=2
 | 
			
		||||
        )
 | 
			
		||||
        return self.get_paginator()
 | 
			
		||||
 | 
			
		||||
    def _map_field_validators(self, field, schema):
 | 
			
		||||
        warnings.warn(
 | 
			
		||||
            "Method `_map_field_validators()` has been renamed to `map_field_validators()`. "
 | 
			
		||||
            "The old name will be removed in DRF v3.14.",
 | 
			
		||||
            RemovedInDRF314Warning, stacklevel=2
 | 
			
		||||
        )
 | 
			
		||||
        return self.map_field_validators(field, schema)
 | 
			
		||||
 | 
			
		||||
    def _map_serializer(self, serializer):
 | 
			
		||||
        warnings.warn(
 | 
			
		||||
            "Method `_map_serializer()` has been renamed to `map_serializer()`. "
 | 
			
		||||
            "The old name will be removed in DRF v3.14.",
 | 
			
		||||
            RemovedInDRF314Warning, stacklevel=2
 | 
			
		||||
        )
 | 
			
		||||
        return self.map_serializer(serializer)
 | 
			
		||||
 | 
			
		||||
    def _map_field(self, field):
 | 
			
		||||
        warnings.warn(
 | 
			
		||||
            "Method `_map_field()` has been renamed to `map_field()`. "
 | 
			
		||||
            "The old name will be removed in DRF v3.14.",
 | 
			
		||||
            RemovedInDRF314Warning, stacklevel=2
 | 
			
		||||
        )
 | 
			
		||||
        return self.map_field(field)
 | 
			
		||||
 | 
			
		||||
    def _map_choicefield(self, field):
 | 
			
		||||
        warnings.warn(
 | 
			
		||||
            "Method `_map_choicefield()` has been renamed to `map_choicefield()`. "
 | 
			
		||||
            "The old name will be removed in DRF v3.14.",
 | 
			
		||||
            RemovedInDRF314Warning, stacklevel=2
 | 
			
		||||
        )
 | 
			
		||||
        return self.map_choicefield(field)
 | 
			
		||||
 | 
			
		||||
    def _get_pagination_parameters(self, path, method):
 | 
			
		||||
        warnings.warn(
 | 
			
		||||
            "Method `_get_pagination_parameters()` has been renamed to `get_pagination_parameters()`. "
 | 
			
		||||
            "The old name will be removed in DRF v3.14.",
 | 
			
		||||
            RemovedInDRF314Warning, stacklevel=2
 | 
			
		||||
        )
 | 
			
		||||
        return self.get_pagination_parameters(path, method)
 | 
			
		||||
 | 
			
		||||
    def _allows_filters(self, path, method):
 | 
			
		||||
        warnings.warn(
 | 
			
		||||
            "Method `_allows_filters()` has been renamed to `allows_filters()`. "
 | 
			
		||||
            "The old name will be removed in DRF v3.14.",
 | 
			
		||||
            RemovedInDRF314Warning, stacklevel=2
 | 
			
		||||
        )
 | 
			
		||||
        return self.allows_filters(path, method)
 | 
			
		||||
 | 
			
		||||
    def _get_reference(self, serializer):
 | 
			
		||||
        warnings.warn(
 | 
			
		||||
            "Method `_get_reference()` has been renamed to `get_reference()`. "
 | 
			
		||||
            "The old name will be removed in DRF v3.14.",
 | 
			
		||||
            RemovedInDRF314Warning, stacklevel=2
 | 
			
		||||
            "The old name will be removed in DRF v3.15.",
 | 
			
		||||
            RemovedInDRF315Warning, stacklevel=2
 | 
			
		||||
        )
 | 
			
		||||
        return self.get_reference(serializer)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,7 +52,7 @@ from rest_framework.fields import (  # NOQA # isort:skip
 | 
			
		|||
    BooleanField, CharField, ChoiceField, DateField, DateTimeField, DecimalField,
 | 
			
		||||
    DictField, DurationField, EmailField, Field, FileField, FilePathField, FloatField,
 | 
			
		||||
    HiddenField, HStoreField, IPAddressField, ImageField, IntegerField, JSONField,
 | 
			
		||||
    ListField, ModelField, MultipleChoiceField, NullBooleanField, ReadOnlyField,
 | 
			
		||||
    ListField, ModelField, MultipleChoiceField, ReadOnlyField,
 | 
			
		||||
    RegexField, SerializerMethodField, SlugField, TimeField, URLField, UUIDField,
 | 
			
		||||
)
 | 
			
		||||
from rest_framework.relations import (  # NOQA # isort:skip
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -679,9 +679,9 @@ class TestBooleanField(FieldValues):
 | 
			
		|||
            assert exc_info.value.detail == expected
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestNullBooleanField(TestBooleanField):
 | 
			
		||||
class TestNullableBooleanField(TestBooleanField):
 | 
			
		||||
    """
 | 
			
		||||
    Valid and invalid values for `NullBooleanField`.
 | 
			
		||||
    Valid and invalid values for `BooleanField` when `allow_null=True`.
 | 
			
		||||
    """
 | 
			
		||||
    valid_inputs = {
 | 
			
		||||
        'true': True,
 | 
			
		||||
| 
						 | 
				
			
			@ -706,16 +706,6 @@ class TestNullBooleanField(TestBooleanField):
 | 
			
		|||
    field = serializers.BooleanField(allow_null=True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestNullableBooleanField(TestNullBooleanField):
 | 
			
		||||
    """
 | 
			
		||||
    Valid and invalid values for `BooleanField` when `allow_null=True`.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def field(self):
 | 
			
		||||
        return serializers.BooleanField(allow_null=True)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# String types...
 | 
			
		||||
 | 
			
		||||
class TestCharField(FieldValues):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user