mirror of
https://github.com/django/django.git
synced 2025-02-21 23:05:09 +00:00
Fixed #31061 -- Ignored positional args in django.urls.resolve() when all optional named parameters are missing.
Regression in 76b993a117b61c41584e95149a67d8a1e9f49dd1. Thanks Claude Paroz for the report and Carlton Gibson for reviews.
This commit is contained in:
parent
f138e75910
commit
82a88d2f48
@ -158,8 +158,9 @@ class RegexPattern(CheckURLMixin):
|
||||
# If there are any named groups, use those as kwargs, ignoring
|
||||
# non-named groups. Otherwise, pass all non-named arguments as
|
||||
# positional arguments.
|
||||
kwargs = {k: v for k, v in match.groupdict().items() if v is not None}
|
||||
kwargs = match.groupdict()
|
||||
args = () if kwargs else match.groups()
|
||||
kwargs = {k: v for k, v in kwargs.items() if v is not None}
|
||||
return path[match.end():], args, kwargs
|
||||
return None
|
||||
|
||||
|
@ -13,3 +13,7 @@ Bugfixes
|
||||
inside Jupyter and other environments that force an async context, by adding
|
||||
and option to disable :ref:`async-safety` mechanism with
|
||||
``DJANGO_ALLOW_ASYNC_UNSAFE`` environment variable (:ticket:`31056`).
|
||||
|
||||
* Fixed a regression in Django 3.0 where ``RegexPattern``, used by
|
||||
:func:`~django.urls.re_path`, returned positional arguments to be passed to
|
||||
the view when all optional named groups were missing (:ticket:`31061`).
|
||||
|
@ -53,7 +53,7 @@ algorithm the system follows to determine which Python code to execute:
|
||||
arguments:
|
||||
|
||||
* An instance of :class:`~django.http.HttpRequest`.
|
||||
* If the matched URL pattern returned no named groups, then the
|
||||
* If the matched URL pattern contained no named groups, then the
|
||||
matches from the regular expression are provided as positional arguments.
|
||||
* The keyword arguments are made up of any named parts matched by the
|
||||
path expression, overridden by any arguments specified in the optional
|
||||
|
@ -12,6 +12,11 @@ urlpatterns = [
|
||||
path('included_urls/', include('urlpatterns.included_urls')),
|
||||
re_path(r'^regex/(?P<pk>[0-9]+)/$', views.empty_view, name='regex'),
|
||||
re_path(r'^regex_optional/(?P<arg1>\d+)/(?:(?P<arg2>\d+)/)?', views.empty_view, name='regex_optional'),
|
||||
re_path(
|
||||
r'^regex_only_optional/(?:(?P<arg1>\d+)/)?',
|
||||
views.empty_view,
|
||||
name='regex_only_optional',
|
||||
),
|
||||
path('', include('urlpatterns.more_urls')),
|
||||
path('<lang>/<path:url>/', views.empty_view, name='lang-and-path'),
|
||||
]
|
||||
|
@ -68,6 +68,16 @@ class SimplifiedURLTests(SimpleTestCase):
|
||||
r'^regex_optional/(?P<arg1>\d+)/(?:(?P<arg2>\d+)/)?',
|
||||
)
|
||||
|
||||
def test_re_path_with_missing_optional_parameter(self):
|
||||
match = resolve('/regex_only_optional/')
|
||||
self.assertEqual(match.url_name, 'regex_only_optional')
|
||||
self.assertEqual(match.kwargs, {})
|
||||
self.assertEqual(match.args, ())
|
||||
self.assertEqual(
|
||||
match.route,
|
||||
r'^regex_only_optional/(?:(?P<arg1>\d+)/)?',
|
||||
)
|
||||
|
||||
def test_path_lookup_with_inclusion(self):
|
||||
match = resolve('/included_urls/extra/something/')
|
||||
self.assertEqual(match.url_name, 'inner-extra')
|
||||
|
Loading…
x
Reference in New Issue
Block a user