如何根据其他字段设置 Pydantic 字段值

An *_*ea. 8 python pydantic

from pydantic import BaseModel


class Grafana(BaseModel):
    user: str
    password: str
    host: str
    port: str
    api_key: str | None = None
    GRAFANA_URL = f"http://{user}:{password}@{host}:{port}"
    API_DATASOURCES = "/api/datasources"
    API_KEYS = "/api/auth/keys"
Run Code Online (Sandbox Code Playgroud)

使用 Pydantic,我收到两个未绑定变量错误消息userpassword其中 、 等GRAFANA_URL

有办法解决这个问题吗?在常规课程中,我只会GRAFANA_URL__init__方法中创建。对于 Pydantic,我不知道如何继续。

Dan*_*erg 12

选项 A:使用@validator

有关详细信息,请参阅验证器文档。

from typing import Any

from pydantic import BaseModel, validator


class Model(BaseModel):
    foo: str
    bar: str
    foobar: str = ""

    @validator("foobar", always=True)
    def set_if_empty(cls, v: str, values: dict[str, Any]) -> str:
        if v == "":
            return values["foo"] + values["bar"]
        return v


obj = Model(foo="a", bar="b")
print(obj)  # foo='a' bar='b' foobar='ab'
Run Code Online (Sandbox Code Playgroud)

这种方式foobar仍然是常规模型领域。

请注意,要使其起作用,必须和之后foobar定义。否则你将不得不使用根验证器 foobar

选项 B:将其设为@property

from pydantic import BaseModel


class Model(BaseModel):
    foo: str
    bar: str

    @property
    def foobar(self) -> str:
        return self.foo + self.bar


obj = Model(foo="a", bar="b")
print(obj)         # foo='a' bar='b'
print(obj.foobar)  # ab
Run Code Online (Sandbox Code Playgroud)

那么foobar不再是模型字段,因此不再是架构的一部分。这可能与您相关,也可能不相关。

选项 C:将其设为@computed_field仅限 Pydantic v2!

Pydantic 2 可以定义计算域。

from pydantic import BaseModel, computed_field


class Model(BaseModel):
    foo: str
    bar: str

    @computed_field
    @property
    def foobar(self) -> str:
        return self.foo + self.bar


obj = Model(foo="a", bar="b")
print(obj)         # foo='a' bar='b' foobar='ab'
Run Code Online (Sandbox Code Playgroud)