2012-05-23 18 views
28

私はトルネードで遊んできましたが、とてもうまく見えないコードを書いています。トルネードのURLクエリパラメータ

例としてレシピを保存するアプリを作成しています。これらは私のハンドラです:

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 /なしでこれらのURLにアプローチするより良い方法はありますか?/recipesと/ recipes /は同じものを表示したいのに対し、/ recipes?name = somethingは検索を行い、理想的には別のハンドラにするのが好きです。

答えて

35

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パターンは、より多くのパラメータを含めるように拡張するん... /レシピ成分=鶏&スタイル=インド - ?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 
+2

1を参照してください。しかし、このURLパターンは、私がこのような検索をしたい場合、もっと多くのパラメータを含めるように拡張されていますか?/ recipes?ingredients = chicken&style = indian – colinjwebb

28

get_argumentあなたはデフォルト値を提供することができます:

details=self.get_argument("details", None, True) 

それが提供されている場合、引数はトルネードもget_arguments機能を持ってい

8

が提供されていない場合は、例外が発生しません。与えられた名前の引数のリストを返します。存在しない場合、空のリスト([])を返します。私はそれがtry..catchブロックの代わりにあなたのWebサービスの入力を浄化するためにこの方法をきれいに見つけました。

サンプル:
は、私は、次の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

あなたがすべて渡されたURLパラメータ/引数を取得することができます(代わりにハードコーディングされたURLの)フィルタリングのためのより動的なアプローチを使用したい場合要求ハンドラ内でself.request.argumentsを使用します。

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

+0

良いヒント。 Unicode文字列に関する1つの発言。ドキュメントには、名前はstr型であり、引数はバイト文字列であると書かれています。これは、引数値をUnicode文字列として返すRequestHandler.get_argumentとは異なります。 – klaas

関連する問題