From what I understand you have a pattern of the form, r'(?P<group>pattern)?'
i.e. a capturing group that you make optional, in which case normally it would return None
if it doesn't match anything.
If you really want to do this rather than refactoring your code, you can inherit from RegexPattern
and override match
by copying it from the source code [GitHub]:
from django.urls.conf import _path
from django.urls.resolvers import RegexPattern
from functools import partial
class MyRegexPattern(RegexPattern):
def match(self, path):
match = self.regex.search(path)
if match:
# If there are any named groups, use those as kwargs, ignoring
# non-named groups. Otherwise, pass all non-named arguments as
# positional arguments.
kwargs = match.groupdict()
args = () if kwargs else match.groups()
# Commented line below from source code
# kwargs = {k: v for k, v in kwargs.items() if v is not None}
return path[match.end():], args, kwargs
return None
# Make the re_path function
re_path = partial(_path, Pattern=MyRegexPattern)
Rather than using this workaround though the better solution would be to either specify multiple url patterns instead of one or fix your views to allow such situations.
Suppose you had patterns like:
re_path(r'^prefix(?P<group>pattern)?suffix/$', views.some_view),
You can write two patterns like:
re_path(r'^prefix(?P<group>pattern)suffix/$', views.some_view),
re_path(r'^prefixsuffix/$', views.some_view, kwargs={'group': None}),
In case you previously had a function based view like:
def some_view(request, group):
...
Simply change it so that group has a default value of None
:
def some_view(request, group=None):
...
If in class based views you were writing self.kwargs['group']
instead write self.kwargs.get('group')
.