From 410575dace9d64a53ec771ea5e21b40525ed0e95 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Tue, 8 Sep 2020 15:32:27 +0100 Subject: [PATCH] Replace all url() calls with path() or re_path() (#7512) * url() is deprecated in Django 3.1 * update given feedbacks on url() is deprecated in Django 3.1 * Fix test_urlpatterns.py to continue testing mixed re_path() and path() * Fix one missed reference Co-authored-by: sanjusci --- docs/api-guide/authentication.md | 4 +- docs/api-guide/filtering.md | 2 +- docs/api-guide/format-suffixes.md | 6 +- docs/api-guide/generic-views.md | 2 +- docs/api-guide/parsers.md | 2 +- docs/api-guide/routers.md | 14 ++--- docs/api-guide/schemas.md | 2 +- docs/community/3.5-announcement.md | 6 +- docs/community/3.6-announcement.md | 2 +- docs/community/3.9-announcement.md | 3 +- docs/coreapi/from-documenting-your-api.md | 4 +- docs/coreapi/schemas.md | 9 +-- docs/index.md | 2 +- docs/topics/api-clients.md | 2 +- .../4-authentication-and-permissions.md | 2 +- .../templates/rest_framework/docs/error.html | 2 +- rest_framework/urls.py | 2 +- rest_framework/versioning.py | 12 ++-- tests/authentication/test_authentication.py | 30 ++++----- tests/browsable_api/auth_urls.py | 6 +- tests/browsable_api/no_auth_urls.py | 4 +- .../test_browsable_nested_api.py | 4 +- tests/schemas/test_coreapi.py | 61 +++++++++--------- tests/schemas/test_managementcommand.py | 4 +- tests/schemas/test_openapi.py | 40 ++++++------ tests/test_api_client.py | 16 ++--- tests/test_atomic_requests.py | 4 +- tests/test_fields.py | 2 +- tests/test_htmlrenderer.py | 8 +-- tests/test_lazy_hyperlinks.py | 4 +- tests/test_metadata.py | 3 +- tests/test_middleware.py | 6 +- tests/test_relations.py | 4 +- tests/test_relations_hyperlink.py | 18 +++--- tests/test_renderers.py | 20 +++--- tests/test_request.py | 8 +-- tests/test_requests_client.py | 10 +-- tests/test_response.py | 20 +++--- tests/test_reverse.py | 5 +- tests/test_routers.py | 23 ++++--- tests/test_testing.py | 12 ++-- tests/test_urlpatterns.py | 63 +++++++------------ tests/test_utils.py | 14 ++--- tests/test_versioning.py | 30 ++++----- tests/test_viewsets.py | 4 +- tests/urls.py | 4 +- 46 files changed, 243 insertions(+), 262 deletions(-) diff --git a/docs/api-guide/authentication.md b/docs/api-guide/authentication.md index ebb0ab4d6..5878040a4 100644 --- a/docs/api-guide/authentication.md +++ b/docs/api-guide/authentication.md @@ -199,7 +199,7 @@ When using `TokenAuthentication`, you may want to provide a mechanism for client from rest_framework.authtoken import views urlpatterns += [ - url(r'^api-token-auth/', views.obtain_auth_token) + path('api-token-auth/', views.obtain_auth_token) ] Note that the URL part of the pattern can be whatever you want to use. @@ -238,7 +238,7 @@ For example, you may return additional user information beyond the `token` value And in your `urls.py`: urlpatterns += [ - url(r'^api-token-auth/', CustomAuthToken.as_view()) + path('api-token-auth/', CustomAuthToken.as_view()) ] diff --git a/docs/api-guide/filtering.md b/docs/api-guide/filtering.md index 8e3bd9ef5..41c1341dd 100644 --- a/docs/api-guide/filtering.md +++ b/docs/api-guide/filtering.md @@ -45,7 +45,7 @@ Another style of filtering might involve restricting the queryset based on some For example if your URL config contained an entry like this: - url('^purchases/(?P.+)/$', PurchaseList.as_view()), + re_path('^purchases/(?P.+)/$', PurchaseList.as_view()), You could then write a view that returned a purchase queryset filtered by the username portion of the URL: diff --git a/docs/api-guide/format-suffixes.md b/docs/api-guide/format-suffixes.md index 04467b3d3..dfdf24953 100644 --- a/docs/api-guide/format-suffixes.md +++ b/docs/api-guide/format-suffixes.md @@ -32,9 +32,9 @@ Example: from blog import views urlpatterns = [ - url(r'^/$', views.apt_root), - url(r'^comments/$', views.comment_list), - url(r'^comments/(?P[0-9]+)/$', views.comment_detail) + path('', views.apt_root), + path('comments/', views.comment_list), + path('comments//', views.comment_detail) ] urlpatterns = format_suffix_patterns(urlpatterns, allowed=['json', 'html']) diff --git a/docs/api-guide/generic-views.md b/docs/api-guide/generic-views.md index 4ff549f07..afc2cab56 100644 --- a/docs/api-guide/generic-views.md +++ b/docs/api-guide/generic-views.md @@ -45,7 +45,7 @@ For more complex cases you might also want to override various methods on the vi For very simple cases you might want to pass through any class attributes using the `.as_view()` method. For example, your URLconf might include something like the following entry: - url(r'^/users/', ListCreateAPIView.as_view(queryset=User.objects.all(), serializer_class=UserSerializer), name='user-list') + path('users/', ListCreateAPIView.as_view(queryset=User.objects.all(), serializer_class=UserSerializer), name='user-list') --- diff --git a/docs/api-guide/parsers.md b/docs/api-guide/parsers.md index a3bc74a2b..e8f03de8b 100644 --- a/docs/api-guide/parsers.md +++ b/docs/api-guide/parsers.md @@ -125,7 +125,7 @@ If it is called without a `filename` URL keyword argument, then the client must # urls.py urlpatterns = [ # ... - url(r'^upload/(?P[^/]+)$', FileUploadView.as_view()) + re_path(r'^upload/(?P[^/]+)$', FileUploadView.as_view()) ] --- diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md index 5f6802222..8d8594eee 100644 --- a/docs/api-guide/routers.md +++ b/docs/api-guide/routers.md @@ -63,7 +63,7 @@ For example, you can append `router.urls` to a list of existing views... router.register(r'accounts', AccountViewSet) urlpatterns = [ - url(r'^forgot-password/$', ForgotPasswordFormView.as_view()), + path('forgot-password/', ForgotPasswordFormView.as_view()), ] urlpatterns += router.urls @@ -71,22 +71,22 @@ For example, you can append `router.urls` to a list of existing views... Alternatively you can use Django's `include` function, like so... urlpatterns = [ - url(r'^forgot-password/$', ForgotPasswordFormView.as_view()), - url(r'^', include(router.urls)), + path('forgot-password', ForgotPasswordFormView.as_view()), + path('', include(router.urls)), ] You may use `include` with an application namespace: urlpatterns = [ - url(r'^forgot-password/$', ForgotPasswordFormView.as_view()), - url(r'^api/', include((router.urls, 'app_name'))), + path('forgot-password/', ForgotPasswordFormView.as_view()), + path('api/', include((router.urls, 'app_name'))), ] Or both an application and instance namespace: urlpatterns = [ - url(r'^forgot-password/$', ForgotPasswordFormView.as_view()), - url(r'^api/', include((router.urls, 'app_name'), namespace='instance_name')), + path('forgot-password/', ForgotPasswordFormView.as_view()), + path('api/', include((router.urls, 'app_name'), namespace='instance_name')), ] See Django's [URL namespaces docs][url-namespace-docs] and the [`include` API reference][include-api-reference] for more details. diff --git a/docs/api-guide/schemas.md b/docs/api-guide/schemas.md index 402315ef9..e39cd21a8 100644 --- a/docs/api-guide/schemas.md +++ b/docs/api-guide/schemas.md @@ -114,7 +114,7 @@ The `get_schema_view()` helper takes the following keyword arguments: only want the `myproject.api` urls to be exposed in the schema: schema_url_patterns = [ - url(r'^api/', include('myproject.api.urls')), + path('api/', include('myproject.api.urls')), ] schema_view = get_schema_view( diff --git a/docs/community/3.5-announcement.md b/docs/community/3.5-announcement.md index cce2dd050..91bfce428 100644 --- a/docs/community/3.5-announcement.md +++ b/docs/community/3.5-announcement.md @@ -69,7 +69,7 @@ schema_view = get_schema_view( ) urlpatterns = [ - url(r'^swagger/$', schema_view), + path('swagger/', schema_view), ... ] ``` @@ -198,8 +198,8 @@ Make sure to include the view before your router urls. For example: schema_view = get_schema_view(title='Example API') urlpatterns = [ - url('^$', schema_view), - url(r'^', include(router.urls)), + path('', schema_view), + path('', include(router.urls)), ] ### Schema path representations diff --git a/docs/community/3.6-announcement.md b/docs/community/3.6-announcement.md index c41ad8ecb..35704eb58 100644 --- a/docs/community/3.6-announcement.md +++ b/docs/community/3.6-announcement.md @@ -73,7 +73,7 @@ To install the API documentation, you'll need to include it in your projects URL urlpatterns = [ ... - url(r'^docs/', include_docs_urls(title=API_TITLE, description=API_DESCRIPTION)) + path('docs/', include_docs_urls(title=API_TITLE, description=API_DESCRIPTION)) ] Once installed you should see something a little like this: diff --git a/docs/community/3.9-announcement.md b/docs/community/3.9-announcement.md index 1cf4464d6..fee6e6909 100644 --- a/docs/community/3.9-announcement.md +++ b/docs/community/3.9-announcement.md @@ -62,6 +62,7 @@ Here's an example of adding an OpenAPI schema to the URL conf: ```python from rest_framework.schemas import get_schema_view from rest_framework.renderers import JSONOpenAPIRenderer +from django.urls import path schema_view = get_schema_view( title='Server Monitoring API', @@ -70,7 +71,7 @@ schema_view = get_schema_view( ) urlpatterns = [ - url('^schema.json$', schema_view), + path('schema.json', schema_view), ... ] ``` diff --git a/docs/coreapi/from-documenting-your-api.md b/docs/coreapi/from-documenting-your-api.md index 9ac3be686..604dfa668 100644 --- a/docs/coreapi/from-documenting-your-api.md +++ b/docs/coreapi/from-documenting-your-api.md @@ -19,7 +19,7 @@ To install the API documentation, you'll need to include it in your project's UR urlpatterns = [ ... - url(r'^docs/', include_docs_urls(title='My API title')) + path('docs/', include_docs_urls(title='My API title')) ] This will include two different views: @@ -41,7 +41,7 @@ You may ensure views are given a `request` instance by calling `include_docs_url urlpatterns = [ ... # Generate schema with valid `request` instance: - url(r'^docs/', include_docs_urls(title='My API title', public=False)) + path('docs/', include_docs_urls(title='My API title', public=False)) ] diff --git a/docs/coreapi/schemas.md b/docs/coreapi/schemas.md index 69606f853..e7a418b80 100644 --- a/docs/coreapi/schemas.md +++ b/docs/coreapi/schemas.md @@ -43,11 +43,12 @@ To add a dynamically generated schema view to your API, use `get_schema_view`. ```python from rest_framework.schemas import get_schema_view +from django.urls import path schema_view = get_schema_view(title="Example API") urlpatterns = [ - url('^schema$', schema_view), + path('schema', schema_view), ... ] ``` @@ -292,7 +293,7 @@ The simplest way to include a schema in your project is to use the schema_view = get_schema_view(title="Server Monitoring API") urlpatterns = [ - url('^$', schema_view), + path('', schema_view), ... ] @@ -358,7 +359,7 @@ List of url patterns to limit the schema introspection to. If you only want the to be exposed in the schema: schema_url_patterns = [ - url(r'^api/', include('myproject.api.urls')), + path('api/', include('myproject.api.urls')), ] schema_view = get_schema_view( @@ -411,7 +412,7 @@ return the schema. **urls.py:** urlpatterns = [ - url('/', schema_view), + path('', schema_view), ... ] diff --git a/docs/index.md b/docs/index.md index c7b78e9c3..54654c7c5 100644 --- a/docs/index.md +++ b/docs/index.md @@ -120,7 +120,7 @@ If you're intending to use the browsable API you'll probably also want to add RE urlpatterns = [ ... - url(r'^api-auth/', include('rest_framework.urls')) + path('api-auth/', include('rest_framework.urls')) ] Note that the URL path can be whatever you want. diff --git a/docs/topics/api-clients.md b/docs/topics/api-clients.md index b020c380a..9b61eaf42 100644 --- a/docs/topics/api-clients.md +++ b/docs/topics/api-clients.md @@ -384,7 +384,7 @@ First, install the API documentation views. These will include the schema resour urlpatterns = [ ... - url(r'^docs/', include_docs_urls(title='My API service'), name='api-docs'), + path('docs/', include_docs_urls(title='My API service'), name='api-docs'), ] Once the API documentation URLs are installed, you'll be able to include both the required JavaScript resources. Note that the ordering of these two lines is important, as the schema loading requires CoreAPI to already be installed. diff --git a/docs/tutorial/4-authentication-and-permissions.md b/docs/tutorial/4-authentication-and-permissions.md index 6808780fa..79ce355c9 100644 --- a/docs/tutorial/4-authentication-and-permissions.md +++ b/docs/tutorial/4-authentication-and-permissions.md @@ -137,7 +137,7 @@ We can add a login view for use with the browsable API, by editing the URLconf i Add the following import at the top of the file: - from django.conf.urls import include + from django.urls import path, include And, at the end of the file, add a pattern to include the login and logout views for the browsable API. diff --git a/rest_framework/templates/rest_framework/docs/error.html b/rest_framework/templates/rest_framework/docs/error.html index 6afc4a88b..694f88a15 100644 --- a/rest_framework/templates/rest_framework/docs/error.html +++ b/rest_framework/templates/rest_framework/docs/error.html @@ -48,7 +48,7 @@ being applied unexpectedly?

when including the docs urls:

-   url(r'^docs/', include_docs_urls(title='Your API',
+   path('docs/', include_docs_urls(title='Your API',
                                     authentication_classes=[],
                                     permission_classes=[])),
 
diff --git a/rest_framework/urls.py b/rest_framework/urls.py index d9b858ebc..0aa301332 100644 --- a/rest_framework/urls.py +++ b/rest_framework/urls.py @@ -6,7 +6,7 @@ your API requires authentication: urlpatterns = [ ... - url(r'^auth/', include('rest_framework.urls')) + path('auth/', include('rest_framework.urls')) ] You should make sure your authentication settings include `SessionAuthentication`. diff --git a/rest_framework/versioning.py b/rest_framework/versioning.py index 8c35a1a58..78cfc9dc8 100644 --- a/rest_framework/versioning.py +++ b/rest_framework/versioning.py @@ -60,8 +60,8 @@ class URLPathVersioning(BaseVersioning): An example URL conf for two views that accept two different versions. urlpatterns = [ - url(r'^(?P[v1|v2]+)/users/$', users_list, name='users-list'), - url(r'^(?P[v1|v2]+)/users/(?P[0-9]+)/$', users_detail, name='users-detail') + re_path(r'^(?P[v1|v2]+)/users/$', users_list, name='users-list'), + re_path(r'^(?P[v1|v2]+)/users/(?P[0-9]+)/$', users_detail, name='users-detail') ] GET /1.0/something/ HTTP/1.1 @@ -99,14 +99,14 @@ class NamespaceVersioning(BaseVersioning): # users/urls.py urlpatterns = [ - url(r'^/users/$', users_list, name='users-list'), - url(r'^/users/(?P[0-9]+)/$', users_detail, name='users-detail') + path('/users/', users_list, name='users-list'), + path('/users//', users_detail, name='users-detail') ] # urls.py urlpatterns = [ - url(r'^v1/', include('users.urls', namespace='v1')), - url(r'^v2/', include('users.urls', namespace='v2')) + path('v1/', include('users.urls', namespace='v1')), + path('v2/', include('users.urls', namespace='v2')) ] GET /1.0/something/ HTTP/1.1 diff --git a/tests/authentication/test_authentication.py b/tests/authentication/test_authentication.py index e872fa744..a73e0d79c 100644 --- a/tests/authentication/test_authentication.py +++ b/tests/authentication/test_authentication.py @@ -2,10 +2,10 @@ import base64 import pytest from django.conf import settings -from django.conf.urls import include, url from django.contrib.auth.models import User from django.http import HttpResponse from django.test import TestCase, override_settings +from django.urls import include, path from rest_framework import ( HTTP_HEADER_ENCODING, exceptions, permissions, renderers, status @@ -47,34 +47,34 @@ class MockView(APIView): urlpatterns = [ - url( - r'^session/$', + path( + 'session/', MockView.as_view(authentication_classes=[SessionAuthentication]) ), - url( - r'^basic/$', + path( + 'basic/', MockView.as_view(authentication_classes=[BasicAuthentication]) ), - url( - r'^remote-user/$', + path( + 'remote-user/', MockView.as_view(authentication_classes=[RemoteUserAuthentication]) ), - url( - r'^token/$', + path( + 'token/', MockView.as_view(authentication_classes=[TokenAuthentication]) ), - url( - r'^customtoken/$', + path( + 'customtoken/', MockView.as_view(authentication_classes=[CustomTokenAuthentication]) ), - url( - r'^customkeywordtoken/$', + path( + 'customkeywordtoken/', MockView.as_view( authentication_classes=[CustomKeywordTokenAuthentication] ) ), - url(r'^auth-token/$', obtain_auth_token), - url(r'^auth/', include('rest_framework.urls', namespace='rest_framework')), + path('auth-token/', obtain_auth_token), + path('auth/', include('rest_framework.urls', namespace='rest_framework')), ] diff --git a/tests/browsable_api/auth_urls.py b/tests/browsable_api/auth_urls.py index 7530c5e40..151278cbd 100644 --- a/tests/browsable_api/auth_urls.py +++ b/tests/browsable_api/auth_urls.py @@ -1,8 +1,8 @@ -from django.conf.urls import include, url +from django.urls import include, path from .views import MockView urlpatterns = [ - url(r'^$', MockView.as_view()), - url(r'^auth/', include('rest_framework.urls', namespace='rest_framework')), + path('', MockView.as_view()), + path('auth/', include('rest_framework.urls', namespace='rest_framework')), ] diff --git a/tests/browsable_api/no_auth_urls.py b/tests/browsable_api/no_auth_urls.py index 348bfe1c0..65701c065 100644 --- a/tests/browsable_api/no_auth_urls.py +++ b/tests/browsable_api/no_auth_urls.py @@ -1,7 +1,7 @@ -from django.conf.urls import url +from django.urls import path from .views import MockView urlpatterns = [ - url(r'^$', MockView.as_view()), + path('', MockView.as_view()), ] diff --git a/tests/browsable_api/test_browsable_nested_api.py b/tests/browsable_api/test_browsable_nested_api.py index f945d2a43..a6c2ee6bd 100644 --- a/tests/browsable_api/test_browsable_nested_api.py +++ b/tests/browsable_api/test_browsable_nested_api.py @@ -1,6 +1,6 @@ -from django.conf.urls import url from django.test import TestCase from django.test.utils import override_settings +from django.urls import path from rest_framework import serializers from rest_framework.generics import ListCreateAPIView @@ -23,7 +23,7 @@ class NestedSerializersView(ListCreateAPIView): urlpatterns = [ - url(r'^api/$', NestedSerializersView.as_view(), name='api'), + path('api/', NestedSerializersView.as_view(), name='api'), ] diff --git a/tests/schemas/test_coreapi.py b/tests/schemas/test_coreapi.py index 5f646258b..7b1f15fef 100644 --- a/tests/schemas/test_coreapi.py +++ b/tests/schemas/test_coreapi.py @@ -1,11 +1,10 @@ import unittest import pytest -from django.conf.urls import include, url from django.core.exceptions import PermissionDenied from django.http import Http404 from django.test import TestCase, override_settings -from django.urls import path +from django.urls import include, path from rest_framework import ( filters, generics, pagination, permissions, serializers @@ -145,8 +144,8 @@ with override_settings(REST_FRAMEWORK={'DEFAULT_SCHEMA_CLASS': 'rest_framework.s router = DefaultRouter() router.register('example', ExampleViewSet, basename='example') urlpatterns = [ - url(r'^$', schema_view), - url(r'^', include(router.urls)) + path('', schema_view), + path('', include(router.urls)) ] @@ -407,9 +406,9 @@ class ExampleDetailView(APIView): class TestSchemaGenerator(TestCase): def setUp(self): self.patterns = [ - url(r'^example/?$', views.ExampleListView.as_view()), - url(r'^example/(?P\d+)/?$', views.ExampleDetailView.as_view()), - url(r'^example/(?P\d+)/sub/?$', views.ExampleDetailView.as_view()), + path('example/', views.ExampleListView.as_view()), + path('example//', views.ExampleDetailView.as_view()), + path('example//sub/', views.ExampleDetailView.as_view()), ] def test_schema_for_regular_views(self): @@ -513,9 +512,9 @@ class TestSchemaGeneratorDjango2(TestCase): class TestSchemaGeneratorNotAtRoot(TestCase): def setUp(self): self.patterns = [ - url(r'^api/v1/example/?$', views.ExampleListView.as_view()), - url(r'^api/v1/example/(?P\d+)/?$', views.ExampleDetailView.as_view()), - url(r'^api/v1/example/(?P\d+)/sub/?$', views.ExampleDetailView.as_view()), + path('api/v1/example/', views.ExampleListView.as_view()), + path('api/v1/example//', views.ExampleDetailView.as_view()), + path('api/v1/example//sub/', views.ExampleDetailView.as_view()), ] def test_schema_for_regular_views(self): @@ -569,7 +568,7 @@ class TestSchemaGeneratorWithMethodLimitedViewSets(TestCase): router = DefaultRouter() router.register('example1', MethodLimitedViewSet, basename='example1') self.patterns = [ - url(r'^', include(router.urls)) + path('', include(router.urls)) ] def test_schema_for_regular_views(self): @@ -635,8 +634,8 @@ class TestSchemaGeneratorWithRestrictedViewSets(TestCase): router.register('example1', Http404ExampleViewSet, basename='example1') router.register('example2', PermissionDeniedExampleViewSet, basename='example2') self.patterns = [ - url('^example/?$', views.ExampleListView.as_view()), - url(r'^', include(router.urls)) + path('example/', views.ExampleListView.as_view()), + path('', include(router.urls)) ] def test_schema_for_regular_views(self): @@ -679,7 +678,7 @@ class ForeignKeySourceView(generics.CreateAPIView): class TestSchemaGeneratorWithForeignKey(TestCase): def setUp(self): self.patterns = [ - url(r'^example/?$', ForeignKeySourceView.as_view()), + path('example/', ForeignKeySourceView.as_view()), ] def test_schema_for_regular_views(self): @@ -725,7 +724,7 @@ class ManyToManySourceView(generics.CreateAPIView): class TestSchemaGeneratorWithManyToMany(TestCase): def setUp(self): self.patterns = [ - url(r'^example/?$', ManyToManySourceView.as_view()), + path('example/', ManyToManySourceView.as_view()), ] def test_schema_for_regular_views(self): @@ -1041,9 +1040,9 @@ with override_settings(REST_FRAMEWORK={'DEFAULT_SCHEMA_CLASS': 'rest_framework.s class SchemaGenerationExclusionTests(TestCase): def setUp(self): self.patterns = [ - url('^excluded-cbv/$', ExcludedAPIView.as_view()), - url('^excluded-fbv/$', excluded_fbv), - url('^included-fbv/$', included_fbv), + path('excluded-cbv/', ExcludedAPIView.as_view()), + path('excluded-fbv/', excluded_fbv), + path('included-fbv/', included_fbv), ] def test_schema_generator_excludes_correctly(self): @@ -1136,8 +1135,8 @@ class TestURLNamingCollisions(TestCase): pass patterns = [ - url(r'^test', simple_fbv), - url(r'^test/list/', simple_fbv), + path('test', simple_fbv), + path('test/list/', simple_fbv), ] generator = SchemaGenerator(title='Naming Colisions', patterns=patterns) @@ -1173,14 +1172,14 @@ class TestURLNamingCollisions(TestCase): def test_manually_routing_generic_view(self): patterns = [ - url(r'^test', NamingCollisionView.as_view()), - url(r'^test/retrieve/', NamingCollisionView.as_view()), - url(r'^test/update/', NamingCollisionView.as_view()), + path('test', NamingCollisionView.as_view()), + path('test/retrieve/', NamingCollisionView.as_view()), + path('test/update/', NamingCollisionView.as_view()), # Fails with method names: - url(r'^test/get/', NamingCollisionView.as_view()), - url(r'^test/put/', NamingCollisionView.as_view()), - url(r'^test/delete/', NamingCollisionView.as_view()), + path('test/get/', NamingCollisionView.as_view()), + path('test/put/', NamingCollisionView.as_view()), + path('test/delete/', NamingCollisionView.as_view()), ] generator = SchemaGenerator(title='Naming Colisions', patterns=patterns) @@ -1196,7 +1195,7 @@ class TestURLNamingCollisions(TestCase): def test_from_router(self): patterns = [ - url(r'from-router', include(naming_collisions_router.urls)), + path('from-router', include(naming_collisions_router.urls)), ] generator = SchemaGenerator(title='Naming Colisions', patterns=patterns) @@ -1228,8 +1227,8 @@ class TestURLNamingCollisions(TestCase): def test_url_under_same_key_not_replaced(self): patterns = [ - url(r'example/(?P\d+)/$', BasicNamingCollisionView.as_view()), - url(r'example/(?P\w+)/$', BasicNamingCollisionView.as_view()), + path('example//', BasicNamingCollisionView.as_view()), + path('example//', BasicNamingCollisionView.as_view()), ] generator = SchemaGenerator(title='Naming Colisions', patterns=patterns) @@ -1245,8 +1244,8 @@ class TestURLNamingCollisions(TestCase): pass patterns = [ - url(r'^test/list/', simple_fbv), - url(r'^test/(?P\d+)/list/', simple_fbv), + path('test/list/', simple_fbv), + path('test//list/', simple_fbv), ] generator = SchemaGenerator(title='Naming Colisions', patterns=patterns) diff --git a/tests/schemas/test_managementcommand.py b/tests/schemas/test_managementcommand.py index 115f871e5..645eaf91d 100644 --- a/tests/schemas/test_managementcommand.py +++ b/tests/schemas/test_managementcommand.py @@ -3,10 +3,10 @@ import os import tempfile import pytest -from django.conf.urls import url from django.core.management import call_command from django.test import TestCase from django.test.utils import override_settings +from django.urls import path from rest_framework.compat import uritemplate, yaml from rest_framework.management.commands import generateschema @@ -20,7 +20,7 @@ class FooView(APIView): urlpatterns = [ - url(r'^$', FooView.as_view()) + path('', FooView.as_view()) ] diff --git a/tests/schemas/test_openapi.py b/tests/schemas/test_openapi.py index d483f3d45..8ea910dc1 100644 --- a/tests/schemas/test_openapi.py +++ b/tests/schemas/test_openapi.py @@ -2,8 +2,8 @@ import uuid import warnings import pytest -from django.conf.urls import url from django.test import RequestFactory, TestCase, override_settings +from django.urls import path from django.utils.translation import gettext_lazy as _ from rest_framework import filters, generics, pagination, routers, serializers @@ -719,8 +719,8 @@ class TestOperationIntrospection(TestCase): def test_duplicate_operation_id(self): patterns = [ - url(r'^duplicate1/?$', views.ExampleOperationIdDuplicate1.as_view()), - url(r'^duplicate2/?$', views.ExampleOperationIdDuplicate2.as_view()), + path('duplicate1/', views.ExampleOperationIdDuplicate1.as_view()), + path('duplicate2/', views.ExampleOperationIdDuplicate2.as_view()), ] generator = SchemaGenerator(patterns=patterns) @@ -874,7 +874,7 @@ class TestOperationIntrospection(TestCase): schema = AutoSchema(tags=['example1', 'example2']) url_patterns = [ - url(r'^test/?$', ExampleStringTagsViewSet.as_view()), + path('test/', ExampleStringTagsViewSet.as_view()), ] generator = SchemaGenerator(patterns=url_patterns) schema = generator.get_schema(request=create_request('/')) @@ -911,8 +911,8 @@ class TestOperationIntrospection(TestCase): pass url_patterns = [ - url(r'^any-dash_underscore/?$', RestaurantAPIView.as_view()), - url(r'^restaurants/branches/?$', BranchAPIView.as_view()) + path('any-dash_underscore/', RestaurantAPIView.as_view()), + path('restaurants/branches/', BranchAPIView.as_view()) ] generator = SchemaGenerator(patterns=url_patterns) schema = generator.get_schema(request=create_request('/')) @@ -930,7 +930,7 @@ class TestGenerator(TestCase): def test_paths_construction(self): """Construction of the `paths` key.""" patterns = [ - url(r'^example/?$', views.ExampleListView.as_view()), + path('example/', views.ExampleListView.as_view()), ] generator = SchemaGenerator(patterns=patterns) generator._initialise_endpoints() @@ -946,8 +946,8 @@ class TestGenerator(TestCase): def test_prefixed_paths_construction(self): """Construction of the `paths` key maintains a common prefix.""" patterns = [ - url(r'^v1/example/?$', views.ExampleListView.as_view()), - url(r'^v1/example/{pk}/?$', views.ExampleDetailView.as_view()), + path('v1/example/', views.ExampleListView.as_view()), + path('v1/example/{pk}/', views.ExampleDetailView.as_view()), ] generator = SchemaGenerator(patterns=patterns) generator._initialise_endpoints() @@ -959,8 +959,8 @@ class TestGenerator(TestCase): def test_mount_url_prefixed_to_paths(self): patterns = [ - url(r'^example/?$', views.ExampleListView.as_view()), - url(r'^example/{pk}/?$', views.ExampleDetailView.as_view()), + path('example/', views.ExampleListView.as_view()), + path('example/{pk}/', views.ExampleDetailView.as_view()), ] generator = SchemaGenerator(patterns=patterns, url='/api') generator._initialise_endpoints() @@ -973,7 +973,7 @@ class TestGenerator(TestCase): def test_schema_construction(self): """Construction of the top level dictionary.""" patterns = [ - url(r'^example/?$', views.ExampleListView.as_view()), + path('example/', views.ExampleListView.as_view()), ] generator = SchemaGenerator(patterns=patterns) @@ -995,7 +995,7 @@ class TestGenerator(TestCase): def test_schema_information(self): """Construction of the top level dictionary.""" patterns = [ - url(r'^example/?$', views.ExampleListView.as_view()), + path('example/', views.ExampleListView.as_view()), ] generator = SchemaGenerator(patterns=patterns, title='My title', version='1.2.3', description='My description') @@ -1009,7 +1009,7 @@ class TestGenerator(TestCase): def test_schema_information_empty(self): """Construction of the top level dictionary.""" patterns = [ - url(r'^example/?$', views.ExampleListView.as_view()), + path('example/', views.ExampleListView.as_view()), ] generator = SchemaGenerator(patterns=patterns) @@ -1022,7 +1022,7 @@ class TestGenerator(TestCase): def test_serializer_model(self): """Construction of the top level dictionary.""" patterns = [ - url(r'^example/?$', views.ExampleGenericAPIViewModel.as_view()), + path('example/', views.ExampleGenericAPIViewModel.as_view()), ] generator = SchemaGenerator(patterns=patterns) @@ -1038,7 +1038,7 @@ class TestGenerator(TestCase): def test_authtoken_serializer(self): patterns = [ - url(r'^api-token-auth/', obtain_auth_token) + path('api-token-auth/', obtain_auth_token) ] generator = SchemaGenerator(patterns=patterns) @@ -1065,7 +1065,7 @@ class TestGenerator(TestCase): def test_component_name(self): patterns = [ - url(r'^example/?$', views.ExampleAutoSchemaComponentName.as_view()), + path('example/', views.ExampleAutoSchemaComponentName.as_view()), ] generator = SchemaGenerator(patterns=patterns) @@ -1080,8 +1080,8 @@ class TestGenerator(TestCase): def test_duplicate_component_name(self): patterns = [ - url(r'^duplicate1/?$', views.ExampleAutoSchemaDuplicate1.as_view()), - url(r'^duplicate2/?$', views.ExampleAutoSchemaDuplicate2.as_view()), + path('duplicate1/', views.ExampleAutoSchemaDuplicate1.as_view()), + path('duplicate2/', views.ExampleAutoSchemaDuplicate2.as_view()), ] generator = SchemaGenerator(patterns=patterns) @@ -1104,7 +1104,7 @@ class TestGenerator(TestCase): schema = AutoSchema(operation_id_base='example') url_patterns = [ - url(r'^example/?$', ExampleView.as_view()), + path('example/', ExampleView.as_view()), ] generator = SchemaGenerator(patterns=url_patterns) schema = generator.get_schema(request=create_request('/')) diff --git a/tests/test_api_client.py b/tests/test_api_client.py index 74a3579e2..976f10ed1 100644 --- a/tests/test_api_client.py +++ b/tests/test_api_client.py @@ -2,9 +2,9 @@ import os import tempfile import unittest -from django.conf.urls import url from django.http import HttpResponse from django.test import override_settings +from django.urls import path, re_path from rest_framework.compat import coreapi, coreschema from rest_framework.parsers import FileUploadParser @@ -178,13 +178,13 @@ class HeadersView(APIView): urlpatterns = [ - url(r'^$', SchemaView.as_view()), - url(r'^example/$', ListView.as_view()), - url(r'^example/(?P[0-9]+)/$', DetailView.as_view()), - url(r'^upload/$', UploadView.as_view()), - url(r'^download/$', DownloadView.as_view()), - url(r'^text/$', TextView.as_view()), - url(r'^headers/$', HeadersView.as_view()), + path('', SchemaView.as_view()), + path('example/', ListView.as_view()), + re_path(r'^example/(?P[0-9]+)/$', DetailView.as_view()), + path('upload/', UploadView.as_view()), + path('download/', DownloadView.as_view()), + path('text/', TextView.as_view()), + path('headers/', HeadersView.as_view()), ] diff --git a/tests/test_atomic_requests.py b/tests/test_atomic_requests.py index de04d2c06..15b41e02f 100644 --- a/tests/test_atomic_requests.py +++ b/tests/test_atomic_requests.py @@ -1,9 +1,9 @@ import unittest -from django.conf.urls import url from django.db import connection, connections, transaction from django.http import Http404 from django.test import TestCase, TransactionTestCase, override_settings +from django.urls import path from rest_framework import status from rest_framework.exceptions import APIException @@ -44,7 +44,7 @@ class NonAtomicAPIExceptionView(APIView): urlpatterns = ( - url(r'^$', NonAtomicAPIExceptionView.as_view()), + path('', NonAtomicAPIExceptionView.as_view()), ) diff --git a/tests/test_fields.py b/tests/test_fields.py index 506e75905..fdd570d8a 100644 --- a/tests/test_fields.py +++ b/tests/test_fields.py @@ -697,7 +697,7 @@ class TestNullBooleanField(TestBooleanField): None: None, 'other': True } - field = serializers.NullBooleanField() + field = serializers.BooleanField(allow_null=True) class TestNullableBooleanField(TestNullBooleanField): diff --git a/tests/test_htmlrenderer.py b/tests/test_htmlrenderer.py index e31a9ced5..fa0f4efc6 100644 --- a/tests/test_htmlrenderer.py +++ b/tests/test_htmlrenderer.py @@ -1,10 +1,10 @@ import django.template.loader import pytest -from django.conf.urls import url from django.core.exceptions import ImproperlyConfigured, PermissionDenied from django.http import Http404 from django.template import TemplateDoesNotExist, engines from django.test import TestCase, override_settings +from django.urls import path from rest_framework import status from rest_framework.decorators import api_view, renderer_classes @@ -35,9 +35,9 @@ def not_found(request): urlpatterns = [ - url(r'^$', example), - url(r'^permission_denied$', permission_denied), - url(r'^not_found$', not_found), + path('', example), + path('permission_denied', permission_denied), + path('not_found', not_found), ] diff --git a/tests/test_lazy_hyperlinks.py b/tests/test_lazy_hyperlinks.py index cf3ee735f..716d02d2a 100644 --- a/tests/test_lazy_hyperlinks.py +++ b/tests/test_lazy_hyperlinks.py @@ -1,6 +1,6 @@ -from django.conf.urls import url from django.db import models from django.test import TestCase, override_settings +from django.urls import path from rest_framework import serializers from rest_framework.renderers import JSONRenderer @@ -29,7 +29,7 @@ def dummy_view(request): urlpatterns = [ - url(r'^example/(?P[0-9]+)/$', dummy_view, name='example-detail'), + path('example//', dummy_view, name='example-detail'), ] diff --git a/tests/test_metadata.py b/tests/test_metadata.py index e1a1fd352..4abc0fc07 100644 --- a/tests/test_metadata.py +++ b/tests/test_metadata.py @@ -311,7 +311,8 @@ class TestMetadata: class TestSimpleMetadataFieldInfo(TestCase): def test_null_boolean_field_info_type(self): options = metadata.SimpleMetadata() - field_info = options.get_field_info(serializers.NullBooleanField()) + field_info = options.get_field_info(serializers.BooleanField( + allow_null=True)) assert field_info['type'] == 'boolean' def test_related_field_choices(self): diff --git a/tests/test_middleware.py b/tests/test_middleware.py index 28a5e558a..6b2c91db7 100644 --- a/tests/test_middleware.py +++ b/tests/test_middleware.py @@ -1,7 +1,7 @@ -from django.conf.urls import url from django.contrib.auth.models import User from django.http import HttpRequest from django.test import override_settings +from django.urls import path from rest_framework.authentication import TokenAuthentication from rest_framework.authtoken.models import Token @@ -17,8 +17,8 @@ class PostView(APIView): urlpatterns = [ - url(r'^auth$', APIView.as_view(authentication_classes=(TokenAuthentication,))), - url(r'^post$', PostView.as_view()), + path('auth', APIView.as_view(authentication_classes=(TokenAuthentication,))), + path('post', PostView.as_view()), ] diff --git a/tests/test_relations.py b/tests/test_relations.py index 9f05e3b31..92aeecf6c 100644 --- a/tests/test_relations.py +++ b/tests/test_relations.py @@ -2,9 +2,9 @@ import uuid import pytest from _pytest.monkeypatch import MonkeyPatch -from django.conf.urls import url from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist from django.test import override_settings +from django.urls import re_path from django.utils.datastructures import MultiValueDict from rest_framework import relations, serializers @@ -146,7 +146,7 @@ class TestProxiedPrimaryKeyRelatedField(APISimpleTestCase): urlpatterns = [ - url(r'^example/(?P.+)/$', lambda: None, name='example'), + re_path(r'^example/(?P.+)/$', lambda: None, name='example'), ] diff --git a/tests/test_relations_hyperlink.py b/tests/test_relations_hyperlink.py index 5ad0e31ff..77e4cd95f 100644 --- a/tests/test_relations_hyperlink.py +++ b/tests/test_relations_hyperlink.py @@ -1,5 +1,5 @@ -from django.conf.urls import url from django.test import TestCase, override_settings +from django.urls import path from rest_framework import serializers from rest_framework.test import APIRequestFactory @@ -17,14 +17,14 @@ def dummy_view(request, pk): urlpatterns = [ - url(r'^dummyurl/(?P[0-9]+)/$', dummy_view, name='dummy-url'), - url(r'^manytomanysource/(?P[0-9]+)/$', dummy_view, name='manytomanysource-detail'), - url(r'^manytomanytarget/(?P[0-9]+)/$', dummy_view, name='manytomanytarget-detail'), - url(r'^foreignkeysource/(?P[0-9]+)/$', dummy_view, name='foreignkeysource-detail'), - url(r'^foreignkeytarget/(?P[0-9]+)/$', dummy_view, name='foreignkeytarget-detail'), - url(r'^nullableforeignkeysource/(?P[0-9]+)/$', dummy_view, name='nullableforeignkeysource-detail'), - url(r'^onetoonetarget/(?P[0-9]+)/$', dummy_view, name='onetoonetarget-detail'), - url(r'^nullableonetoonesource/(?P[0-9]+)/$', dummy_view, name='nullableonetoonesource-detail'), + path('dummyurl//', dummy_view, name='dummy-url'), + path('manytomanysource//', dummy_view, name='manytomanysource-detail'), + path('manytomanytarget//', dummy_view, name='manytomanytarget-detail'), + path('foreignkeysource//', dummy_view, name='foreignkeysource-detail'), + path('foreignkeytarget//', dummy_view, name='foreignkeytarget-detail'), + path('nullableforeignkeysource//', dummy_view, name='nullableforeignkeysource-detail'), + path('onetoonetarget//', dummy_view, name='onetoonetarget-detail'), + path('nullableonetoonesource//', dummy_view, name='nullableonetoonesource-detail'), ] diff --git a/tests/test_renderers.py b/tests/test_renderers.py index 71c5fb3f6..8271608e1 100644 --- a/tests/test_renderers.py +++ b/tests/test_renderers.py @@ -3,12 +3,12 @@ from collections import OrderedDict from collections.abc import MutableMapping import pytest -from django.conf.urls import include, url from django.core.cache import cache from django.db import models from django.http.request import HttpRequest from django.template import loader from django.test import TestCase, override_settings +from django.urls import include, path, re_path from django.utils.safestring import SafeText from django.utils.translation import gettext_lazy as _ @@ -111,14 +111,14 @@ class HTMLView1(APIView): urlpatterns = [ - url(r'^.*\.(?P.+)$', MockView.as_view(renderer_classes=[RendererA, RendererB])), - url(r'^$', MockView.as_view(renderer_classes=[RendererA, RendererB])), - url(r'^cache$', MockGETView.as_view()), - url(r'^parseerror$', MockPOSTView.as_view(renderer_classes=[JSONRenderer, BrowsableAPIRenderer])), - url(r'^html$', HTMLView.as_view()), - url(r'^html1$', HTMLView1.as_view()), - url(r'^empty$', EmptyGETView.as_view()), - url(r'^api', include('rest_framework.urls', namespace='rest_framework')) + re_path(r'^.*\.(?P.+)$', MockView.as_view(renderer_classes=[RendererA, RendererB])), + path('', MockView.as_view(renderer_classes=[RendererA, RendererB])), + path('cache', MockGETView.as_view()), + path('parseerror', MockPOSTView.as_view(renderer_classes=[JSONRenderer, BrowsableAPIRenderer])), + path('html', HTMLView.as_view()), + path('html1', HTMLView1.as_view()), + path('empty', EmptyGETView.as_view()), + path('api', include('rest_framework.urls', namespace='rest_framework')) ] @@ -637,7 +637,7 @@ class BrowsableAPIRendererTests(URLPatternsTestCase): router = SimpleRouter() router.register('examples', ExampleViewSet, basename='example') router.register('auth-examples', AuthExampleViewSet, basename='auth-example') - urlpatterns = [url(r'^api/', include(router.urls))] + urlpatterns = [path('api/', include(router.urls))] def setUp(self): self.renderer = BrowsableAPIRenderer() diff --git a/tests/test_request.py b/tests/test_request.py index be84fe5f9..4425c020f 100644 --- a/tests/test_request.py +++ b/tests/test_request.py @@ -5,7 +5,6 @@ import os.path import tempfile import pytest -from django.conf.urls import url from django.contrib.auth import authenticate, login, logout from django.contrib.auth.middleware import AuthenticationMiddleware from django.contrib.auth.models import User @@ -13,6 +12,7 @@ from django.contrib.sessions.middleware import SessionMiddleware from django.core.files.uploadedfile import SimpleUploadedFile from django.http.request import RawPostDataException from django.test import TestCase, override_settings +from django.urls import path from rest_framework import status from rest_framework.authentication import SessionAuthentication @@ -153,9 +153,9 @@ class FileUploadView(APIView): urlpatterns = [ - url(r'^$', MockView.as_view()), - url(r'^echo/$', EchoView.as_view()), - url(r'^upload/$', FileUploadView.as_view()) + path('', MockView.as_view()), + path('echo/', EchoView.as_view()), + path('upload/', FileUploadView.as_view()) ] diff --git a/tests/test_requests_client.py b/tests/test_requests_client.py index 59b388c5a..c8e7be6ee 100644 --- a/tests/test_requests_client.py +++ b/tests/test_requests_client.py @@ -1,10 +1,10 @@ import unittest -from django.conf.urls import url from django.contrib.auth import authenticate, login from django.contrib.auth.models import User from django.shortcuts import redirect from django.test import override_settings +from django.urls import path from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_protect, ensure_csrf_cookie @@ -90,10 +90,10 @@ class AuthView(APIView): urlpatterns = [ - url(r'^$', Root.as_view(), name='root'), - url(r'^headers/$', HeadersView.as_view(), name='headers'), - url(r'^session/$', SessionView.as_view(), name='session'), - url(r'^auth/$', AuthView.as_view(), name='auth'), + path('', Root.as_view(), name='root'), + path('headers/', HeadersView.as_view(), name='headers'), + path('session/', SessionView.as_view(), name='session'), + path('auth/', AuthView.as_view(), name='auth'), ] diff --git a/tests/test_response.py b/tests/test_response.py index d3a56d01b..0d5528dc9 100644 --- a/tests/test_response.py +++ b/tests/test_response.py @@ -1,5 +1,5 @@ -from django.conf.urls import include, url from django.test import TestCase, override_settings +from django.urls import include, path, re_path from rest_framework import generics, routers, serializers, status, viewsets from rest_framework.parsers import JSONParser @@ -117,15 +117,15 @@ new_model_viewset_router.register(r'', HTMLNewModelViewSet) urlpatterns = [ - url(r'^setbyview$', MockViewSettingContentType.as_view(renderer_classes=[RendererA, RendererB, RendererC])), - url(r'^.*\.(?P.+)$', MockView.as_view(renderer_classes=[RendererA, RendererB, RendererC])), - url(r'^$', MockView.as_view(renderer_classes=[RendererA, RendererB, RendererC])), - url(r'^html$', HTMLView.as_view()), - url(r'^json$', JSONView.as_view()), - url(r'^html1$', HTMLView1.as_view()), - url(r'^html_new_model$', HTMLNewModelView.as_view()), - url(r'^html_new_model_viewset', include(new_model_viewset_router.urls)), - url(r'^restframework', include('rest_framework.urls', namespace='rest_framework')) + path('setbyview', MockViewSettingContentType.as_view(renderer_classes=[RendererA, RendererB, RendererC])), + re_path(r'^.*\.(?P.+)$', MockView.as_view(renderer_classes=[RendererA, RendererB, RendererC])), + path('', MockView.as_view(renderer_classes=[RendererA, RendererB, RendererC])), + path('html', HTMLView.as_view()), + path('json', JSONView.as_view()), + path('html1', HTMLView1.as_view()), + path('html_new_model', HTMLNewModelView.as_view()), + path('html_new_model_viewset', include(new_model_viewset_router.urls)), + path('restframework', include('rest_framework.urls', namespace='rest_framework')) ] diff --git a/tests/test_reverse.py b/tests/test_reverse.py index 9ab1667c5..b26b448c9 100644 --- a/tests/test_reverse.py +++ b/tests/test_reverse.py @@ -1,6 +1,5 @@ -from django.conf.urls import url from django.test import TestCase, override_settings -from django.urls import NoReverseMatch +from django.urls import NoReverseMatch, path from rest_framework.reverse import reverse from rest_framework.test import APIRequestFactory @@ -13,7 +12,7 @@ def null_view(request): urlpatterns = [ - url(r'^view$', null_view, name='view'), + path('view', null_view, name='view'), ] diff --git a/tests/test_routers.py b/tests/test_routers.py index 007cb4768..f767a843d 100644 --- a/tests/test_routers.py +++ b/tests/test_routers.py @@ -1,11 +1,10 @@ from collections import namedtuple import pytest -from django.conf.urls import include, url from django.core.exceptions import ImproperlyConfigured from django.db import models from django.test import TestCase, override_settings -from django.urls import resolve, reverse +from django.urls import include, path, resolve, reverse from rest_framework import permissions, serializers, viewsets from rest_framework.decorators import action @@ -118,7 +117,7 @@ class TestSimpleRouter(URLPatternsTestCase, TestCase): router.register('basics', BasicViewSet, basename='basic') urlpatterns = [ - url(r'^api/', include(router.urls)), + path('api/', include(router.urls)), ] def setUp(self): @@ -163,8 +162,8 @@ class TestSimpleRouter(URLPatternsTestCase, TestCase): class TestRootView(URLPatternsTestCase, TestCase): urlpatterns = [ - url(r'^non-namespaced/', include(namespaced_router.urls)), - url(r'^namespaced/', include((namespaced_router.urls, 'namespaced'), namespace='namespaced')), + path('non-namespaced/', include(namespaced_router.urls)), + path('namespaced/', include((namespaced_router.urls, 'namespaced'), namespace='namespaced')), ] def test_retrieve_namespaced_root(self): @@ -181,8 +180,8 @@ class TestCustomLookupFields(URLPatternsTestCase, TestCase): Ensure that custom lookup fields are correctly routed. """ urlpatterns = [ - url(r'^example/', include(notes_router.urls)), - url(r'^example2/', include(kwarged_notes_router.urls)), + path('example/', include(notes_router.urls)), + path('example2/', include(kwarged_notes_router.urls)), ] def setUp(self): @@ -238,8 +237,8 @@ class TestLookupUrlKwargs(URLPatternsTestCase, TestCase): Setup a deep lookup_field, but map it to a simple URL kwarg. """ urlpatterns = [ - url(r'^example/', include(notes_router.urls)), - url(r'^example2/', include(kwarged_notes_router.urls)), + path('example/', include(notes_router.urls)), + path('example2/', include(kwarged_notes_router.urls)), ] def setUp(self): @@ -426,7 +425,7 @@ class TestDynamicListAndDetailRouter(TestCase): class TestEmptyPrefix(URLPatternsTestCase, TestCase): urlpatterns = [ - url(r'^empty-prefix/', include(empty_prefix_router.urls)), + path('empty-prefix/', include(empty_prefix_router.urls)), ] def test_empty_prefix_list(self): @@ -443,7 +442,7 @@ class TestEmptyPrefix(URLPatternsTestCase, TestCase): class TestRegexUrlPath(URLPatternsTestCase, TestCase): urlpatterns = [ - url(r'^regex/', include(regex_url_path_router.urls)), + path('regex/', include(regex_url_path_router.urls)), ] def test_regex_url_path_list(self): @@ -462,7 +461,7 @@ class TestRegexUrlPath(URLPatternsTestCase, TestCase): class TestViewInitkwargs(URLPatternsTestCase, TestCase): urlpatterns = [ - url(r'^example/', include(notes_router.urls)), + path('example/', include(notes_router.urls)), ] def test_suffix(self): diff --git a/tests/test_testing.py b/tests/test_testing.py index 8094bfd8d..cc60e4f00 100644 --- a/tests/test_testing.py +++ b/tests/test_testing.py @@ -1,9 +1,9 @@ from io import BytesIO -from django.conf.urls import url from django.contrib.auth.models import User from django.shortcuts import redirect from django.test import TestCase, override_settings +from django.urls import path from rest_framework import fields, serializers from rest_framework.decorators import api_view @@ -47,10 +47,10 @@ def post_view(request): urlpatterns = [ - url(r'^view/$', view), - url(r'^session-view/$', session_view), - url(r'^redirect-view/$', redirect_view), - url(r'^post-view/$', post_view) + path('view/', view), + path('session-view/', session_view), + path('redirect-view/', redirect_view), + path('post-view/', post_view) ] @@ -284,7 +284,7 @@ class TestAPIRequestFactory(TestCase): class TestUrlPatternTestCase(URLPatternsTestCase): urlpatterns = [ - url(r'^$', view), + path('', view), ] @classmethod diff --git a/tests/test_urlpatterns.py b/tests/test_urlpatterns.py index 90820b532..adcd0a742 100644 --- a/tests/test_urlpatterns.py +++ b/tests/test_urlpatterns.py @@ -1,8 +1,7 @@ from collections import namedtuple -from django.conf.urls import include, url from django.test import TestCase -from django.urls import Resolver404, URLResolver, path, re_path +from django.urls import Resolver404, URLResolver, include, path, re_path from django.urls.resolvers import RegexPattern from rest_framework.test import APIRequestFactory @@ -61,7 +60,7 @@ class FormatSuffixTests(TestCase): def test_trailing_slash(self): urlpatterns = [ - url(r'^test/$', dummy_view), + path('test/', dummy_view), ] self._test_trailing_slash(urlpatterns) @@ -81,7 +80,7 @@ class FormatSuffixTests(TestCase): def test_format_suffix(self): urlpatterns = [ - url(r'^test$', dummy_view), + path('test', dummy_view), ] self._test_format_suffix(urlpatterns) @@ -116,7 +115,7 @@ class FormatSuffixTests(TestCase): def test_default_args(self): urlpatterns = [ - url(r'^test$', dummy_view, {'foo': 'bar'}), + path('test', dummy_view, {'foo': 'bar'}), ] self._test_default_args(urlpatterns) @@ -135,15 +134,6 @@ class FormatSuffixTests(TestCase): self._resolve_urlpatterns(urlpatterns, test_paths) def test_included_urls(self): - nested_patterns = [ - url(r'^path$', dummy_view) - ] - urlpatterns = [ - url(r'^test/', include(nested_patterns), {'foo': 'bar'}), - ] - self._test_included_urls(urlpatterns) - - def test_included_urls_django2(self): nested_patterns = [ path('path', dummy_view) ] @@ -152,44 +142,35 @@ class FormatSuffixTests(TestCase): ] self._test_included_urls(urlpatterns) - def test_included_urls_django2_mixed(self): - nested_patterns = [ - path('path', dummy_view) - ] - urlpatterns = [ - url('^test/', include(nested_patterns), {'foo': 'bar'}), - ] - self._test_included_urls(urlpatterns) - - def test_included_urls_django2_mixed_args(self): + def test_included_urls_mixed(self): nested_patterns = [ path('path/', dummy_view), - url('^url/(?P[0-9]+)$', dummy_view) + re_path(r'^re_path/(?P[0-9]+)$', dummy_view) ] urlpatterns = [ - url('^purl/(?P[0-9]+)/', include(nested_patterns), {'foo': 'bar'}), + re_path(r'^pre_path/(?P[0-9]+)/', include(nested_patterns), {'foo': 'bar'}), path('ppath//', include(nested_patterns), {'foo': 'bar'}), ] test_paths = [ - # parent url() nesting child path() - URLTestPath('/purl/87/path/42', (), {'parent': '87', 'child': 42, 'foo': 'bar', }), - URLTestPath('/purl/87/path/42.api', (), {'parent': '87', 'child': 42, 'foo': 'bar', 'format': 'api'}), - URLTestPath('/purl/87/path/42.asdf', (), {'parent': '87', 'child': 42, 'foo': 'bar', 'format': 'asdf'}), + # parent re_path() nesting child path() + URLTestPath('/pre_path/87/path/42', (), {'parent': '87', 'child': 42, 'foo': 'bar', }), + URLTestPath('/pre_path/87/path/42.api', (), {'parent': '87', 'child': 42, 'foo': 'bar', 'format': 'api'}), + URLTestPath('/pre_path/87/path/42.asdf', (), {'parent': '87', 'child': 42, 'foo': 'bar', 'format': 'asdf'}), - # parent path() nesting child url() - URLTestPath('/ppath/87/url/42', (), {'parent': 87, 'child': '42', 'foo': 'bar', }), - URLTestPath('/ppath/87/url/42.api', (), {'parent': 87, 'child': '42', 'foo': 'bar', 'format': 'api'}), - URLTestPath('/ppath/87/url/42.asdf', (), {'parent': 87, 'child': '42', 'foo': 'bar', 'format': 'asdf'}), + # parent path() nesting child re_path() + URLTestPath('/ppath/87/re_path/42', (), {'parent': 87, 'child': '42', 'foo': 'bar', }), + URLTestPath('/ppath/87/re_path/42.api', (), {'parent': 87, 'child': '42', 'foo': 'bar', 'format': 'api'}), + URLTestPath('/ppath/87/re_path/42.asdf', (), {'parent': 87, 'child': '42', 'foo': 'bar', 'format': 'asdf'}), # parent path() nesting child path() URLTestPath('/ppath/87/path/42', (), {'parent': 87, 'child': 42, 'foo': 'bar', }), URLTestPath('/ppath/87/path/42.api', (), {'parent': 87, 'child': 42, 'foo': 'bar', 'format': 'api'}), URLTestPath('/ppath/87/path/42.asdf', (), {'parent': 87, 'child': 42, 'foo': 'bar', 'format': 'asdf'}), - # parent url() nesting child url() - URLTestPath('/purl/87/url/42', (), {'parent': '87', 'child': '42', 'foo': 'bar', }), - URLTestPath('/purl/87/url/42.api', (), {'parent': '87', 'child': '42', 'foo': 'bar', 'format': 'api'}), - URLTestPath('/purl/87/url/42.asdf', (), {'parent': '87', 'child': '42', 'foo': 'bar', 'format': 'asdf'}), + # parent re_path() nesting child re_path() + URLTestPath('/pre_path/87/re_path/42', (), {'parent': '87', 'child': '42', 'foo': 'bar', }), + URLTestPath('/pre_path/87/re_path/42.api', (), {'parent': '87', 'child': '42', 'foo': 'bar', 'format': 'api'}), + URLTestPath('/pre_path/87/re_path/42.asdf', (), {'parent': '87', 'child': '42', 'foo': 'bar', 'format': 'asdf'}), ] self._resolve_urlpatterns(urlpatterns, test_paths) @@ -202,13 +183,13 @@ class FormatSuffixTests(TestCase): ] self._resolve_urlpatterns(urlpatterns, test_paths, allowed=allowed_formats) - def test_allowed_formats(self): + def test_allowed_formats_re_path(self): urlpatterns = [ - url('^test$', dummy_view), + re_path(r'^test$', dummy_view), ] self._test_allowed_formats(urlpatterns) - def test_allowed_formats_django2(self): + def test_allowed_formats_path(self): urlpatterns = [ path('test', dummy_view), ] diff --git a/tests/test_utils.py b/tests/test_utils.py index 500c6a3fa..c72f680fe 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,7 +1,7 @@ from unittest import mock -from django.conf.urls import url from django.test import TestCase, override_settings +from django.urls import path from rest_framework.decorators import action from rest_framework.routers import SimpleRouter @@ -64,12 +64,12 @@ class ResourceViewSet(ModelViewSet): router = SimpleRouter() router.register(r'resources', ResourceViewSet) urlpatterns = [ - url(r'^$', Root.as_view()), - url(r'^resource/$', ResourceRoot.as_view()), - url(r'^resource/customname$', CustomNameResourceInstance.as_view()), - url(r'^resource/(?P[0-9]+)$', ResourceInstance.as_view()), - url(r'^resource/(?P[0-9]+)/$', NestedResourceRoot.as_view()), - url(r'^resource/(?P[0-9]+)/(?P[A-Za-z]+)$', NestedResourceInstance.as_view()), + path('', Root.as_view()), + path('resource/', ResourceRoot.as_view()), + path('resource/customname', CustomNameResourceInstance.as_view()), + path('resource/', ResourceInstance.as_view()), + path('resource//', NestedResourceRoot.as_view()), + path('resource//', NestedResourceInstance.as_view()), ] urlpatterns += router.urls diff --git a/tests/test_versioning.py b/tests/test_versioning.py index d4e269df3..d40d54229 100644 --- a/tests/test_versioning.py +++ b/tests/test_versioning.py @@ -1,6 +1,6 @@ import pytest -from django.conf.urls import include, url from django.test import override_settings +from django.urls import include, path, re_path from rest_framework import serializers, status, versioning from rest_framework.decorators import APIView @@ -144,14 +144,14 @@ class TestRequestVersion: class TestURLReversing(URLPatternsTestCase, APITestCase): included = [ - url(r'^namespaced/$', dummy_view, name='another'), - url(r'^example/(?P\d+)/$', dummy_pk_view, name='example-detail') + path('namespaced/', dummy_view, name='another'), + path('example//', dummy_pk_view, name='example-detail') ] urlpatterns = [ - url(r'^v1/', include((included, 'v1'), namespace='v1')), - url(r'^another/$', dummy_view, name='another'), - url(r'^(?P[v1|v2]+)/another/$', dummy_view, name='another'), + path('v1/', include((included, 'v1'), namespace='v1')), + path('another/', dummy_view, name='another'), + re_path(r'^(?P[v1|v2]+)/another/$', dummy_view, name='another'), ] def test_reverse_unversioned(self): @@ -310,12 +310,12 @@ class TestAllowedAndDefaultVersion: class TestHyperlinkedRelatedField(URLPatternsTestCase, APITestCase): included = [ - url(r'^namespaced/(?P\d+)/$', dummy_pk_view, name='namespaced'), + path('namespaced//', dummy_pk_view, name='namespaced'), ] urlpatterns = [ - url(r'^v1/', include((included, 'v1'), namespace='v1')), - url(r'^v2/', include((included, 'v2'), namespace='v2')) + path('v1/', include((included, 'v1'), namespace='v1')), + path('v2/', include((included, 'v2'), namespace='v2')) ] def setUp(self): @@ -342,17 +342,17 @@ class TestHyperlinkedRelatedField(URLPatternsTestCase, APITestCase): class TestNamespaceVersioningHyperlinkedRelatedFieldScheme(URLPatternsTestCase, APITestCase): nested = [ - url(r'^namespaced/(?P\d+)/$', dummy_pk_view, name='nested'), + path('namespaced//', dummy_pk_view, name='nested'), ] included = [ - url(r'^namespaced/(?P\d+)/$', dummy_pk_view, name='namespaced'), - url(r'^nested/', include((nested, 'nested-namespace'), namespace='nested-namespace')) + path('namespaced//', dummy_pk_view, name='namespaced'), + path('nested/', include((nested, 'nested-namespace'), namespace='nested-namespace')) ] urlpatterns = [ - url(r'^v1/', include((included, 'restframeworkv1'), namespace='v1')), - url(r'^v2/', include((included, 'restframeworkv2'), namespace='v2')), - url(r'^non-api/(?P\d+)/$', dummy_pk_view, name='non-api-view') + path('v1/', include((included, 'restframeworkv1'), namespace='v1')), + path('v2/', include((included, 'restframeworkv2'), namespace='v2')), + path('non-api//', dummy_pk_view, name='non-api-view') ] def _create_field(self, view_name, version): diff --git a/tests/test_viewsets.py b/tests/test_viewsets.py index 2a2997a0b..8842b0b1c 100644 --- a/tests/test_viewsets.py +++ b/tests/test_viewsets.py @@ -2,9 +2,9 @@ from collections import OrderedDict from functools import wraps import pytest -from django.conf.urls import include, url from django.db import models from django.test import TestCase, override_settings +from django.urls import include, path from rest_framework import status from rest_framework.decorators import action @@ -124,7 +124,7 @@ router.register(r'mapping', ActionViewSetWithMapping, basename='mapping') urlpatterns = [ - url(r'^api/', include(router.urls)), + path('api/', include(router.urls)), ] diff --git a/tests/urls.py b/tests/urls.py index 76ada5e3d..d9147683f 100644 --- a/tests/urls.py +++ b/tests/urls.py @@ -3,14 +3,14 @@ URLConf for test suite. We need only the docs urls for DocumentationRenderer tests. """ -from django.conf.urls import url +from django.urls import path from rest_framework.compat import coreapi from rest_framework.documentation import include_docs_urls if coreapi: urlpatterns = [ - url(r'^docs/', include_docs_urls(title='Test Suite API')), + path('docs/', include_docs_urls(title='Test Suite API')), ] else: urlpatterns = []