私はトルネードをいじくり回してきましたが、あまりナイスとは思えないコードをいくつか書きました。
例としてレシピを保存するアプリを書いています。これらは私のハンドラーです:
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/
Try/exceptなしでこれらのURLにアプローチするより良い方法はありますか?/recipes?name = somethingは検索を行い、理想的には異なるハンドラーであるのに対し、/ recipesと/ recipes /は同じものを表示したいです。
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)
正規表現に一致する「テキスト」は、スラグ引数としてEntryHandlerのgetメソッドに渡されます。 URLがどのハンドラとも一致しない場合、ユーザーは404エラーを受け取ります。
別のフォールバックを提供する場合は、パラメーターをオプションにすることができます
(r"/entry/([^/]*)", EntryHandler),
class EntryHandler(BaseHandler):
def get(self, slug=None):
pass
更新:
リンクの+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
get_argument
を使用すると、デフォルト値を指定できます。
details=self.get_argument("details", None, True)
指定されている場合、引数が指定されていなくても例外は発生しません
竜巻にもget_arguments
関数。指定された名前の引数のリストを返します。存在しない場合は、空のリスト([]
)。このようにすれば、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"}
(ハードコーディングされた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 を参照してください