diff --git a/docs/api-guide/routers.md b/docs/api-guide/routers.md index d2d65d951..91ef0b96e 100644 --- a/docs/api-guide/routers.md +++ b/docs/api-guide/routers.md @@ -167,17 +167,22 @@ This behavior can be modified by setting the `trailing_slash` argument to `False Trailing slashes are conventional in Django, but are not used by default in some other frameworks such as Rails. Which style you choose to use is largely a matter of preference, although some javascript frameworks may expect a particular routing style. -The router will match lookup values containing any characters except slashes and period characters. For a more restrictive (or lenient) lookup pattern, set the `lookup_value_regex` attribute on the viewset. For example, you can limit the lookup to valid UUIDs: +By default the URLs created by `SimpleRouter` use regular expressions. This behavior can be modified by setting the `use_regex_path` argument to `False` when instantiating the router, in this case [path converters][path-converters-topic-reference] are used. For example: + + router = SimpleRouter(use_regex_path=False) + +**Note**: `use_regex_path=False` only works with Django 2.x or above, since this feature was introduced in 2.0.0. See [release note][simplified-routing-release-note] + + +The router will match lookup values containing any characters except slashes and period characters. For a more restrictive (or lenient) lookup pattern, set the `lookup_value_regex` attribute on the viewset or `lookup_value_converter` if using path converters. For example, you can limit the lookup to valid UUIDs: class MyModelViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet): lookup_field = 'my_model_id' lookup_value_regex = '[0-9a-f]{32}' -By default, the URLs created by `SimpleRouter` use regular expressions. This behavior can be modified by setting the `use_regex_path` argument to `False` when instantiating the router, in this case [path converters][path-converters-topic-reference] are used. For example: - - router = SimpleRouter(use_regex_path=False) - -**Note**: `use_regex_path=False` only works with Django 2.x or above, since this feature was introduced in 2.0.0. See [release note][simplified-routing-release-note] + class MyPathModelViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet): + lookup_field = 'my_model_uuid' + lookup_value_converter = 'uuid' ## DefaultRouter diff --git a/rest_framework/routers.py b/rest_framework/routers.py index bcc280f13..5b9cc3674 100644 --- a/rest_framework/routers.py +++ b/rest_framework/routers.py @@ -125,13 +125,14 @@ class SimpleRouter(BaseRouter): def __init__(self, trailing_slash=True, use_regex_path=True): self.trailing_slash = '/' if trailing_slash else '' + self._use_regex = use_regex_path if use_regex_path: - self._base_regex = '(?P<{lookup_prefix}{lookup_url_kwarg}>{lookup_value})' - self._default_regex = '[^/.]+' + self._base_pattern = '(?P<{lookup_prefix}{lookup_url_kwarg}>{lookup_value})' + self._default_value_pattern = '[^/.]+' self._url_conf = re_path else: - self._base_regex = '<{lookup_value}:{lookup_prefix}{lookup_url_kwarg}>' - self._default_regex = 'path' + self._base_pattern = '<{lookup_value}:{lookup_prefix}{lookup_url_kwarg}>' + self._default_value_pattern = 'path' self._url_conf = path # remove regex characters from routes _routes = [] @@ -237,8 +238,14 @@ class SimpleRouter(BaseRouter): # consume `.json` style suffixes and should break at '/' boundaries. lookup_field = getattr(viewset, 'lookup_field', 'pk') lookup_url_kwarg = getattr(viewset, 'lookup_url_kwarg', None) or lookup_field - lookup_value = getattr(viewset, 'lookup_value_regex', self._default_regex) - return self._base_regex.format( + lookup_value = None + if not self._use_regex: + # try to get a more appropriate attribute when not using regex + lookup_value = getattr(viewset, 'lookup_value_converter', None) + if lookup_value is None: + # fallback to legacy + lookup_value = getattr(viewset, 'lookup_value_regex', self._default_value_pattern) + return self._base_pattern.format( lookup_prefix=lookup_prefix, lookup_url_kwarg=lookup_url_kwarg, lookup_value=lookup_value