Say I have model
class UserDB(BaseModel):
first_name: Optional[str] = None
last_name: Optional[str] = None
How do I make another model that is constructed from this one and has a field that changes based on the fields in this model?
For instance, something like this
class User(BaseModel):
full_name: str = first_name + ' ' + last_name
Constructed like this maybe
User.parse_obj(UserDB)
Thanks!
Pydantic is a useful library for data parsing and validation. It coerces input types to the declared type (using type hints), accumulates all the errors using ValidationError & it's also well documented making it easily discoverable.
ORM Mode (aka Arbitrary Class Instances) Pydantic models can be created from arbitrary class instances to support models that map to ORM objects. To do this: The Config property orm_mode must be set to True . The special constructor from_orm must be used to create the model instance.
constr is a specific type that give validation rules regarding this specific type. You have equivalent for all classic python types.
pydantic allows custom data types to be defined or you can extend validation with methods on a model decorated with the validator decorator. dataclasses integration. As well as BaseModel , pydantic provides a dataclass decorator which creates (almost) vanilla Python dataclasses with input data parsing and validation.
If you do not want to keep first_name
and last_name
in User
then you can
__init__
.full_name
.Both methods do what you want:
from typing import Optional
from pydantic import BaseModel, validator
class UserDB(BaseModel):
first_name: Optional[str] = None
last_name: Optional[str] = None
class User_1(BaseModel):
location: str # for a change
full_name: Optional[str] = None
def __init__(self, user_db: UserDB, **data):
super().__init__(full_name=f"{user_db.first_name} {user_db.last_name}", **data)
user_db = UserDB(first_name="John", last_name="Stark")
user = User_1(user_db, location="Mars")
print(user)
class User_2(BaseModel):
first_name: Optional[str] = None
last_name: Optional[str] = None
full_name: Optional[str] = None
@validator('full_name', always=True)
def ab(cls, v, values) -> str:
return f"{values['first_name']} {values['last_name']}"
user = User_2(**user_db.dict())
print(user)
output
location='Mars' full_name='John Stark'
first_name='John' last_name='Stark' full_name='John Stark'
UPDATE:
For working with response_model
you can customize __init__
in such way:
class User_1(BaseModel):
location: str # for a change
full_name: Optional[str] = None
# def __init__(self, user_db: UserDB, **data):
def __init__(self, first_name, last_name, **data):
super().__init__(full_name=f"{first_name} {last_name}", **data)
user_db = UserDB(first_name="John", last_name="Stark")
user = User_1(**user_db.dict(), location="Mars")
print(user)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With