カスタムIDフィールドの処理

単一の文書エンドポイントについては、ほとんどの場合、親リソースエンドポイントを定義する以外に何もする必要はありません。そこであなたが配置したとしましょう /invoices エンドポイントは、クライアントがベースを問い合わせることができます invoices データベース集合。♪the /invoices/<ObjectId> フレームワークはエンドポイントを提供し、クライアントはそのエンドポイントを使用して単一の文書を検索および/または編集する。デフォルトでは、イヴは以下の場合、この機能をシームレスに提供します。 ID_FIELD フィールドは ObjectId タイプです。

しかし、あなたはそのようなセットを持っているかもしれません。あなたの一意の識別子はそうではありません ObjectId そして、あなたはまだ各文書の最終ノードが正常に動作することを望んでいます。心配しないでください。これは可能です。少し修理しなければなりません。

荷役をする. UUID

このチュートリアルでは、データベースセット(伝票)のうちの1つが一意識別子としてUUIDフィールドを使用するシーンを考慮する。我々のAPIは,以下に示す文書サイトを公開してほしい. /invoices/uuid これは似たようなものです

/invoices/48c00ee9-4dbe-413f-9fc3-d5f12a91de1c それがそうです。

次は私たちが従わなければならない手順です

  1. UUID系列を文字列に変換できるカスタムJSONEncodeをカスタマイズし,それを我々のEVEアプリケーションに渡す.

  2. 新しいのを追加する uuid データタイプは,入力されたUID値を正確に検証できるようにする.

  3. EveがUUID URLを正しく解析する方法を知っているように,我々の伝票サイトを構成する.

カスタムJSONエンコーダ

EveデフォルトJSONシーケンス化プログラムは、一般的なデータタイプを完全に直列化することができる datetime (RFC 1123文字列にシーケンス化されている、例えば Sat, 23 Feb 1985 12:00:00 GMT )と ObjectId 値(文字列にも列化する).

未知データ型の支援を加えるため,我々のEve事例がどのように正しく直列化されるかを指導する必要がある.これは標準的なサブクラスを分けるように簡単です JSONEncoder あるいはもっと良いのはイブ自身の BaseJSONEncoder したがって、私たちのカスタムシーケンス化プログラムは、イヴのすべての直列化された魔力を保持します。

from eve.io.base import BaseJSONEncoder
from uuid import UUID

class UUIDEncoder(BaseJSONEncoder):
    """ JSONEconder subclass used by the json render function.
    This is different from BaseJSONEoncoder since it also addresses
    encoding of UUID
    """

    def default(self, obj):
        if isinstance(obj, UUID):
            return str(obj)
        else:
            # delegate rendering to base class method (the base class
            # will properly render ObjectIds, datetimes, etc.)
            return super(UUIDEncoder, self).default(obj)

UUID 検証

デフォルトの場合、イヴは、新たに挿入された文書毎に一意の識別子、すなわち ObjectId タイプです。これは私たちがこのサイトで起こることを望んでいることではない。ここでは、クライアント自身が一意の識別子を提供し、それらがUUIDタイプであるかどうかを検証することも望ましい。これを実現するためには、まず私たちのデータ検証層を拡張する必要があります(参照 データ検証 カスタム検証の詳細について):

from eve.io.mongo import Validator
from uuid import UUID

class UUIDValidator(Validator):
    """
    Extends the base mongo validator adding support for the uuid data-type
    """
    def _validate_type_uuid(self, value):
        try:
            UUID(value)
            return True
        except ValueError:
            pass

UUID URLs

現在、EveはUID値を提示して検証することができるが、どのリソースがこれらの特性を使用するかはまだ分からない。また設定する必要があります item_url したがって,UUIDフォーマットのURLを正確に解析することができる.私たちのを選びましょう settings.py モジュール、それに応じてインタフェースドメイン名を更新します:

invoices = {
    # this resource item endpoint (/invoices/<id>) will match a UUID regex.
    'item_url': 'regex("[a-f0-9]{8}-?[a-f0-9]{4}-?4[a-f0-9]{3}-?[89ab][a-f0-9]{3}-?[a-f0-9]{12}")',
    'schema': {
        # set our _id field of our custom uuid type.
        '_id': {'type': 'uuid'},
    },
}

DOMAIN = {
    'invoices': invoices
}

すべてのAPIリソースが一意の文書識別子としてUUIDをサポートする場合、グローバルを設定するだけでよい場合があります。 ITEM_URL これを単一のリソースエンドポイントごとに設定しないようにUUID正規表現として設定する.

手渡す UUID 前夜までジュースを送る

今は失われたすべての破片がそこにあります。私たちはただイブにそれらの使い方を教えなければなりません。イヴはURLマッピングを構築する際に新たなデータタイプを知る必要があるため,アプリケーションをインスタンス化する際には,開始時にカスタマイズクラスを渡す必要がある:

app = Eve(json_encoder=UUIDEncoder, validator=UUIDValidator)

覚えておいてくださいカスタマイズされたものを使っていれば ID_FIELD 値は、MongoDB(およびEve)に依存して自動生成されるべきではありません ID_FIELD あなたにあげました。あなたは次のようにこの値を渡すべきです。

POST
{"name":"bill", "_id":"48c00ee9-4dbe-413f-9fc3-d5f12a91de1c"}

注釈

デフォルトの場合、イヴはPyMongoの UuidRepresentation 至る standard それは.これにより、Pythonによって生成された現代のUID値をシームレスに処理することができます。設定することで uuidRepresentation の価値 MONGO_OPTIONS あなたの望み通りです。詳細についてはご参照ください PyMongo documentation それがそうです。