def get_lookup_routes(self, viewset): ret = [self.routes[0]] for route in self.lookups_routes: if route.mapping == {'{httpmethod}': '{methodname}'}: for extra_action in viewset.get_extra_actions(): methodname = extra_action.__name__ mapping = extra_action.mapping detail = extra_action.detail initkwargs = route.initkwargs.copy() initkwargs.update(extra_action.kwargs) name = self.replace_methodname(route.name, methodname) if 'extra_lookup_fields' in initkwargs: uri = route.url[1] uri = self.replace_methodname(uri, methodname) ret.append(routers.Route( url=uri, mapping=mapping, name=f'{name}-extra', initkwargs=initkwargs, detail=detail )) uri = self.replace_methodname(route.url[0], methodname) ret.append(routers.Route( url=uri, mapping=mapping, name=name, initkwargs=initkwargs, detail=detail )) else: # Standard route ret.append(route) return ret
class CustomRouter(routers.SimpleRouter): routes = [ # List route. routers.Route(url=r'^{prefix}{trailing_slash}$', mapping={'get': 'list'}, name='{basename}-list', initkwargs={'suffix': 'List'}), # Dynamically generated list routes. # Generated using @list_route decorator # on methods of the viewset. routers.DynamicListRoute( url=r'^{prefix}/{methodname}{trailing_slash}$', name='{basename}-{methodnamehyphen}', initkwargs={}), # Detail route. routers.Route(url=r'^{prefix}/{lookup}{trailing_slash}$', mapping={ 'get': 'retrieve', 'post': 'create', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy' }, name='{basename}-detail', initkwargs={'suffix': 'Instance'}), # Dynamically generated detail routes. # Generated using @detail_route decorator on methods of the viewset. routers.DynamicDetailRoute( url=r'^{prefix}/{lookup}/{methodname}{trailing_slash}$', name='{basename}-{methodnamehyphen}', initkwargs={}), ]
def get_routes(self, viewset): ret = super().get_routes(viewset) lookup_field = getattr(viewset, 'lookup_field', None) if lookup_field: # List route. ret.append(routers.Route( url=r'^{prefix}{trailing_slash}$', mapping={ 'get': 'list', 'post': 'create' }, name='{basename}-list', detail=False, initkwargs={'suffix': 'List'}, )) detail_url_regex = r'^{prefix}/{lookup}{trailing_slash}$' if not lookup_field: detail_url_regex = r'^{prefix}{trailing_slash}$' # Detail route. ret.append(routers.Route( url=detail_url_regex, mapping={ 'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy' }, name='{basename}-detail', detail=True, initkwargs={'suffix': 'Instance'} )) return ret
def __init__(self, *args, **kwargs): super(MultiLookupRouter, self).__init__(*args, **kwargs) self.lookups_routes = [] self.lookups_routes.append( routers.Route(url=r'^{prefix}/{lookups}{trailing_slash}$', mapping={ 'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy' }, name='{basename}-detail', initkwargs={'suffix': 'Instance'})) self.lookups_routes.append( routers.Route(url=r'^{prefix}/{lookup}{trailing_slash}$', mapping={ 'get': 'list', 'post': 'create' }, name='{basename}-list', initkwargs={'suffix': 'List'})) # Dynamically generated routes. # Generated using @action or @link decorators on methods of the viewset self.lookups_routes.append( routers.Route(url=[ r'^{prefix}/{lookups}/{methodname}{trailing_slash}$', r'^{prefix}/{lookups}/{methodname}/{extra}{trailing_slash}$' ], mapping={ '{httpmethod}': '{methodname}', }, name='{basename}-{methodnamehyphen}', initkwargs={}))
class OrderActionsRouter(routers.SimpleRouter): routes = [ routers.Route( url=r'^{prefix}/$', mapping={ 'get': 'retrieve', 'post': 'create', 'patch': 'partial_update', 'put': 'update', }, name='{basename}-detail', initkwargs={'suffix': 'Detail'} ), routers.DynamicDetailRoute( url=r'^{prefix}/{methodnamehyphen}/$', name='{basename}-{methodnamehyphen}', initkwargs={} ), routers.Route( url=r'{prefix}/pay/(?P<model_label>' + r'|'.join( i['key'].replace('.', '\.') for i in views.PaymentproviderListView.paymentproviders ) + r')/$', mapping={ 'post': 'pay', }, name='{basename}-pay', initkwargs={'suffix': 'Detail'}, ) ]
class HeadRouter(routers.DefaultRouter): routes = [ # List route. routers.Route( url=r'^{prefix}{trailing_slash}$', mapping={ 'head': 'list', 'get': 'list', 'post': 'create' }, name='{basename}-list', initkwargs={'suffix': 'List'} ), # Detail route. routers.Route( url=r'^{prefix}/{lookup}{trailing_slash}$', mapping={ 'head': 'retrieve', 'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy' }, name='{basename}-detail', initkwargs={'suffix': 'Instance'} ), ]
class ProfileRouter(routers.SimpleRouter): routes = [ routers.Route(url=r'^{prefix}/google{trailing_slash}$', mapping={'post': 'google'}, name='{basename}-google', detail=True, initkwargs={}), routers.Route(url=r'^{prefix}/facebook{trailing_slash}$', mapping={'post': 'facebook'}, name='{basename}-facebook', detail=True, initkwargs={}), routers.Route(url=r'^{prefix}/instagram{trailing_slash}$', mapping={'post': 'instagram'}, name='{basename}-instagram', detail=True, initkwargs={}), routers.Route(url=r'^{prefix}{trailing_slash}$', mapping={'post': 'create'}, name='{basename}', detail=True, initkwargs={}), routers.Route(url=r'^{prefix}/request_access{trailing_slash}$', mapping={'post': 'request_access'}, name='{basename}-request-access', detail=True, initkwargs={}), ]
class RestRouter(routers.DefaultRouter): schema_title = "PeeringDB API" schema_url = "" schema_renderers = None routes = [ # List route. routers.Route( url=r"^{prefix}{trailing_slash}$", mapping={ "get": "list", "post": "create" }, name="{basename}-list", detail=False, initkwargs={"suffix": "List"}, ), # Detail route. routers.Route( url=r"^{prefix}/{lookup}{trailing_slash}$", mapping={ "get": "retrieve", "put": "update", "patch": "partial_update", "delete": "destroy", }, name="{basename}-detail", detail=True, initkwargs={"suffix": "Instance"}, ), routers.DynamicRoute( url=r"^{prefix}/{lookup}/{methodnamehyphen}$", name="{basename}-{methodnamehyphen}", detail=True, initkwargs={}, ), # Dynamically generated routes. # Generated using @action or @link decorators on methods of the # viewset. routers.Route( url=r"^{prefix}/{lookup}/{methodname}{trailing_slash}$", mapping={ "{httpmethod}": "{methodname}", }, name="{basename}-{methodnamehyphen}", detail=False, initkwargs={}, ), ] def __init__(self, trailing_slash=False): self.trailing_slash = trailing_slash and "/" or "" super(routers.DefaultRouter, self).__init__(trailing_slash=False)
class SignalsRouterVersion1(routers.DefaultRouter): APIRootView = SignalsAPIRootViewVersion1 # Overriding the `routes` attribute from the default DRF `routes`. We do this to control the # usage of trailing slashes for different routes. In DRF you can only add or remove the # trailing slash for all routes... routes = [ # List route. routers.Route( url=r'^{prefix}/$', mapping={ 'get': 'list', 'post': 'create', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy', }, name='{basename}-list', detail=False, initkwargs={'suffix': 'List'} ), # Dynamically generated list routes. Generated using # @action(detail=False) decorator on methods of the viewset. routers.DynamicRoute( url=r'^{prefix}/{url_path}$', name='{basename}-{url_name}', detail=False, initkwargs={} ), # Detail route. routers.Route( url=r'^{prefix}/{lookup}$', mapping={ 'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy' }, name='{basename}-detail', detail=True, initkwargs={'suffix': 'Instance'} ), # Dynamically generated detail routes. Generated using # @action(detail=True) decorator on methods of the viewset. routers.DynamicRoute( url=r'^{prefix}/{lookup}/{url_path}$', name='{basename}-{url_name}', detail=True, initkwargs={} ), ]
def _get_verb_route(self, action, routes): url_path = routers.escape_curly_brackets(action.url_path) url = r'^{prefix}/{url_path}{trailing_slash}$' if not url_path: url = url.replace('/{url_path}', '') else: url = url.replace('{url_path}', url_path) # 多个 verb 对应相同 url 时,合并 mapping for route in routes: if route.url == url: route.mapping[action.verb_method] = action.__name__ return # name = '{basename}-{url_name}' if not action.url_name: name = name.replace('-{url_name}', '') else: name = name.replace('{url_name}', action.url_name) initkwargs = action.kwargs.copy() routes.append(routers.Route( url=url, mapping={action.verb_method: action.__name__}, name=name, detail=None, initkwargs=initkwargs))
class SimpleRouterEx(routers.SimpleRouter): include_root_view = True include_format_suffixes = True default_schema_renderers = None routes = [ # routers.Route( # url=r'^{prefix}$', # mapping={'get': 'list'}, # name='{basename}-list', # detail=False, # initkwargs={'suffix': 'List'} # ), routers.Route(url=r'^{prefix}/{lookup}$', mapping={'get': 'retrieve'}, name='{basename}-detail', detail=True, initkwargs={'suffix': 'Detail'}), routers.DynamicRoute(url=r'^{prefix}/{lookup}/{url_path}$', name='{basename}-{url_name}', detail=True, initkwargs={}), routers.DynamicRoute(url=r'^{prefix}/{url_path}/{lookup}$', name='{basename}-{url_name}', detail=False, initkwargs={}) ]
class SingletonRouter(routers.SimpleRouter): """Same as default router but without detail route and GET, POST, PUT, PATCH and DELETE maps to same url as list. See CurrentUserViewset for usages. This allows GenericViewSet to be used against a singleton resource. If `/me` endpoint represents currently logged in user you are able to `GET /me`, `PUT /me`, `DELETE /me` and can also add any list_routes like `POST /me/change-avatar`. """ routes = [ # Mapping for list, create, update, partial_update and delete function to http verb. routers.Route( url=r'^{prefix}{trailing_slash}$', mapping={ 'get': 'list', 'post': 'create', 'patch': 'partial_update', 'put': 'update', 'delete': 'destroy', }, name='{basename}', initkwargs={'suffix': ''} ), # Dynamically generated list routes. # Generated using @list_route decorator # on methods of the viewset. routers.DynamicListRoute( url=r'^{prefix}/{methodname}{trailing_slash}$', name='{basename}-{methodnamehyphen}', initkwargs={} ), ]
class SingletonRouter(routers.SimpleRouter): """Same as default router but without detail route and GET, POST, PUT, PATCH and DELETE maps to same url as list. See CurrentUserViewset for usages. This allows GenericViewSet to be used against a singleton resource. If `/me` endpoint represents currently logged in user you are able to `GET /me`, `PUT /me`, `DELETE /me` and can also add any list_routes like `POST /me/change-avatar`. """ routes = [ # Mapping for list, create, update, partial_update and delete function to http verb. routers.Route( url=r"^{prefix}{trailing_slash}$", mapping={ "get": "list", "post": "create", "patch": "partial_update", "put": "update", "delete": "destroy", }, name="{basename}", detail=False, initkwargs={"suffix": ""}, ), # Dynamically generated list routes. # Generated using @action decorator # on methods of the viewset. routers.DynamicRoute( url=r"^{prefix}/{url_path}$", name="{basename}-{url_name}", detail=False, initkwargs={}, ), ]
class CourierRouter(routers.SimpleRouter): routes = [ routers.Route(url=r'^{prefix}/{lookup}$', mapping={ 'get': 'retrieve', 'patch': 'partial_update' }, name='{basename}-detail', detail=True, initkwargs={'suffix': 'Details'}), routers.Route(url=r'^{prefix}$', mapping={'post': 'create'}, name='{basename}-detail', detail=True, initkwargs={'suffix': 'Detail'}), ]
class ProductListRouter(routers.DefaultRouter): routers = [ routers.Route(url=r'^{prefix}/$', mapping={'get': 'list'}, name='{basename}-list', detail=False, initkwargs={'suffix': ''}), ]
class CustomPostOnlyRouter(routers.SimpleRouter): routes = [ routers.Route(url=r'^{prefix}$', mapping={'post': 'create'}, name='{basename}-list', detail=False, initkwargs={'suffix': 'List'}) ]
class ProductRouter(routers.DefaultRouter): routes = [ routers.Route(url=r'^{prefix}/{lookup}/$', mapping={'get': 'retrieve'}, name='{basename}-detail', detail=True, initkwargs={'suffix': ''}), ]
class CustomRouter(routers.SimpleRouter): routes = [ routers.Route(url=r'^{prefix}$', mapping={'get': 'list'}, name='{basename}-kasra', detail=False, initkwargs={'suffix': 'List'}), routers.Route(url=r'^{prefix}/{lookup}$', mapping={'get': 'retrieve'}, name='{basename}-detail', detail=True, initkwargs={'suffix': 'Detail'}), routers.DynamicRoute(url=r'^{prefix}/{lookup}/{url_path}$', name='{basename}-{url_name}', detail=True, initkwargs={}) ]
def make_routes(template_text, mapping): """ Return a Route that substitutes the given template_text in the URL regex. """ return routers.Route( url=r'^{prefix}/{%s}{trailing_slash}$' % template_text, mapping=mapping, name='{basename}-list', initkwargs={'suffix': 'List'})
def make_routes(template_text): return routers.Route( url=r'^{prefix}/{%s}{trailing_slash}$' % template_text, mapping={ 'get': 'list', 'post': 'create' }, name='{basename}-list', initkwargs={'suffix': 'List'})
class PostsRouter(routers.SimpleRouter): routes = [ routers.Route(url=r'^{prefix}{trailing_slash}$', mapping={'get': 'list'}, name='{basename}-list', initkwargs={'suffix': 'List'}, detail=False), routers.Route(url=r'^{prefix}/{lookup}{trailing_slash}$', mapping={'get': 'retrieve'}, name='{basename}-detail', initkwargs={'suffix': 'Detail'}, detail=True), routers.Route(url=r'^{prefix}/{lookup}/update/$', mapping={'put': 'update'}, name='{basename}-update', initkwargs={'suffix': 'Detail'}, detail=True), ]
class ProfileRouter(routers.SimpleRouter): routes = [ routers.Route( url=r'^{prefix}/$', mapping={'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'}, name='{basename}-profile', detail=True, initkwargs={} ), ]
class CustomRestRouter(rest_route.DefaultRouter): include_format_suffixes = False routes = [ # List route. rest_route.Route(url=r'^{prefix}/list$', mapping={ 'get': 'list', }, name='{basename}.list', detail=False, initkwargs={'suffix': 'List'}), rest_route.Route(url=r'^{prefix}/save$', mapping={'post': 'save'}, name='{basename}.save', detail=True, initkwargs={}), rest_route.Route(url=r'^{prefix}/delete$', mapping={'post': 'delete'}, name='{basename}.delete', detail=False, initkwargs={}), rest_route.Route(url=r'^{prefix}/edit$', mapping={ 'get': 'edit', }, name='{basename}.edit', detail=True, initkwargs={}), rest_route.Route(url=r'^{prefix}/metadata$', mapping={ 'get': 'metadata', 'options': 'metadata', }, name='{basename}.metadata', detail=True, initkwargs={}), # Dynamically generated list routes. Generated using # @action(detail=False) decorator on methods of the viewset. rest_route.DynamicRoute(url=r'^{prefix}/{url_path}$', name='{basename}.{url_name}', detail=False, initkwargs={}) ]
class RestRouter(routers.DefaultRouter): schema_title = "PeeringDB API" schema_url = "" schema_renderers = None routes = [ # List route. routers.Route(url=r'^{prefix}{trailing_slash}$', mapping={ 'get': 'list', 'post': 'create' }, name='{basename}-list', initkwargs={'suffix': 'List'}), # Detail route. routers.Route(url=r'^{prefix}/{lookup}{trailing_slash}$', mapping={ 'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy' }, name='{basename}-detail', initkwargs={'suffix': 'Instance'}), routers.DynamicDetailRoute( url=r'^{prefix}/{lookup}/{methodnamehyphen}$', name='{basename}-{methodnamehyphen}', initkwargs={}), # Dynamically generated routes. # Generated using @action or @link decorators on methods of the # viewset. routers.Route(url=r'^{prefix}/{lookup}/{methodname}{trailing_slash}$', mapping={ '{httpmethod}': '{methodname}', }, name='{basename}-{methodnamehyphen}', initkwargs={}), ] def __init__(self, trailing_slash=False): self.trailing_slash = trailing_slash and '/' or '' super(routers.DefaultRouter, self).__init__(trailing_slash=False)
class ManyEnabledRouter(routers.DefaultRouter): routes = routers.DefaultRouter.routes routes[0] = routers.Route(url=r'^{prefix}{trailing_slash}$', mapping={ 'get': 'list', 'post': 'create', 'patch': 'update_add_delete_many', }, name='{basename}-list', initkwargs={'suffix': 'List'})
def get_lookup_routes(self, viewset): ret = [self.routes[0]] # Determine any `@action` or `@link` decorated methods on the viewset dynamic_routes = [] for methodname in dir(viewset): attr = getattr(viewset, methodname) httpmethods = getattr(attr, 'bind_to_methods', None) if httpmethods: httpmethods = [method.lower() for method in httpmethods] dynamic_routes.append((httpmethods, methodname)) for route in self.lookups_routes: if route.mapping == {'{httpmethod}': '{methodname}'}: # Dynamic routes (@link or @action decorator) for httpmethods, methodname in dynamic_routes: initkwargs = route.initkwargs.copy() initkwargs.update(getattr(viewset, methodname).kwargs) mapping = dict( (httpmethod, methodname) for httpmethod in httpmethods) name = routers.replace_methodname(route.name, methodname) if 'extra_lookup_fields' in initkwargs: uri = route.url[1] uri = routers.replace_methodname(uri, methodname) ret.append( routers.Route( url=uri, mapping=mapping, name='%s-extra' % name, initkwargs=initkwargs, )) uri = routers.replace_methodname(route.url[0], methodname) ret.append( routers.Route( url=uri, mapping=mapping, name=name, initkwargs=initkwargs, )) else: # Standard route ret.append(route) return ret
class APIViewRouter(routers.DefaultRouter): routes = [ routers.Route( url=r'^{prefix}{trailing_slash}$', mapping={ 'get': 'list', 'put': 'update', 'patch': 'partial_update', }, name='{basename}-list', detail=False, initkwargs={}, ), ] def get_routes(self, viewset): return self.routes def get_urls(self): ret = [] for prefix, viewset, basename in self.registry: lookup = self.get_lookup_regex(viewset) routes = self.get_routes(viewset) print(viewset) for route in routes: # Only actions which actually exist on the viewset will be bound mapping = self.get_method_map(viewset, route.mapping) if not mapping: continue # Build the url pattern regex = route.url.format(prefix=prefix, lookup=lookup, trailing_slash=self.trailing_slash) # If there is no prefix, the first part of the url is probably # controlled by 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 prefix and regex[:2] == '^/': regex = '^' + regex[2:] initkwargs = route.initkwargs.copy() # exclude mapping if not a Viewset (aka APIView) if issubclass(viewset, viewsets.ViewSetMixin): view = viewset.as_view(mapping, **initkwargs) else: view = viewset.as_view(**initkwargs) name = route.name.format(basename=basename) ret.append(url(regex, view, name=name)) return ret
def make_routes(template_text): return routers.Route( url=r'^{prefix}/{%s}{trailing_slash}$' % template_text, mapping={ 'get': 'list', 'post': 'create', 'patch': 'bulk_validation_status', 'delete': 'bulk_delete' }, name='{basename}-list', detail=False, initkwargs={'suffix': 'List'})
class OrdersRouter(routers.SimpleRouter): routes = [ routers.DynamicRoute(url=r'^{prefix}/{url_path}$', name='{basename}-{url_name}', detail=True, initkwargs={}), routers.Route(url=r'^{prefix}$', mapping={'post': 'create'}, name='{basename}-detail', detail=True, initkwargs={'suffix': 'Detail'}) ]
class CurrentUserRouter(routers.SimpleRouter): routes = [ routers.Route( url=r"^{prefix}$", mapping={"get": "retrieve", "put": "update", "patch": "partial_update", "delete": "destroy"}, name="{basename}-detail", detail=True, initkwargs={"suffix": "Detail"}, ), routers.DynamicRoute( url=r"^{prefix}/{url_path}$", name="{basename}-{url_name}", detail=True, initkwargs={} ), ]