mirror of
https://github.com/encode/django-rest-framework.git
synced 2024-11-23 01:57:00 +03:00
format_suffix_patterns
is applied before the trailing slash.
This commit is contained in:
parent
ca0a7ee1de
commit
e7e5946c2e
|
@ -21,7 +21,7 @@ def apply_suffix_patterns(urlpatterns, suffix_pattern, suffix_required):
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Regular URL pattern
|
# Regular URL pattern
|
||||||
regex = urlpattern.regex.pattern.rstrip('$') + suffix_pattern
|
regex = urlpattern.regex.pattern.rstrip('$').rstrip('/') + suffix_pattern
|
||||||
view = urlpattern._callback or urlpattern._callback_str
|
view = urlpattern._callback or urlpattern._callback_str
|
||||||
kwargs = urlpattern.default_args
|
kwargs = urlpattern.default_args
|
||||||
name = urlpattern.name
|
name = urlpattern.name
|
||||||
|
@ -55,8 +55,8 @@ def format_suffix_patterns(urlpatterns, suffix_required=False, allowed=None):
|
||||||
allowed_pattern = allowed[0]
|
allowed_pattern = allowed[0]
|
||||||
else:
|
else:
|
||||||
allowed_pattern = '(%s)' % '|'.join(allowed)
|
allowed_pattern = '(%s)' % '|'.join(allowed)
|
||||||
suffix_pattern = r'\.(?P<%s>%s)$' % (suffix_kwarg, allowed_pattern)
|
suffix_pattern = r'\.(?P<%s>%s)/?$' % (suffix_kwarg, allowed_pattern)
|
||||||
else:
|
else:
|
||||||
suffix_pattern = r'\.(?P<%s>[a-z0-9]+)$' % suffix_kwarg
|
suffix_pattern = r'\.(?P<%s>[a-z0-9]+)/?$' % suffix_kwarg
|
||||||
|
|
||||||
return apply_suffix_patterns(urlpatterns, suffix_pattern, suffix_required)
|
return apply_suffix_patterns(urlpatterns, suffix_pattern, suffix_required)
|
||||||
|
|
|
@ -17,7 +17,8 @@ def dummy_view(request, *args, **kwargs):
|
||||||
|
|
||||||
class FormatSuffixTests(TestCase):
|
class FormatSuffixTests(TestCase):
|
||||||
"""
|
"""
|
||||||
Tests `format_suffix_patterns` against different URLPatterns to ensure the URLs still resolve properly, including any captured parameters.
|
Tests `format_suffix_patterns` against different URLPatterns to ensure the
|
||||||
|
URLs still resolve properly, including any captured parameters.
|
||||||
"""
|
"""
|
||||||
def _resolve_urlpatterns(self, urlpatterns, test_paths):
|
def _resolve_urlpatterns(self, urlpatterns, test_paths):
|
||||||
factory = APIRequestFactory()
|
factory = APIRequestFactory()
|
||||||
|
@ -35,11 +36,37 @@ class FormatSuffixTests(TestCase):
|
||||||
self.assertEqual(callback_args, test_path.args)
|
self.assertEqual(callback_args, test_path.args)
|
||||||
self.assertEqual(callback_kwargs, test_path.kwargs)
|
self.assertEqual(callback_kwargs, test_path.kwargs)
|
||||||
|
|
||||||
|
def test_trailing_slash(self):
|
||||||
|
factory = APIRequestFactory()
|
||||||
|
urlpatterns = format_suffix_patterns([
|
||||||
|
url(r'^test/$', dummy_view),
|
||||||
|
])
|
||||||
|
resolver = urlresolvers.RegexURLResolver(r'^/', urlpatterns)
|
||||||
|
|
||||||
|
test_paths = [
|
||||||
|
(URLTestPath('/test.api', (), {'format': 'api'}), True),
|
||||||
|
(URLTestPath('/test/.api', (), {'format': 'api'}), False),
|
||||||
|
(URLTestPath('/test.api/', (), {'format': 'api'}), True),
|
||||||
|
]
|
||||||
|
|
||||||
|
for test_path, expected_resolved in test_paths:
|
||||||
|
request = factory.get(test_path.path)
|
||||||
|
try:
|
||||||
|
callback, callback_args, callback_kwargs = resolver.resolve(request.path_info)
|
||||||
|
except urlresolvers.Resolver404:
|
||||||
|
callback, callback_args, callback_kwargs = (None, None, None)
|
||||||
|
if not expected_resolved:
|
||||||
|
assert callback is None
|
||||||
|
continue
|
||||||
|
|
||||||
|
print(test_path, callback, callback_args, callback_kwargs)
|
||||||
|
assert callback_args == test_path.args
|
||||||
|
assert callback_kwargs == test_path.kwargs
|
||||||
|
|
||||||
def test_format_suffix(self):
|
def test_format_suffix(self):
|
||||||
urlpatterns = patterns(
|
urlpatterns = [
|
||||||
'',
|
|
||||||
url(r'^test$', dummy_view),
|
url(r'^test$', dummy_view),
|
||||||
)
|
]
|
||||||
test_paths = [
|
test_paths = [
|
||||||
URLTestPath('/test', (), {}),
|
URLTestPath('/test', (), {}),
|
||||||
URLTestPath('/test.api', (), {'format': 'api'}),
|
URLTestPath('/test.api', (), {'format': 'api'}),
|
||||||
|
@ -48,10 +75,9 @@ class FormatSuffixTests(TestCase):
|
||||||
self._resolve_urlpatterns(urlpatterns, test_paths)
|
self._resolve_urlpatterns(urlpatterns, test_paths)
|
||||||
|
|
||||||
def test_default_args(self):
|
def test_default_args(self):
|
||||||
urlpatterns = patterns(
|
urlpatterns = [
|
||||||
'',
|
|
||||||
url(r'^test$', dummy_view, {'foo': 'bar'}),
|
url(r'^test$', dummy_view, {'foo': 'bar'}),
|
||||||
)
|
]
|
||||||
test_paths = [
|
test_paths = [
|
||||||
URLTestPath('/test', (), {'foo': 'bar', }),
|
URLTestPath('/test', (), {'foo': 'bar', }),
|
||||||
URLTestPath('/test.api', (), {'foo': 'bar', 'format': 'api'}),
|
URLTestPath('/test.api', (), {'foo': 'bar', 'format': 'api'}),
|
||||||
|
@ -60,14 +86,12 @@ class FormatSuffixTests(TestCase):
|
||||||
self._resolve_urlpatterns(urlpatterns, test_paths)
|
self._resolve_urlpatterns(urlpatterns, test_paths)
|
||||||
|
|
||||||
def test_included_urls(self):
|
def test_included_urls(self):
|
||||||
nested_patterns = patterns(
|
nested_patterns = [
|
||||||
'',
|
|
||||||
url(r'^path$', dummy_view)
|
url(r'^path$', dummy_view)
|
||||||
)
|
]
|
||||||
urlpatterns = patterns(
|
urlpatterns = [
|
||||||
'',
|
|
||||||
url(r'^test/', include(nested_patterns), {'foo': 'bar'}),
|
url(r'^test/', include(nested_patterns), {'foo': 'bar'}),
|
||||||
)
|
]
|
||||||
test_paths = [
|
test_paths = [
|
||||||
URLTestPath('/test/path', (), {'foo': 'bar', }),
|
URLTestPath('/test/path', (), {'foo': 'bar', }),
|
||||||
URLTestPath('/test/path.api', (), {'foo': 'bar', 'format': 'api'}),
|
URLTestPath('/test/path.api', (), {'foo': 'bar', 'format': 'api'}),
|
||||||
|
|
Loading…
Reference in New Issue
Block a user