我一直在玩Tornado,我写了一些看起来不太好的代码。
我正在编写一个用于存储食谱的应用程序作为示例。这些是我的处理程序:
handlers = [
(r"/recipes/", RecipeHandler),
(r"/recipes", RecipeSearchHandler), #so query params can be used to search
]
这引导我写下这个:
class RecipeHandler(RequestHandler):
def get(self):
self.render('recipes/index.html')
class RecipeSearchHandler(RequestHandler):
def get(self):
try:
name = self.get_argument('name', True)
self.write(name)
# will do some searching
except AssertionError:
self.write("no params")
# will probably redirect to /recipes/
有没有更好的方法来处理这些网址而不尝试/除外?我喜欢/食谱和/食谱/显示相同的东西,而/食谱?名称=某些东西会进行搜索,理想情况下是一个不同的处理程序。
答案 0 :(得分:43)
有一种更好的GET请求方式。在github here
上的龙卷风源中有一个演示# url handler
handlers = [(r"/entry/([^/]+)", EntryHandler),]
class EntryHandler(BaseHandler):
def get(self, slug):
entry = self.db.get("SELECT * FROM entries WHERE slug = %s", slug)
if not entry: raise tornado.web.HTTPError(404)
self.render("entry.html", entry=entry)
与正则表达式匹配的任何“text”将作为slug参数传递给EntryHandler的get方法。如果url与任何处理程序都不匹配,则用户将收到404错误。
如果您想提供另一个后备,可以将参数设为可选
(r"/entry/([^/]*)", EntryHandler),
class EntryHandler(BaseHandler):
def get(self, slug=None):
pass
<强>更新强>
+1链接。但是,如果我想像这样搜索,这个URL模式会扩展为包含更多参数... /食谱?成分=鸡肉&amp; style =印度 - colinjameswebb
是的。
handlers = [
(r'/(\d{4})/(\d{2})/(\d{2})/([a-zA-Z\-0-9\.:,_]+)/?', DetailHandler)
]
class DetailHandler(BaseHandler):
def get(self, year, month, day, slug):
pass
答案 1 :(得分:36)
get_argument
允许您提供默认值:
details=self.get_argument("details", None, True)
如果提供了,那么如果没有提供参数,则不会发生异常
答案 2 :(得分:10)
龙卷风也有get_arguments
功能。它返回具有给定名称的参数列表。如果不存在,则返回空列表( []
)。我发现它更清洁,以清理您的Web服务输入而不是try..catch
块。
样品:
假设我有一个以下的URL处理程序:
(r"/recipe",GetRecipe)
和请求处理程序:
class GetRecipe(RequestHandler):
def get(self):
recipe_id = self.get_arguments("rid")
if recipe_id == []:
# Handle me
self.set_status(400)
return self.finish("Invalid recipe id")
self.write({"recipe_id":self.get_argument("rid")})
recipe_id
列表也会保留值,但我发现self.get_argument
使用方便了这种方式。
现在结果如下:
curl "http://localhost:8890/recipe" -v
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8890 (#0)
> GET /recipe HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:8890
> Accept: */*
>
< HTTP/1.1 400 Bad Request
< Content-Length: 17
< Content-Type: text/html; charset=UTF-8
* Server TornadoServer/1.1.1 is not blacklisted
< Server: TornadoServer/1.1.1
<
* Connection #0 to host localhost left intact
Invalid recipe id
curl "http://localhost:8890/recipe?rid=230" -v
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8890 (#0)
> GET /recipe?rid=230 HTTP/1.1
> User-Agent: curl/7.35.0
> Host: localhost:8890
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Length: 20
< Etag: "d69ecb9086a20160178ade6b13eb0b3959aa13c6"
< Content-Type: text/javascript; charset=UTF-8
* Server TornadoServer/1.1.1 is not blacklisted
< Server: TornadoServer/1.1.1
<
* Connection #0 to host localhost left intact
{"recipe_id": "230"}
答案 3 :(得分:3)
如果您想使用更动态的方法进行过滤(而不是使用硬编码的URL),您可以在请求处理程序中使用self.request.arguments
获取所有传递的URL参数/参数。
class ApiHandler(RequestHandler):
def get(self, path):
filters = self.request.arguments
for k,v in filters.items():
# Do filtering etc...
请参阅http://www.tornadoweb.org/en/stable/httputil.html#tornado.httputil.HTTPServerRequest.arguments