I'm working with Tortoise ORM in a FastAPI project and have a Channel model which optionally includes a password hash when channel is protected. I want to generate a list of channels for API responses, where I exclude the password_hash field and include a new computed boolean field, protected, to indicate whether a channel is password protected.
Here's the model definition:
from tortoise import fields, models
from tortoise.contrib.pydantic import pydantic_model_creator
class Channel(models.Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=100)
password_hash = fields.CharField(max_length=128, null=True)
owner = fields.ForeignKeyField('models.User', related_name='channels')
ChannelSchema = pydantic_model_creator(Channel, name="Channel")
Current API response example:
[
{
"id": 1,
"name": "my channel",
"password_hash": null
},
{
"id": 2,
"name": "my protected channel",
"password_hash": "$2b$..."
}
]
Desired API response:
[
{
"id": 1,
"name": "my channel",
"protected": false
},
{
"id": 2,
"name": "my protected channel",
"protected": true
}
]
How can I correctly include the protected computed attribute in my Pydantic model while excluding the password_hash field?
I attempted to create a computed attribute password_protected and exclude password_hash like so:
class Channel(models.Model):
...
def password_protected(self) -> bool:
return bool(self.password_hash)
class PydanticMeta:
computed = ["password_protected"]
# exclude = ["password_hash"]
However, excluding password_hash leads to an error:
AttributeError: 'ResponseChannelSchema' object has no attribute 'password_hash'
Here's how I solved this problem, using the
serialize_passwordmethod for serialization, andserialization_alias.