龙卷风URL查询参数

col*_*ebb 36 python tornado

我一直在玩Tornado,我写了一些看起来不太好的代码.

我正在编写一个应用程序来存储食谱作为示例.这些是我的处理程序:

handlers = [
    (r"/recipes/", RecipeHandler),
    (r"/recipes", RecipeSearchHandler), #so query params can be used to search
]
Run Code Online (Sandbox Code Playgroud)

这导致我写这个:

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/
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来处理这些URL没有尝试/除外?我喜欢/食谱和/食谱/显示相同的东西,而/食谱?名称=某些东西会进行搜索,理想情况下是一个不同的处理程序.

mfu*_*ger 44

GET请求有更好的方法.有一个在github上龙卷风源的演示在这里

# 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)
Run Code Online (Sandbox Code Playgroud)

与正则表达式匹配的任何"文本"将作为slug参数传递给EntryHandler的get方法.如果url与任何处理程序都不匹配,则用户将收到404错误.

如果您想提供另一个后备,可以将参数设置为可选

(r"/entry/([^/]*)", EntryHandler),

class EntryHandler(BaseHandler):
    def get(self, slug=None):
        pass
Run Code Online (Sandbox Code Playgroud)

更新:

+1链接.但是,如果我想像这样搜索,这个URL模式扩展到包含更多参数.../recipes?ingredient = chicken&style = indian - 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
Run Code Online (Sandbox Code Playgroud)

  • +1链接.但是,如果我想像这样搜索这个URL模式,那么它会扩展为包含更多参数.../recipes?ingredient = chicken&style = indian (3认同)

Cas*_*ash 36

get_argument 允许您提供默认值:

details=self.get_argument("details", None, True)
Run Code Online (Sandbox Code Playgroud)

如果提供了,则如果未提供参数,则不会发生异常


Ara*_*ndh 11

龙卷风也有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")})
Run Code Online (Sandbox Code Playgroud)


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"}
Run Code Online (Sandbox Code Playgroud)


frm*_*ryr 6

如果您想使用更动态的过滤方法(而不是硬编码的 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...
Run Code Online (Sandbox Code Playgroud)

http://www.tornadoweb.org/en/stable/httputil.html#tornado.httputil.HTTPServerRequest.arguments