use name to define route name for different methods on same url
This commit is contained in:
parent
eab809d410
commit
762b2782ee
|
@ -266,4 +266,38 @@ app.blueprint(bp)
|
|||
|
||||
# then you need use `app.url_for('test_named_bp.get_handler')`
|
||||
# instead of `app.url_for('test_named_bp.handler')`
|
||||
|
||||
# different names can be used for same url with different methods
|
||||
|
||||
@app.get('/test', name='route_test')
|
||||
def handler(request):
|
||||
return text('OK')
|
||||
|
||||
@app.post('/test', name='route_post')
|
||||
def handler2(request):
|
||||
return text('OK POST')
|
||||
|
||||
@app.put('/test', name='route_put')
|
||||
def handler3(request):
|
||||
return text('OK PUT')
|
||||
|
||||
# below url are the same, you can use any of them
|
||||
# '/test'
|
||||
app.url_for('route_test')
|
||||
# app.url_for('route_post')
|
||||
# app.url_for('route_put')
|
||||
|
||||
# for same handler name with different methods
|
||||
# you need specify the name (it's url_for issue)
|
||||
@app.get('/get')
|
||||
def handler(request):
|
||||
return text('OK')
|
||||
|
||||
@app.post('/post', name='post_handler')
|
||||
def handler(request):
|
||||
return text('OK')
|
||||
|
||||
# then
|
||||
# app.url_for('handler') == '/get'
|
||||
# app.url_for('post_handler') == '/post'
|
||||
```
|
||||
|
|
|
@ -67,6 +67,7 @@ class Router:
|
|||
|
||||
def __init__(self):
|
||||
self.routes_all = {}
|
||||
self.routes_names = {}
|
||||
self.routes_static = {}
|
||||
self.routes_dynamic = defaultdict(list)
|
||||
self.routes_always_check = []
|
||||
|
@ -125,13 +126,12 @@ class Router:
|
|||
|
||||
# Add versions with and without trailing /
|
||||
slash_is_missing = (
|
||||
not uri[-1] == '/'
|
||||
and not self.routes_all.get(uri + '/', False)
|
||||
not uri[-1] == '/' and not self.routes_all.get(uri + '/', False)
|
||||
)
|
||||
without_slash_is_missing = (
|
||||
uri[-1] == '/'
|
||||
and not self.routes_all.get(uri[:-1], False)
|
||||
and not uri == '/'
|
||||
uri[-1] == '/' and not
|
||||
self.routes_all.get(uri[:-1], False) and not
|
||||
uri == '/'
|
||||
)
|
||||
# add version with trailing slash
|
||||
if slash_is_missing:
|
||||
|
@ -229,9 +229,6 @@ class Router:
|
|||
else:
|
||||
route = self.routes_all.get(uri)
|
||||
|
||||
if route:
|
||||
route = merge_route(route, methods, handler)
|
||||
else:
|
||||
# prefix the handler name with the blueprint name
|
||||
# if available
|
||||
if hasattr(handler, '__blueprintname__'):
|
||||
|
@ -240,11 +237,18 @@ class Router:
|
|||
else:
|
||||
handler_name = name or getattr(handler, '__name__', None)
|
||||
|
||||
if route:
|
||||
route = merge_route(route, methods, handler)
|
||||
else:
|
||||
route = Route(
|
||||
handler=handler, methods=methods, pattern=pattern,
|
||||
parameters=parameters, name=handler_name, uri=uri)
|
||||
|
||||
self.routes_all[uri] = route
|
||||
pairs = self.routes_names.get(handler_name)
|
||||
if not (pairs and (pairs[0] + '/' == uri or uri + '/' == pairs[0])):
|
||||
self.routes_names[handler_name] = (uri, route)
|
||||
|
||||
if properties['unhashable']:
|
||||
self.routes_always_check.append(route)
|
||||
elif parameters:
|
||||
|
@ -265,6 +269,11 @@ class Router:
|
|||
uri = host + uri
|
||||
try:
|
||||
route = self.routes_all.pop(uri)
|
||||
for handler_name, pairs in self.routes_names.items():
|
||||
if pairs[0] == uri:
|
||||
self.routes_names.pop(handler_name)
|
||||
break
|
||||
|
||||
except KeyError:
|
||||
raise RouteDoesNotExist("Route was not registered: {}".format(uri))
|
||||
|
||||
|
@ -289,11 +298,7 @@ class Router:
|
|||
if not view_name:
|
||||
return (None, None)
|
||||
|
||||
for uri, route in self.routes_all.items():
|
||||
if route.name == view_name:
|
||||
return uri, route
|
||||
|
||||
return (None, None)
|
||||
return self.routes_names.get(view_name, (None, None))
|
||||
|
||||
def get(self, request):
|
||||
"""Get a request handler based on the URL of the request, or raises an
|
||||
|
|
|
@ -7,7 +7,6 @@ import pytest
|
|||
from sanic import Sanic
|
||||
from sanic.blueprints import Blueprint
|
||||
from sanic.response import text
|
||||
from sanic.router import RouteExists, RouteDoesNotExist
|
||||
from sanic.exceptions import URLBuildError
|
||||
from sanic.constants import HTTP_METHODS
|
||||
|
||||
|
@ -360,11 +359,7 @@ def test_overload_routes():
|
|||
return text('OK1')
|
||||
|
||||
@app.route('/overload', methods=['POST', 'PUT'], name='route_second')
|
||||
async def handler2(request):
|
||||
return text('OK2')
|
||||
|
||||
@app.route('/overload2', methods=['POST', 'PUT'], name='route_third')
|
||||
async def handler3(request):
|
||||
async def handler1(request):
|
||||
return text('OK2')
|
||||
|
||||
request, response = app.test_client.get(app.url_for('route_first'))
|
||||
|
@ -376,16 +371,18 @@ def test_overload_routes():
|
|||
request, response = app.test_client.put(app.url_for('route_first'))
|
||||
assert response.text == 'OK2'
|
||||
|
||||
request, response = app.test_client.get(app.url_for('route_second'))
|
||||
assert response.text == 'OK1'
|
||||
|
||||
request, response = app.test_client.post(app.url_for('route_second'))
|
||||
assert response.text == 'OK2'
|
||||
|
||||
request, response = app.test_client.put(app.url_for('route_second'))
|
||||
assert response.text == 'OK2'
|
||||
|
||||
assert app.router.routes_all['/overload'].name == 'route_first'
|
||||
with pytest.raises(URLBuildError):
|
||||
app.url_for('handler1')
|
||||
|
||||
with pytest.raises(URLBuildError):
|
||||
app.url_for('handler2')
|
||||
|
||||
with pytest.raises(URLBuildError):
|
||||
app.url_for('route_second')
|
||||
|
||||
assert app.url_for('route_third') == '/overload2'
|
||||
with pytest.raises(URLBuildError):
|
||||
app.url_for('handler3')
|
||||
assert app.url_for('route_first') == '/overload'
|
||||
assert app.url_for('route_second') == app.url_for('route_first')
|
||||
|
|
Loading…
Reference in New Issue
Block a user