diff --git a/rest_framework/compat.py b/rest_framework/compat.py index b164f09c1..c0aa1d2fc 100644 --- a/rest_framework/compat.py +++ b/rest_framework/compat.py @@ -25,14 +25,35 @@ from django.views.generic import View try: from django.urls import ( - NoReverseMatch, RegexURLPattern, RegexURLResolver, ResolverMatch, Resolver404, get_script_prefix, reverse, reverse_lazy, resolve + NoReverseMatch, URLPattern as RegexURLPattern, URLResolver as RegexURLResolver, ResolverMatch, Resolver404, get_script_prefix, reverse, reverse_lazy, resolve ) + except ImportError: from django.core.urlresolvers import ( # Will be removed in Django 2.0 NoReverseMatch, RegexURLPattern, RegexURLResolver, ResolverMatch, Resolver404, get_script_prefix, reverse, reverse_lazy, resolve ) +def get_regex_pattern(urlpattern): + if hasattr(urlpattern, 'pattern'): + # Django 2.0 + return urlpattern.pattern.regex.pattern + else: + # Django < 2.0 + return urlpattern.regex.pattern + + +def make_url_resolver(regex, urlpatterns): + try: + # Django 2.0 + from django.urls.resolvers import RegexPattern + return RegexURLResolver(RegexPattern(regex), urlpatterns) + + except ImportError: + # Django < 2.0 + return RegexURLResolver(regex, urlpatterns) + + try: import urlparse # Python 2.x except ImportError: diff --git a/rest_framework/schemas/generators.py b/rest_framework/schemas/generators.py index a9fa15b87..e43aa99fa 100644 --- a/rest_framework/schemas/generators.py +++ b/rest_framework/schemas/generators.py @@ -15,7 +15,7 @@ from django.utils import six from rest_framework import exceptions from rest_framework.compat import ( - RegexURLPattern, RegexURLResolver, coreapi, coreschema + RegexURLPattern, RegexURLResolver, coreapi, coreschema, get_regex_pattern ) from rest_framework.request import clone_request from rest_framework.settings import api_settings @@ -135,7 +135,7 @@ class EndpointEnumerator(object): api_endpoints = [] for pattern in patterns: - path_regex = prefix + pattern.regex.pattern + path_regex = prefix + get_regex_pattern(pattern) if isinstance(pattern, RegexURLPattern): path = self.get_path_from_regex(path_regex) callback = pattern.callback diff --git a/rest_framework/urlpatterns.py b/rest_framework/urlpatterns.py index 90f97f27d..293897b94 100644 --- a/rest_framework/urlpatterns.py +++ b/rest_framework/urlpatterns.py @@ -2,7 +2,7 @@ from __future__ import unicode_literals from django.conf.urls import include, url -from rest_framework.compat import RegexURLResolver +from rest_framework.compat import RegexURLResolver, get_regex_pattern from rest_framework.settings import api_settings @@ -11,7 +11,7 @@ def apply_suffix_patterns(urlpatterns, suffix_pattern, suffix_required): for urlpattern in urlpatterns: if isinstance(urlpattern, RegexURLResolver): # Set of included URL patterns - regex = urlpattern.regex.pattern + regex = get_regex_pattern(urlpattern) namespace = urlpattern.namespace app_name = urlpattern.app_name kwargs = urlpattern.default_kwargs @@ -22,7 +22,7 @@ def apply_suffix_patterns(urlpatterns, suffix_pattern, suffix_required): ret.append(url(regex, include((patterns, app_name), namespace), kwargs)) else: # Regular URL pattern - regex = urlpattern.regex.pattern.rstrip('$').rstrip('/') + suffix_pattern + regex = get_regex_pattern(urlpattern).rstrip('$').rstrip('/') + suffix_pattern view = urlpattern.callback kwargs = urlpattern.default_args name = urlpattern.name diff --git a/tests/test_urlpatterns.py b/tests/test_urlpatterns.py index 7d5aecfe5..7320de479 100644 --- a/tests/test_urlpatterns.py +++ b/tests/test_urlpatterns.py @@ -5,7 +5,7 @@ from collections import namedtuple from django.conf.urls import include, url from django.test import TestCase -from rest_framework.compat import RegexURLResolver, Resolver404 +from rest_framework.compat import Resolver404, make_url_resolver from rest_framework.test import APIRequestFactory from rest_framework.urlpatterns import format_suffix_patterns @@ -28,7 +28,7 @@ class FormatSuffixTests(TestCase): urlpatterns = format_suffix_patterns(urlpatterns) except Exception: self.fail("Failed to apply `format_suffix_patterns` on the supplied urlpatterns") - resolver = RegexURLResolver(r'^/', urlpatterns) + resolver = make_url_resolver(r'^/', urlpatterns) for test_path in test_paths: request = factory.get(test_path.path) try: @@ -43,7 +43,7 @@ class FormatSuffixTests(TestCase): urlpatterns = format_suffix_patterns([ url(r'^test/$', dummy_view), ]) - resolver = RegexURLResolver(r'^/', urlpatterns) + resolver = make_url_resolver(r'^/', urlpatterns) test_paths = [ (URLTestPath('/test.api', (), {'format': 'api'}), True),