0

これはよく出てくるもののようですが、それに関するドキュメントは見つかりません。

私はAPIを書いていて、URLを次のようにしたい:

'/api/v1.0/restaurant/Name&Address'

Flask-restful を使用して、URL を次のように定義しました。

'/api/v1.0/restaurant/<name>&<address>'

ただし、Werkzeug はこれを好まず、werkzeug/routing.py で BuildError を発生させます。

add_resource を使用して URL を次のように定義すると、

'/api/v1.0/restaurant/<name>'

アドレスを配線すると、すべて正常に動作します。

2 つの変数を取るように URL を定義するにはどうすればよいですか?

編集

Traceback (most recent call last):
  File "/home/ubuntu/.virtualenvs/data/local/lib/python2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
    rv = self.dispatch_request()
  File "/home/ubuntu/.virtualenvs/data/local/lib/python2.7/site-packages/flask/app.py", line 1461, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "/home/ubuntu/.virtualenvs/data/local/lib/python2.7/site-packages/flask_restful/__init__.py", line 397, in wrapper
    resp = resource(*args, **kwargs)
  File "/home/ubuntu/.virtualenvs/data/local/lib/python2.7/site-packages/flask/views.py", line 84, in view
    return self.dispatch_request(*args, **kwargs)
  File "/home/ubuntu/.virtualenvs/data/local/lib/python2.7/site-packages/flask_restful/__init__.py", line 487, in dispatch_request
    resp = meth(*args, **kwargs)
  File "/home/ubuntu/Hotsauce/api/app/views.py", line 75, in get
    resto = {'restaurant': marshal(restaurant, resto_fields)}
  File "/home/ubuntu/.virtualenvs/data/local/lib/python2.7/site-packages/flask_restful/__init__.py", line 533, in marshal
    return OrderedDict(items)
  File "/usr/lib/python2.7/collections.py", line 52, in __init__
    self.__update(*args, **kwds)
  File "/home/ubuntu/.virtualenvs/data/lib/python2.7/_abcoll.py", line 547, in update
    for key, value in other:
  File "/home/ubuntu/.virtualenvs/data/local/lib/python2.7/site-packages/flask_restful/__init__.py", line 532, in <genexpr>
    for k, v in fields.items())
  File "/home/ubuntu/.virtualenvs/data/local/lib/python2.7/site-packages/flask_restful/fields.py", line 232, in output
    o = urlparse(url_for(self.endpoint, _external = self.absolute, **data))
  File "/home/ubuntu/.virtualenvs/data/local/lib/python2.7/site-packages/flask/helpers.py", line 312, in url_for
    return appctx.app.handle_url_build_error(error, endpoint, values)
  File "/home/ubuntu/.virtualenvs/data/local/lib/python2.7/site-packages/flask/app.py", line 1641, in handle_url_build_error
    reraise(exc_type, exc_value, tb)
  File "/home/ubuntu/.virtualenvs/data/local/lib/python2.7/site-packages/flask/helpers.py", line 305, in url_for
    force_external=external)
  File "/home/ubuntu/.virtualenvs/data/local/lib/python2.7/site-packages/werkzeug/routing.py", line 1620, in build
    raise BuildError(endpoint, values, method)
BuildError: ('restaurant', {u'city_id': 2468, u’score’: Decimal('0E-10'), 'id': 37247, u'nbhd_id': 6596, u'address_region': u'NY', u'phone_number': u'(718) 858-6700', '_sa_instance_state': <sqlalchemy.orm.state.InstanceState object at 0x26f33d0>, u'complete': False, u'name': u'Asya', u'address_locality': u'New York', u'address_updated': True, u'street_address': u'46 Henry St'}, None)

エラーを生成する関連コードは次のとおりです。

resto_fields = {
    'id': fields.Integer,
    'name': fields.String,
    'street_address': fields.String,
    'address_locality': fields.String,
    'address_region': fields.String,
    ‘score’: fields.Float,
    'phone_number': fields.String,
    'uri': fields.Url('restaurant')
    }

def get(self, name, address):
    restaurant = session.query(Restaurant).filter_by(name=name).filter_by(address=address)

    resto = {'restaurant': marshal(restaurant, resto_fields)}

    return resto
4

3 に答える 3

2

これは、&アンパサンドや複数の URL パラメーターの使用とは関係ありません。

resto_fieldsエンドポイントの出力フィールド マッピングからのエントリのみを使用できます。マッピングにエントリがありません、エンドポイントで URL を作成するために必要です。addressresto_fieldsrestaurant

address出力フィールドにフィールドを追加する、ルート内の既存のフィールドの 1 つを使用します。

于 2014-03-24T21:55:18.747 に答える
1

これは理想的ではありませんが、うまく機能します。

この問題は、resto_fields を使用したマーシャリング中に、flask-restful がリソースの uri を作成しようとしたときに発生していました。

これは、URL が名前のみを変数として使用する場合は問題ありませんでしたが、URL に名前とアドレスが必要になると、BuildError が発生しました。

この問題を回避するには、削除しました

'uri': fields.Url('restaurant')

restos_fields から取得し、リソースをマーシャリングした後に uri を構築し、それを返す前にマーシャリングされたリソースに追加しました。

    resto = {'restaurant': marshal(restaurant, resto_fields)}

    resto['restaurant']['uri'] = '/api/v1.0/restaurant/{0}&{1}'.format(name, address)
    return resto

誰かがこの作品を作るよりエレガントな方法を持っているなら、私はそれについて聞きたいと思っています.

于 2014-03-24T21:23:13.163 に答える
0

これを理解するのにしばらく時間がかかったので、正しい答え...

@Martijnの答えは、この場合にはまったく正しくありません。

get正解:メソッドに必要な属性をデータ ディクショナリに含める必要があります(出力フィールドにはありません)。

したがって、コードは次のように機能するはずです。

resto_fields = {
    'id': fields.Integer,
    'name': fields.String,
    'street_address': fields.String,
    'address_locality': fields.String,
    'address_region': fields.String,
    ‘score’: fields.Float,
    'phone_number': fields.String,
    'uri': fields.Url('restaurant')
    }

def get(self, name, address):
    restaurant = session.query(Restaurant).filter_by(name=name).filter_by(address=address)

    # restaurant must have an 'address' field
    restaurant['address'] = ' '.join[restaurant['street_address'], restaurant['address_locality']]
    resto = {'restaurant': marshal(restaurant, resto_fields)}

    return resto

address生成された応答の一部にはなりません

于 2015-04-28T05:49:20.780 に答える