如何使用列表中的值来验证 pydantic BaseModel 中的某些计算?
How to use values from list to validate some calculations in pydantic BaseModel?
我正在使用 Pydantic root_validator
在我的模型中执行一些计算:
class ProductLne(BaseModel):
qtt_line: float = 0.00
prix_unite: float = 0.00
so_total_ht: float = 0.00
class Config:
validate_assignment = True
@root_validator()
def calculat_so_totals(cls, values):
values["so_total_ht"] = values.get("qtt_line")*values.get("prix_unite")
return values
class Bon(BaseModel):
articles: List[ProductLne] = []
total_ht: float = 0.00
class Config:
validate_assignment = True
@root_validator()
def set_total_ht(cls, values):
for item in values.get('articles'):
values['total_ht'] += item.so_total_ht
return values
一些数据
item_line1 = ProductLne(qtt_line=10, prix_unite=10.00)
item_line2 = ProductLne(qtt_line=10, prix_unite=12.00)
bon1 = Bon()
bon1.articles.append(item_line1)
bon1.articles.append(item_line2)
当运行
print(bon1.total_ht)
我得到:0.0,O.OO
我要220
如何使这个函数 return 的值正确?
我发现了你的问题。这是因为您试图访问 cls 上不存在的数据,并且您从值访问数据的方式是错误的。首先,您必须在某些时候通过 ProductLne
和 Bon
传递数据。因此,我更改了您的代码以在初始化时设置 ProductLne
的值,然后在 Bon
初始化时在验证器中对其进行初始化。然后 运行 Bon()
我相信这就是您想要完成的。您仍然可以通过脚本传递数据,我只是不知道您的脚本是什么样的。示例(简化):
class ProductLne(BaseModel):
qtt_line: float = 1.0
so_total_ht: float = 1.0
@root_validator()
def calculat_so_totals(cls, values):
values["so_total_ht"] = values.get("qtt_line")
return values
class Bon(BaseModel):
articles: List[ProductLne] = []
total_ht: float = 0.0
@root_validator()
def set_total_ht(cls, values):
product_line = ProductLne()
values["articles"].append(product_line)
for item in values.get("articles"):
values["total_ht"] += item.qtt_line
return values
我不知道这是否是好的原因,但我得到了我想要的
from pydantic import BaseModel, root_validator, Field
from typing import List
from typing import TYPE_CHECKING, Union
if TYPE_CHECKING:
from pydantic.typing import DictStrAny
class PropertyBaseModel(BaseModel):
@classmethod
def get_properties(cls):
return [
prop for prop in dir(cls)
if isinstance(getattr(cls, prop), property) and prop not in ("__values__", "fields")
]
def dict(self, *args, **kwargs) -> 'DictStrAny':
self.__dict__.update({prop: getattr(self, prop) for prop in self.get_properties()})
return super().dict(*args, **kwargs)
class ProductLne(PropertyBaseModel):
prix: float = 0.00
qtt_line: float = 0.0
@property
def so_total_ht(self) -> float:
return self.qtt_line * self.prix
class Bon(BaseModel):
articles: List[ProductLne] = []
@property
def total_ht(self) -> float:
bla = 0.00
for item in self.articles:
bla += item.so_total_ht
return bla
item_line1 = ProductLne(prix=10.00,qtt_line=10)
item_line2 = ProductLne(prix=12.00,qtt_line=10)
print(item_line1.so_total_ht)
print(item_line2.so_total_ht)
bon1 = Bon()
bon1.articles.append(item_line1)
bon1.articles.append(item_line2)
print(bon1.total_ht) #220
我正在使用 Pydantic root_validator
在我的模型中执行一些计算:
class ProductLne(BaseModel):
qtt_line: float = 0.00
prix_unite: float = 0.00
so_total_ht: float = 0.00
class Config:
validate_assignment = True
@root_validator()
def calculat_so_totals(cls, values):
values["so_total_ht"] = values.get("qtt_line")*values.get("prix_unite")
return values
class Bon(BaseModel):
articles: List[ProductLne] = []
total_ht: float = 0.00
class Config:
validate_assignment = True
@root_validator()
def set_total_ht(cls, values):
for item in values.get('articles'):
values['total_ht'] += item.so_total_ht
return values
一些数据
item_line1 = ProductLne(qtt_line=10, prix_unite=10.00)
item_line2 = ProductLne(qtt_line=10, prix_unite=12.00)
bon1 = Bon()
bon1.articles.append(item_line1)
bon1.articles.append(item_line2)
当运行
print(bon1.total_ht)
我得到:0.0,O.OO 我要220
如何使这个函数 return 的值正确?
我发现了你的问题。这是因为您试图访问 cls 上不存在的数据,并且您从值访问数据的方式是错误的。首先,您必须在某些时候通过 ProductLne
和 Bon
传递数据。因此,我更改了您的代码以在初始化时设置 ProductLne
的值,然后在 Bon
初始化时在验证器中对其进行初始化。然后 运行 Bon()
我相信这就是您想要完成的。您仍然可以通过脚本传递数据,我只是不知道您的脚本是什么样的。示例(简化):
class ProductLne(BaseModel):
qtt_line: float = 1.0
so_total_ht: float = 1.0
@root_validator()
def calculat_so_totals(cls, values):
values["so_total_ht"] = values.get("qtt_line")
return values
class Bon(BaseModel):
articles: List[ProductLne] = []
total_ht: float = 0.0
@root_validator()
def set_total_ht(cls, values):
product_line = ProductLne()
values["articles"].append(product_line)
for item in values.get("articles"):
values["total_ht"] += item.qtt_line
return values
我不知道这是否是好的原因,但我得到了我想要的
from pydantic import BaseModel, root_validator, Field
from typing import List
from typing import TYPE_CHECKING, Union
if TYPE_CHECKING:
from pydantic.typing import DictStrAny
class PropertyBaseModel(BaseModel):
@classmethod
def get_properties(cls):
return [
prop for prop in dir(cls)
if isinstance(getattr(cls, prop), property) and prop not in ("__values__", "fields")
]
def dict(self, *args, **kwargs) -> 'DictStrAny':
self.__dict__.update({prop: getattr(self, prop) for prop in self.get_properties()})
return super().dict(*args, **kwargs)
class ProductLne(PropertyBaseModel):
prix: float = 0.00
qtt_line: float = 0.0
@property
def so_total_ht(self) -> float:
return self.qtt_line * self.prix
class Bon(BaseModel):
articles: List[ProductLne] = []
@property
def total_ht(self) -> float:
bla = 0.00
for item in self.articles:
bla += item.so_total_ht
return bla
item_line1 = ProductLne(prix=10.00,qtt_line=10)
item_line2 = ProductLne(prix=12.00,qtt_line=10)
print(item_line1.so_total_ht)
print(item_line2.so_total_ht)
bon1 = Bon()
bon1.articles.append(item_line1)
bon1.articles.append(item_line2)
print(bon1.total_ht) #220