Repository: django-json-api/django-rest-framework-json-api

Issue:
add Django 3.1
[Django 3.1](https://docs.djangoproject.com/en/3.1/releases/3.1/) is recently released. Upstream DRF has passing tests for it but has not yet published support for it. 


Discussion:

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -84,6 +84,7 @@ def get_package_data(package):
         'Programming Language :: Python :: 3.5',
         'Programming Language :: Python :: 3.6',
         'Programming Language :: Python :: 3.7',
+        'Programming Language :: Python :: 3.8',
         'Topic :: Internet :: WWW/HTTP',
         'Topic :: Software Development :: Libraries :: Application Frameworks',
         'Topic :: Software Development :: Libraries :: Python Modules',
@@ -91,7 +92,7 @@ def get_package_data(package):
     install_requires=[
         'inflection>=0.3.0',
         'djangorestframework>=3.12,<3.13',
-        'django>=2.2,<3.1',
+        'django>=2.2,<3.2',
     ],
     extras_require={
         'django-polymorphic': ['django-polymorphic>=2.0'],


Test patch:
diff --git a/example/tests/test_errors.py b/example/tests/test_errors.py
--- a/example/tests/test_errors.py
+++ b/example/tests/test_errors.py
@@ -1,7 +1,6 @@
 import pytest
-from django.conf.urls import url
 from django.test import override_settings
-from django.urls import reverse
+from django.urls import path, reverse
 from rest_framework import views
 
 from rest_framework_json_api import serializers
@@ -51,8 +50,8 @@ def post(self, request, *args, **kwargs):
 
 
 urlpatterns = [
-    url('entries-nested', DummyTestView.as_view(),
-        name='entries-nested-list')
+    path('entries-nested', DummyTestView.as_view(),
+         name='entries-nested-list')
 ]
 
 
diff --git a/example/tests/test_parsers.py b/example/tests/test_parsers.py
--- a/example/tests/test_parsers.py
+++ b/example/tests/test_parsers.py
@@ -1,9 +1,8 @@
 import json
 from io import BytesIO
 
-from django.conf.urls import url
 from django.test import TestCase, override_settings
-from django.urls import reverse
+from django.urls import path, reverse
 from rest_framework import status, views
 from rest_framework.exceptions import ParseError
 from rest_framework.response import Response
@@ -104,7 +103,7 @@ def patch(self, request, *args, **kwargs):
 
 
 urlpatterns = [
-    url(r'repeater$', DummyAPIView.as_view(), name='repeater'),
+    path('repeater', DummyAPIView.as_view(), name='repeater'),
 ]
 
 
diff --git a/example/urls_test.py b/example/urls_test.py
--- a/example/urls_test.py
+++ b/example/urls_test.py
@@ -1,4 +1,4 @@
-from django.conf.urls import include, url
+from django.conf.urls import re_path
 from rest_framework import routers
 
 from .api.resources.identity import GenericIdentity, Identity
@@ -41,50 +41,50 @@
 router.register(r'identities', Identity)
 
 urlpatterns = [
-    url(r'^', include(router.urls)),
-
     # old tests
-    url(r'identities/default/(?P<pk>\d+)$',
-        GenericIdentity.as_view(), name='user-default'),
+    re_path(r'identities/default/(?P<pk>\d+)$',
+            GenericIdentity.as_view(), name='user-default'),
 
 
-    url(r'^entries/(?P<entry_pk>[^/.]+)/blog$',
-        BlogViewSet.as_view({'get': 'retrieve'}),
-        name='entry-blog'
-        ),
-    url(r'^entries/(?P<entry_pk>[^/.]+)/comments$',
-        CommentViewSet.as_view({'get': 'list'}),
-        name='entry-comments'
-        ),
-    url(r'^entries/(?P<entry_pk>[^/.]+)/suggested/$',
-        EntryViewSet.as_view({'get': 'list'}),
-        name='entry-suggested'
-        ),
-    url(r'^drf-entries/(?P<entry_pk>[^/.]+)/suggested/$',
-        DRFEntryViewSet.as_view({'get': 'list'}),
-        name='drf-entry-suggested'
-        ),
-    url(r'entries/(?P<entry_pk>[^/.]+)/authors$',
-        AuthorViewSet.as_view({'get': 'list'}),
-        name='entry-authors'),
-    url(r'entries/(?P<entry_pk>[^/.]+)/featured$',
-        EntryViewSet.as_view({'get': 'retrieve'}),
-        name='entry-featured'),
+    re_path(r'^entries/(?P<entry_pk>[^/.]+)/blog$',
+            BlogViewSet.as_view({'get': 'retrieve'}),
+            name='entry-blog'
+            ),
+    re_path(r'^entries/(?P<entry_pk>[^/.]+)/comments$',
+            CommentViewSet.as_view({'get': 'list'}),
+            name='entry-comments'
+            ),
+    re_path(r'^entries/(?P<entry_pk>[^/.]+)/suggested/$',
+            EntryViewSet.as_view({'get': 'list'}),
+            name='entry-suggested'
+            ),
+    re_path(r'^drf-entries/(?P<entry_pk>[^/.]+)/suggested/$',
+            DRFEntryViewSet.as_view({'get': 'list'}),
+            name='drf-entry-suggested'
+            ),
+    re_path(r'entries/(?P<entry_pk>[^/.]+)/authors$',
+            AuthorViewSet.as_view({'get': 'list'}),
+            name='entry-authors'),
+    re_path(r'entries/(?P<entry_pk>[^/.]+)/featured$',
+            EntryViewSet.as_view({'get': 'retrieve'}),
+            name='entry-featured'),
 
-    url(r'^authors/(?P<pk>[^/.]+)/(?P<related_field>\w+)/$',
-        AuthorViewSet.as_view({'get': 'retrieve_related'}),
-        name='author-related'),
+    re_path(r'^authors/(?P<pk>[^/.]+)/(?P<related_field>\w+)/$',
+            AuthorViewSet.as_view({'get': 'retrieve_related'}),
+            name='author-related'),
 
-    url(r'^entries/(?P<pk>[^/.]+)/relationships/(?P<related_field>\w+)$',
-        EntryRelationshipView.as_view(),
-        name='entry-relationships'),
-    url(r'^blogs/(?P<pk>[^/.]+)/relationships/(?P<related_field>\w+)$',
-        BlogRelationshipView.as_view(),
-        name='blog-relationships'),
-    url(r'^comments/(?P<pk>[^/.]+)/relationships/(?P<related_field>\w+)$',
-        CommentRelationshipView.as_view(),
-        name='comment-relationships'),
-    url(r'^authors/(?P<pk>[^/.]+)/relationships/(?P<related_field>\w+)$',
-        AuthorRelationshipView.as_view(),
-        name='author-relationships'),
+    re_path(r'^entries/(?P<pk>[^/.]+)/relationships/(?P<related_field>\w+)$',
+            EntryRelationshipView.as_view(),
+            name='entry-relationships'),
+    re_path(r'^blogs/(?P<pk>[^/.]+)/relationships/(?P<related_field>\w+)$',
+            BlogRelationshipView.as_view(),
+            name='blog-relationships'),
+    re_path(r'^comments/(?P<pk>[^/.]+)/relationships/(?P<related_field>\w+)$',
+            CommentRelationshipView.as_view(),
+            name='comment-relationships'),
+    re_path(r'^authors/(?P<pk>[^/.]+)/relationships/(?P<related_field>\w+)$',
+            AuthorRelationshipView.as_view(),
+            name='author-relationships'),
 ]
+
+urlpatterns += router.urls