| Server IP : 85.214.239.14 / Your IP : 216.73.216.27 Web Server : Apache/2.4.65 (Debian) System : Linux h2886529.stratoserver.net 4.9.0 #1 SMP Mon Sep 30 15:36:27 MSK 2024 x86_64 User : www-data ( 33) PHP Version : 8.2.29 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : OFF Directory : /proc/3/root/srv/modoboa/env/lib/python3.5/site-packages/rest_framework_nested/ |
Upload File : |
"""
Routers for nested resources.
Example:
# urls.py
from rest_framework_nested import routers
router = routers.SimpleRouter()
router.register(r'domains', DomainViewSet)
domains_router = routers.NestedSimpleRouter(router, r'domains', lookup='domain')
domains_router.register(r'nameservers', NameserverViewSet)
url_patterns = patterns('',
url(r'^', include(router.urls)),
url(r'^', include(domains_router.urls)),
)
router = routers.DefaultRouter()
router.register('users', UserViewSet, 'user')
router.register('accounts', AccountViewSet, 'account')
urlpatterns = router.urls
"""
from __future__ import unicode_literals
import sys
import re
from rest_framework.routers import SimpleRouter, DefaultRouter # noqa: F401
if sys.version_info[0] < 3:
IDENTIFIER_REGEX = re.compile(r"^[^\d\W]\w*$")
else:
IDENTIFIER_REGEX = re.compile(r"^[^\d\W]\w*$", re.UNICODE)
class LookupMixin(object):
"""
Deprecated.
No method override is needed since Django Rest Framework 2.4.
"""
class NestedMixin(object):
def __init__(self, parent_router, parent_prefix, *args, **kwargs):
self.parent_router = parent_router
self.parent_prefix = parent_prefix
self.nest_count = getattr(parent_router, 'nest_count', 0) + 1
self.nest_prefix = kwargs.pop('lookup', 'nested_%i' % self.nest_count) + '_'
super(NestedMixin, self).__init__(*args, **kwargs)
if 'trailing_slash' not in kwargs:
# Inherit trailing_slash only when not specified explicitly.
#
# drf transposes the trailing_slash argument into the actual appended value
# within the route urls. This means that, on the parent class, trailing_slash
# is either '/' or '' for the expected kwarg values True or False, respectively.
# If, however, the trailing_slash property has been further customized beyond
# those two values (for example, to add an optional slash with '/?'), we won't
# be able to set it through the kwargs.
#
# By copying the value of trailing_slash directly, we ensure that our inherited
# behavior is ALWAYS consistent with the parent. If we didn't, we might create
# a situation where the parent's trailing slash is truthy (but not '/') and
# we set our trailing slash to just '/', leading to inconsistent behavior.
self.trailing_slash = parent_router.trailing_slash
parent_registry = [registered for registered
in self.parent_router.registry
if registered[0] == self.parent_prefix]
try:
parent_registry = parent_registry[0]
parent_prefix, parent_viewset, parent_basename = parent_registry
except:
raise RuntimeError('parent registered resource not found')
self.check_valid_name(self.nest_prefix)
nested_routes = []
parent_lookup_regex = parent_router.get_lookup_regex(parent_viewset, self.nest_prefix)
self.parent_regex = '{parent_prefix}/{parent_lookup_regex}/'.format(
parent_prefix=parent_prefix,
parent_lookup_regex=parent_lookup_regex
)
# If there is no parent prefix, the first part of the url is probably
# controlled by the project's urls.py and the router is in an app,
# so a slash in the beginning will (A) cause Django to give warnings
# and (B) generate URLs that will require using `//`
if not self.parent_prefix and self.parent_regex[0] == '/':
self.parent_regex = self.parent_regex[1:]
if hasattr(parent_router, 'parent_regex'):
self.parent_regex = parent_router.parent_regex + self.parent_regex
for route in self.routes:
route_contents = route._asdict()
# This will get passed through .format in a little bit, so we need
# to escape it
escaped_parent_regex = self.parent_regex.replace('{', '{{').replace('}', '}}')
route_contents['url'] = route.url.replace('^', '^' + escaped_parent_regex)
nested_routes.append(type(route)(**route_contents))
self.routes = nested_routes
def check_valid_name(self, value):
if IDENTIFIER_REGEX.match(value) is None:
raise ValueError("lookup argument '{}' needs to be valid python identifier".format(value))
class NestedSimpleRouter(NestedMixin, SimpleRouter):
""" Create a NestedSimpleRouter nested within `parent_router`
Args:
parent_router: Parent router. Maybe be a SimpleRouter or another nested
router.
parent_prefix: The url prefix within parent_router under which the
routes from this router should be nested.
lookup:
The regex variable that matches an instance of the parent-resource
will be called '<lookup>_<parent-viewset.lookup_field>'
In the example above, lookup=domain and the parent viewset looks up
on 'pk' so the parent lookup regex will be 'domain_pk'.
Default: 'nested_<n>' where <n> is 1+parent_router.nest_count
"""
pass
class NestedDefaultRouter(NestedMixin, DefaultRouter):
""" Create a NestedDefaultRouter nested within `parent_router`
Args:
parent_router: Parent router. Maybe be a DefaultRouter or another nested
router.
parent_prefix: The url prefix within parent_router under which the
routes from this router should be nested.
lookup:
The regex variable that matches an instance of the parent-resource
will be called '<lookup>_<parent-viewset.lookup_field>'
In the example above, lookup=domain and the parent viewset looks up
on 'pk' so the parent lookup regex will be 'domain_pk'.
Default: 'nested_<n>' where <n> is 1+parent_router.nest_count
"""
pass