簡體   English   中英

如何在驗證器 function 中獲取 model pydantic 的 json

[英]How to get json of model pydantic in validator function

想象一下,我有像這樣的 pydantic 的 Model:

 class Input(BaseModel): field1: ObjectIdField =... field2: str =... field3: int =... field4: str =... @validator('field4') def validate_field4(cls, v, values, **kwargs): # print(values) => {'field1': ObjectId('63185d5c721c6ef40eb2462a'), 'field2': 'deleted', 'field3': 1} # I want to check this # if json.dumps(values) == v: # OK # else: # raise Exception return v class Config: json_encoders = { ObjectId: lambda v: str(v), }

如您所見,我想獲得 model 的 json 除了一個字段(字段4)。 有沒有很好的解決方案來處理 model 的內部驗證器?

評論未能解決的是 Pydantics .json是一個實例方法(就像.dict方法一樣),因此在驗證器中完全沒用,驗證器始終是在實例初始化之前調用的class方法。

(注意:您沒有提供有關您的ObjectIdField class 如何工作的代碼或解釋,因此我不得不猜測並實現一個非常簡單的 class 來嘗試模擬您顯示的行為。)

這是完成驗證的一種方法:

import json
from typing import Any

from pydantic import BaseModel, validator


class ObjectIdField:
    def __init__(self, value: str) -> None:
        self.value = value

    def __repr__(self) -> str:
        return f"ObjectId('{self.value}')"

    def __str__(self) -> str:
        return self.value


def encode_obj_id(obj_id: ObjectIdField) -> str:
    return str(obj_id)


def json_encode(obj: Any) -> str:
    return json.dumps(obj, default=encode_obj_id)


class Input(BaseModel):
    field1: ObjectIdField = ...
    field2: str = ...
    field3: int = ...
    field4: str = ...

    @validator('field4')
    def validate_field4(cls, v: str, values: dict[str, Any]) -> str:
        serialized = json_encode(values)
        assert v == serialized
        return v

    class Config:
        arbitrary_types_allowed = True  # to allow `ObjectIdField`
        json_encoders = {
            ObjectIdField: encode_obj_id,
        }


if __name__ == '__main__':
    data = dict(
        field1=ObjectIdField("abc"),
        field2="foo",
        field3=123,
    )
    data_json = json_encode(data)
    instance = Input(**data, field4=data_json)
    assert data_json == instance.json(exclude={"field4"})

    # instance = Input(**data, field4="invalid")  # this fails validation

json.dumps function 有一個default參數,它采用 function

對於無法以其他方式序列化的對象,會調用它。

我們可以使用它來構造我們自己的小助手 function json_encode ,它使用encode_obj_id function 序列化ObjectIdField類型。

由於field4不存在於傳遞給該字段的驗證器 function 的values字典中,我們可以簡單地在該字典上調用我們的json_encode function 並將其與field4v進行比較。

注意:這僅適用於字段 4 在field4上最后定義的情況,因為字段按照定義的順序進行驗證。 如果您在field4上的 field4之后有另一個字段,則在調用驗證器時其值將從values字典中丟失。

希望這可以幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM