在 FastAPI 和 Tortoise-ORM 中,可以使用 Tortoise-ORM 提供的 to_dict()
方法,将模型对象转换为 Python 字典表示。以下是一个示例:只需在模型类中添加以下代码:
from fastapi import FastAPI
from tortoise import fields
from tortoise.models import Model
from tortoise.contrib.fastapi import register_tortoise
class User(Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=50)
email = fields.CharField(max_length=255)
def to_dict(self):
return {
"id": self.id,
"name": self.name,
"email": self.email,
}
app = FastAPI()
register_tortoise(
app,
db_url="sqlite://db.sqlite3",
modules={"models": ["__main__"]},
generate_schemas=True,
add_exception_handlers=True,
)
@app.get("/users/{user_id}")
async def get_user(user_id: int):
user = await User.get(id=user_id)
return user.to_dict()
对于每个模型对象,你现在可以像这样调用 to_dict()
方法:
user = await User.get(id=user_id)
user_dict = user.to_dict()
这里我们在 User
模型类中定义了一个 to_dict()
方法,用于将模型对象转换为字典表示。然后,在视图函数中,我们使用 User.get()
方法获取了一个 User
对象,并将其转换为字典表示。
请注意,在上面的 register_tortoise()
方法中,我们指定了 generate_schemas=True
,这会在应用程序启动时自动生成数据库表格。这是因为 Tortoise-ORM 不会自动创建数据库表格,所以需要手动执行此步骤。如果你已经手动创建了数据库表格,则可以将此参数设置为 False
。
另一种通用的方法:
当然,还有其他方法可以将 Tortoise-ORM 模型对象转换为 Python 字典表示。以下是一种通用的方法:
def model_to_dict(model):
data = {}
for field in model._meta.fields:
field_name = field.attname
value = getattr(model, field_name)
if isinstance(field, fields.ForeignKeyField):
if value:
value = value.id
else:
value = None
data[field_name] = value
return data
这个方法接受一个 Tortoise-ORM 模型对象,并返回一个 Python 字典表示。它使用 _meta
属性获取模型类的元数据,并迭代模型的每个字段,将每个字段的名称和值添加到结果字典中。
在处理外键字段时,该方法将其转换为关联对象的 ID。如果外键字段的值为 None
,则将其转换为 None
值。
你可以在 API 视图函数中使用此方法,例如:
from fastapi import FastAPI
from tortoise import fields
from tortoise.models import Model
from tortoise.contrib.fastapi import register_tortoise
class User(Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=50)
email = fields.CharField(max_length=255)
app = FastAPI()
register_tortoise(
app,
db_url="sqlite://db.sqlite3",
modules={"models": ["__main__"]},
generate_schemas=True,
add_exception_handlers=True,
)
@app.get("/users/{user_id}")
async def get_user(user_id: int):
user = await User.get(id=user_id)
user_dict = model_to_dict(user)
return user_dict
这样就可以将 User
模型对象转换为 Python 字典表示了。
如果你有一个对象列表,并且想将它转换为 Python 字典列表,你可以使用上面的方法,并在循环中对每个对象调用 model_to_dict()
方法。例如
from fastapi import FastAPI, Response
import json
...
@app.get("/users")
async def get_users():
users = await User.all()
user_dicts = [model_to_dict(user) for user in users]
return Response(content=json.dumps(user_dicts), media_type="application/json")
这样返回的就是 JSON 格式的用户列表了。
如果你希望由 FastAPI 自动处理模型对象的序列化,可以使用 FastAPI 提供的 response_model_exclude_unset
和 response_model_exclude_none
参数。这些参数将根据模型类的字段设置,自动忽略未设置或空值的字段。示例:
from fastapi import FastAPI
from tortoise import fields
from tortoise.models import Model
from tortoise.contrib.fastapi import register_tortoise
class User(Model):
id = fields.IntField(pk=True)
name = fields.CharField(max_length=50)
email = fields.CharField(max_length=255)
app = FastAPI()
register_tortoise(
app,
db_url="sqlite://db.sqlite3",
modules={"models": ["__main__"]},
generate_schemas=True,
add_exception_handlers=True,
)
@app.get("/users/{user_id}", response_model=User, response_model_exclude_unset=True)
async def get_user(user_id: int):
user = await User.get(id=user_id)
return user
这样,在响应中,只有设置了值的字段才会出现。如果你想完全禁用字段过滤,请将 response_model_exclude_unset
参数设置为 False
,并将 response_model_exclude_none
参数设置为 True
。
值得注意的是,设置这些参数仅会影响响应的输出,而不会影响输入的验证。在输入验证方面,FastAPI 将始终根据模型类的字段设置进行验证。