Skip to content

Add support for Python 3.8, Django 3.0 and DRF 3.11 #752

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 39 additions & 12 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
language: python
dist: xenial
sudo: required
cache: pip
# Favor explicit over implicit and use an explicit build matrix.
Expand All @@ -12,6 +13,10 @@ matrix:
- env: TOXENV=py35-django22-drfmaster
- env: TOXENV=py36-django22-drfmaster
- env: TOXENV=py37-django22-drfmaster
- env: TOXENV=py38-django22-drfmaster
- env: TOXENV=py36-django30-drfmaster
- env: TOXENV=py37-django30-drfmaster
- env: TOXENV=py38-django30-drfmaster

include:
- python: 3.6
Expand All @@ -21,50 +26,72 @@ matrix:

- python: 3.5
env: TOXENV=py35-django111-drf310
- python: 3.5
env: TOXENV=py35-django111-drf311
- python: 3.5
env: TOXENV=py35-django111-drfmaster
- python: 3.5
env: TOXENV=py35-django21-drf310
- python: 3.5
env: TOXENV=py35-django21-drf311
- python: 3.5
env: TOXENV=py35-django21-drfmaster
- python: 3.5
dist: xenial
env: TOXENV=py35-django22-drf310
- python: 3.5
dist: xenial
env: TOXENV=py35-django22-drf311
- python: 3.5
env: TOXENV=py35-django22-drfmaster

- python: 3.6
env: TOXENV=py36-django111-drf310
- python: 3.6
env: TOXENV=py36-django111-drf311
- python: 3.6
env: TOXENV=py36-django111-drfmaster
- python: 3.6
env: TOXENV=py36-django21-drf310
- python: 3.6
env: TOXENV=py36-django21-drf311
- python: 3.6
env: TOXENV=py36-django21-drfmaster
- python: 3.6
dist: xenial
env: TOXENV=py36-django22-drf310
- python: 3.6
dist: xenial
env: TOXENV=py36-django22-drf311
- python: 3.6
env: TOXENV=py36-django22-drfmaster
- python: 3.6
env: TOXENV=py36-django30-drf311
- python: 3.6
env: TOXENV=py36-django30-drfmaster

- python: 3.7
dist: xenial
sudo: required
env: TOXENV=py37-django21-drf310
- python: 3.7
dist: xenial
sudo: required
env: TOXENV=py37-django21-drf311
- python: 3.7
env: TOXENV=py37-django21-drfmaster
- python: 3.7
dist: xenial
sudo: required
env: TOXENV=py37-django22-drf310
- python: 3.7
dist: xenial
sudo: required
env: TOXENV=py37-django22-drf311
- python: 3.7
env: TOXENV=py37-django22-drfmaster
- python: 3.7
env: TOXENV=py37-django30-drf311
- python: 3.7
env: TOXENV=py37-django30-drfmaster

- python: 3.8
env: TOXENV=py38-django22-drf311
- python: 3.8
env: TOXENV=py38-django22-drfmaster
- python: 3.8
env: TOXENV=py38-django30-drf311
- python: 3.8
env: TOXENV=py38-django30-drfmaster

install:
- pip install tox
script:
Expand Down
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
Note that in line with [Django REST Framework policy](http://www.django-rest-framework.org/topics/release-notes/),
any parts of the framework not mentioned in the documentation should generally be considered private API, and may be subject to change.

## [Unreleased]

### Added

* Added support for Python 3.8
* Added support for Django REST framework 3.11
* Added support for Django 3.0

## [3.0.0] - 2019-10-14

This release is not backwards compatible. For easy migration best upgrade first to version
Expand Down
6 changes: 3 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,9 @@ As a Django REST Framework JSON API (short DJA) we are trying to address followi
Requirements
------------

1. Python (3.5, 3.6, 3.7)
2. Django (1.11, 2.1, 2.2)
3. Django REST Framework (3.10)
1. Python (3.5, 3.6, 3.7, 3.8)
2. Django (1.11, 2.1, 2.2, 3.0)
3. Django REST Framework (3.10, 3.11)

We **highly** recommend and only officially support the latest patch release of each Python, Django and REST Framework series.

Expand Down
6 changes: 3 additions & 3 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@ like the following:

## Requirements

1. Python (3.5, 3.6, 3.7)
2. Django (1.11, 2.1, 2.2)
3. Django REST Framework (3.10)
1. Python (3.5, 3.6, 3.7, 3.8)
2. Django (1.11, 2.1, 2.2, 3.0)
3. Django REST Framework (3.10, 3.11)

We **highly** recommend and only officially support the latest patch release of each Python, Django and REST Framework series.

Expand Down
4 changes: 2 additions & 2 deletions example/api/resources/identity.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ def posts(self, request):
posts = [{'id': 1, 'title': 'Test Blog Post'}]

data = {
encoding.force_text('identities'): IdentitySerializer(identities, many=True).data,
encoding.force_text('posts'): PostSerializer(posts, many=True).data,
encoding.force_str('identities'): IdentitySerializer(identities, many=True).data,
encoding.force_str('posts'): PostSerializer(posts, many=True).data,
}
return Response(utils.format_field_names(data, format_type='camelize'))

Expand Down
2 changes: 1 addition & 1 deletion example/tests/test_format_keys.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def test_camelization(self):
'data': [
{
'type': 'users',
'id': encoding.force_text(user.pk),
'id': encoding.force_str(user.pk),
'attributes': {
'firstName': user.first_name,
'lastName': user.last_name,
Expand Down
12 changes: 6 additions & 6 deletions example/tests/test_model_viewsets.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def test_key_in_list_result(self):
'data': [
{
'type': 'users',
'id': encoding.force_text(user.pk),
'id': encoding.force_str(user.pk),
'attributes': {
'first-name': user.first_name,
'last-name': user.last_name,
Expand Down Expand Up @@ -72,7 +72,7 @@ def test_page_two_in_list_result(self):
'data': [
{
'type': 'users',
'id': encoding.force_text(user.pk),
'id': encoding.force_str(user.pk),
'attributes': {
'first-name': user.first_name,
'last-name': user.last_name,
Expand Down Expand Up @@ -112,7 +112,7 @@ def test_page_range_in_list_result(self):
'data': [
{
'type': 'users',
'id': encoding.force_text(users[0].pk),
'id': encoding.force_str(users[0].pk),
'attributes': {
'first-name': users[0].first_name,
'last-name': users[0].last_name,
Expand All @@ -121,7 +121,7 @@ def test_page_range_in_list_result(self):
},
{
'type': 'users',
'id': encoding.force_text(users[1].pk),
'id': encoding.force_str(users[1].pk),
'attributes': {
'first-name': users[1].first_name,
'last-name': users[1].last_name,
Expand Down Expand Up @@ -157,7 +157,7 @@ def test_key_in_detail_result(self):
expected = {
'data': {
'type': 'users',
'id': encoding.force_text(self.miles.pk),
'id': encoding.force_str(self.miles.pk),
'attributes': {
'first-name': self.miles.first_name,
'last-name': self.miles.last_name,
Expand Down Expand Up @@ -193,7 +193,7 @@ def test_key_in_post(self):
data = {
'data': {
'type': 'users',
'id': encoding.force_text(self.miles.pk),
'id': encoding.force_str(self.miles.pk),
'attributes': {
'first-name': self.miles.first_name,
'last-name': self.miles.last_name,
Expand Down
4 changes: 2 additions & 2 deletions example/tests/test_sideload_resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,5 @@ def test_get_sideloaded_data(self):

self.assertEqual(
sorted(content.keys()),
[encoding.force_text('identities'),
encoding.force_text('posts')])
[encoding.force_str('identities'),
encoding.force_str('posts')])
2 changes: 1 addition & 1 deletion rest_framework_json_api/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from rest_framework import exceptions, status

from rest_framework_json_api import utils
Expand Down
6 changes: 3 additions & 3 deletions rest_framework_json_api/metadata.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from collections import OrderedDict

from django.db.models.fields import related
from django.utils.encoding import force_text
from django.utils.encoding import force_str
from rest_framework import serializers
from rest_framework.metadata import SimpleMetadata
from rest_framework.settings import api_settings
Expand Down Expand Up @@ -123,7 +123,7 @@ def get_field_info(self, field):
for attr in attrs:
value = getattr(field, attr, None)
if value is not None and value != '':
field_info[attr] = force_text(value, strings_only=True)
field_info[attr] = force_str(value, strings_only=True)

if getattr(field, 'child', None):
field_info['child'] = self.get_field_info(field.child)
Expand All @@ -138,7 +138,7 @@ def get_field_info(self, field):
field_info['choices'] = [
{
'value': choice_value,
'display_name': force_text(choice_name, strings_only=True)
'display_name': force_str(choice_name, strings_only=True)
}
for choice_value, choice_name in field.choices.items()
]
Expand Down
2 changes: 1 addition & 1 deletion rest_framework_json_api/relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import inflection
from django.core.exceptions import ImproperlyConfigured
from django.urls import NoReverseMatch
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from rest_framework.fields import MISSING_ERROR_MESSAGE, SkipField
from rest_framework.relations import MANY_RELATION_KWARGS
from rest_framework.relations import ManyRelatedField as DRFManyRelatedField
Expand Down
12 changes: 6 additions & 6 deletions rest_framework_json_api/renderers.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ def extract_relationships(cls, fields, resource, resource_instance):
relation_data.append(
OrderedDict([
('type', relation_type),
('id', encoding.force_text(related_object.pk))
('id', encoding.force_str(related_object.pk))
])
)

Expand Down Expand Up @@ -168,7 +168,7 @@ def extract_relationships(cls, fields, resource, resource_instance):
relation_data = {
'data': (
OrderedDict([
('type', relation_type), ('id', encoding.force_text(relation_id))
('type', relation_type), ('id', encoding.force_str(relation_id))
])
if relation_id is not None else None)
}
Expand Down Expand Up @@ -231,7 +231,7 @@ def extract_relationships(cls, fields, resource, resource_instance):

relation_data.append(OrderedDict([
('type', nested_resource_instance_type),
('id', encoding.force_text(nested_resource_instance.pk))
('id', encoding.force_str(nested_resource_instance.pk))
]))
data.update({
field_name: {
Expand Down Expand Up @@ -264,7 +264,7 @@ def extract_relationships(cls, fields, resource, resource_instance):

relation_data.append(OrderedDict([
('type', nested_resource_instance_type),
('id', encoding.force_text(nested_resource_instance.pk))
('id', encoding.force_str(nested_resource_instance.pk))
]))

data.update({field_name: {'data': relation_data}})
Expand All @@ -287,7 +287,7 @@ def extract_relationships(cls, fields, resource, resource_instance):
'data': (
OrderedDict([
('type', relation_type),
('id', encoding.force_text(relation_instance_id))
('id', encoding.force_str(relation_instance_id))
]) if resource.get(field_name) else None)
}
})
Expand Down Expand Up @@ -486,7 +486,7 @@ def build_json_resource_obj(cls, fields, resource, resource_instance, resource_n
resource_name = utils.get_resource_type_from_instance(resource_instance)
resource_data = [
('type', resource_name),
('id', encoding.force_text(resource_instance.pk) if resource_instance else None),
('id', encoding.force_str(resource_instance.pk) if resource_instance else None),
('attributes', cls.extract_attributes(fields, resource)),
]
relationships = cls.extract_relationships(fields, resource, resource_instance)
Expand Down
2 changes: 1 addition & 1 deletion rest_framework_json_api/serializers.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import inflection
from django.core.exceptions import ObjectDoesNotExist
from django.db.models.query import QuerySet
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from rest_framework.exceptions import ParseError
from rest_framework.serializers import * # noqa: F403

Expand Down
4 changes: 2 additions & 2 deletions rest_framework_json_api/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from django.http import Http404
from django.utils import encoding
from django.utils.module_loading import import_string as import_class_from_dotted_path
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from rest_framework import exceptions
from rest_framework.exceptions import APIException

Expand Down Expand Up @@ -341,7 +341,7 @@ def format_drf_errors(response, context, exc):
def format_error_object(message, pointer, response):
error_obj = {
'detail': message,
'status': encoding.force_text(response.status_code),
'status': encoding.force_str(response.status_code),
}
if pointer is not None:
error_obj['source'] = {
Expand Down
8 changes: 6 additions & 2 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,15 +1,19 @@
[tox]
envlist =
py{35,36}-django111-drf{310,master},
py{35,36,37}-django{21,22}-drf{310,master},
py{35,36}-django{111}-drf{310,311,master},
py{35,36,37}-django{21,22}-drf{310,311,master},
py38-django22-drf{311,master},
py{36,37,38}-django{30}-drf{311,master},
lint,docs

[testenv]
deps =
django111: Django>=1.11,<1.12
django21: Django>=2.1,<2.2
django22: Django>=2.2,<2.3
django30: Django>=3.0,<3.1
drf310: djangorestframework>=3.10.2,<3.11
drf311: djangorestframework>=3.11,<3.12
drfmaster: https://github.com/encode/django-rest-framework/archive/master.zip
-rrequirements/requirements-testing.txt
-rrequirements/requirements-optionals.txt
Expand Down