14

私は現在、MongoEngine の「オブジェクト ドキュメント マッパー」の可能性を探っています。現時点ではっきりしていないのは、検証とオブジェクト作成のロジックを Document オブジェクト自体にどの程度移行できるかということです。

私はそれが問題ではないという印象を持っていますが、問題に関する多くの例/警告/ベストプラクティスを見つけていません.

  • フィールドの内容が有効かどうかを評価するために、save() で自動的に呼び出されるカスタム検証関数。
  • フィールドの内容のハッシュに基づく、save() での識別子の自動生成。

カスタム ロジックを呼び出せるように、save() メソッドをオーバーライドする必要があると思いますが、例が不足しているため、それは間違ったアプローチである可能性があります...

例や、mongoEngine を使用した高品質のコードベースへの参照は大歓迎です。

4

3 に答える 3

25

モデルにメソッドを実装するclean()ことにより、カスタム検証を実行する必要があります。

class Essay(Document):
    status = StringField(choices=('Published', 'Draft'), required=True)
    pub_date = DateTimeField()

    def clean(self):
        """
        Ensures that only published essays have a `pub_date` and
        automatically sets the pub_date if published and not set.
        """
        if self.status == 'Draft' and self.pub_date is not None:
            msg = 'Draft entries should not have a publication date.'
            raise ValidationError(msg)

        # Set the pub_date for published items if not set.
        if self.status == 'Published' and self.pub_date is None:
            self.pub_date = datetime.now()

編集:とはいえ、モデル定義で設定されたルールに基づいてモデルを検証する前に、clean()呼び出されたときに注意する必要があります。validate()

于 2013-09-13T16:15:42.723 に答える
15

をオーバーライドできますがsave()、親クラスのメソッドを呼び出さなければならないという通常の警告があります。

すべてのモデルに検証フックを追加したい場合は、次のDocumentようなカスタムの子クラスを作成することを検討してください。

class MyDocument(mongoengine.Document):

    def save(self, *args, **kwargs):
        for hook in self._pre_save_hooks:
            # the callable can raise an exception if
            # it determines that it is inappropriate
            # to save this instance; or it can modify
            # the instance before it is saved
            hook(self):

        super(MyDocument, self).save(*args, **kwargs)

次に、かなり自然な方法で、特定のモデル クラスのフックを定義できます。

class SomeModel(MyDocument):
    # fields...

    _pre_save_hooks = [
        some_callable,
        another_callable
    ]
于 2011-07-06T20:06:59.487 に答える
7

Document の validate メソッドをオーバーライドすることもできますが、エラーを追加できるように、スーパークラスの Document エラーを飲み込む必要があります。

残念ながら、これは MongoEngine の内部実装の詳細に依存しているため、将来的に機能しなくなるかどうかは誰にもわかりません。

class MyDoc(Document):
    def validate(self):
        errors = {}
        try:
            super(MyDoc, self).validate()
        except ValidationError as e:
            errors = e.errors

        # Your custom validation here...
        # Unfortunately this might swallow any other errors on 'myfield'
        if self.something_is_wrong():
            errors['myfield'] = ValidationError("this field is wrong!", field_name='myfield')

        if errors:
            raise ValidationError('ValidationError', errors=errors)

また、MongoEngine では、他の種類のフック (質問で言及した識別子の生成など) を処理するための適切なシグナル サポートが提供されています。

http://mongoengine.readthedocs.io/en/latest/guide/signals.html

于 2012-08-22T22:27:37.280 に答える