Fastapi TortoiseORM字段参数、常用字段类型及参数、模型和表单验证器详解

一、安装Tortoise ORM

pip install tortoise-orm
(注:Fastapi TortoiseORM 与 Django ORM写法非常相似)

二、常用字段参数

  • pk: 是否为主键字段,默认 False
  • unique: 是否唯一,默认 False
  • index: 是否为索引字段,默认 False
  • null: 是否允许为 NULL,默认 False
  • default: 字段的默认值,可以是函数或静态值。
  • description: 字段的描述,通常用于文档化。
  • max_length: 最大长度,主要用于 CharField
  • precision: 精度,主要用于 DecimalField
  • scale: 小数位数,主要用于 DecimalField
  • generated: 是否是数据库生成的字段(如自动递增字段)。
  • read_only: 是否为只读字段。
  • constraints: 定义复杂的约束条件。

三、 常用字段类型及参数

基本字段类型

字段类型

参数(选项)

说明

CharField

max_length

default

字符串字段,需定义最大长度

TextField

default

长文本字段

IntField

default

null

generated

整数字段

BigIntField

同上

大整数字段

FloatField

default

null

浮点字段

DecimalField

max_digits

decimal_places

高精度浮点字段

BooleanField

default

布尔字段

DatetimeField

auto_now

auto_now_add

日期时间字段,支持自动更新

DateField

auto_now

auto_now_add

日期字段

关系字段

字段类型

参数(选项)

说明

ForeignKeyField

model_name

related_name

on_delete

外键字段

OneToOneField

model_name

related_name

on_delete

一对一关系字段

ManyToManyField

model_name

through

related_name

多对多关系字段

四、模型案例

from tortoise.models import Model
from tortoise import fields

class User(Model):
    id = fields.IntField(pk=True)
    username = fields.CharField(max_length=50, unique=True)
    email = fields.CharField(max_length=100, unique=True, null=True)
    password = fields.CharField(max_length=128)
    is_active = fields.BooleanField(default=True)
    created_at = fields.DatetimeField(auto_now_add=True)
    updated_at = fields.DatetimeField(auto_now=True)

    class Meta:
        table = "user"
        indexes = [("username", "email")]  # 联合索引

五、表单验证器
Pydantic 用于数据验证 ,可以结合 Tortoise-ORM 一起使用

from pydantic import BaseModel, EmailStr, Field

# 创建 Pydantic 模型用于表单验证
class UserCreate(BaseModel):
    username: str = Field(..., max_length=50)
    email: EmailStr
    password: str = Field(..., min_length=6)

class UserResponse(BaseModel):
    id: int
    username: str
    email: EmailStr
    is_active: bool
    created_at: str

    class Config:
        orm_mode = True

六、Pydantic 模型与 Tortoise 模型结合

创建用户的 API 示例

from fastapi import FastAPI, HTTPException
from models import User  # Tortoise 模型
from schemas import UserCreate, UserResponse  # Pydantic 模型

app = FastAPI()

@app.post("/users/", response_model=UserResponse)
async def create_user(user: UserCreate):
    existing_user = await User.filter(username=user.username).first()
    if existing_user:
        raise HTTPException(status_code=400, detail="Username already exists")
    new_user = await User.create(**user.dict())
    return new_user

七、关系表
1、一对一关系

一对一关系表示两个模型之间存在唯一的对应关系。例如,一个人只有一个身份证,一个身份证只属于一个人。

from tortoise import fields, models

class IDCard(models.Model):
    id = fields.IntField(pk=True)
    number = fields.CharField(max_length=20, unique=True)

    person: fields.OneToOneRelation["Person"]

    class Meta:
        table = "id_card"

class Person(models.Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=50)

    id_card: fields.OneToOneRelation[IDCard] = fields.OneToOneField(
        "models.IDCard", related_name="person", on_delete=fields.OnDelete.CASCADE
    )

    class Meta:
        table = "person"
  • fields.OneToOneField 用于定义一对一关系。
  • related_name 参数用于在关联的模型中反向访问。
  • on_delete 参数定义了当关联的模型被删除时的行为,例如 fields.OnDelete.CASCADE 表示级联删除。
async def create_person_with_id_card():
    id_card = await IDCard.create(number="1234567890")
    person = await Person.create(name="张三", id_card=id_card)
    print(f"创建了人员:{person.name},身份证号:{person.id_card.number}")

async def get_person_by_id_card_number(number: str):
    id_card = await IDCard.get(number=number)
    person = await id_card.person
    print(f"通过身份证号 {number} 找到了人员:{person.name}")

2、一对多关系

一对多关系表示一个模型可以关联多个其他模型。例如,一个作者可以有多篇文章,一篇文章只能有一个作者。

from tortoise import fields, models

class Author(models.Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=50)

    articles: fields.ReverseRelation["Article"]

    class Meta:
        table = "author"

class Article(models.Model):
    id = fields.IntField(pk=True)
    title = fields.CharField(max_length=100)
    content = fields.TextField()

    author: fields.ForeignKeyRelation[Author] = fields.ForeignKeyField(
        "models.Author", related_name="articles", on_delete=fields.OnDelete.CASCADE
    )

    class Meta:
        table = "article"

fields.ForeignKeyField 用于定义外键,表示多的一方。

fields.ReverseRelation 用于在一的一方反向访问多的一方。

async def create_author_with_articles():
    author = await Author.create(name="李四")
    await Article.create(title="文章1", content="内容1", author=author)
    await Article.create(title="文章2", content="内容2", author=author)
    print(f"作者 {author.name} 发表了 {await author.articles.all().count()} 篇文章")

async def get_articles_by_author_name(name: str):
    author = await Author.get(name=name)
    articles = await author.articles.all()
    for article in articles:
        print(f"文章标题:{article.title}")

3、多对多关系

多对多关系表示两个模型之间可以互相关联多个。例如,一个学生可以选择多门课程,一门课程可以被多个学生选择。

from tortoise import fields, models

class Student(models.Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=50)

    courses: fields.ManyToManyRelation["Course"] = fields.ManyToManyField(
        "models.Course", related_name="students"
    )

    class Meta:
        table = "student"

class Course(models.Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=50)

    students: fields.ManyToManyRelation[Student]

    class Meta:
        table = "course"

fields.ManyToManyField 用于定义多对多关系。Tortoise ORM 会自动创建一个中间表来维护这种关系。

async def create_student_with_courses():
    student = await Student.create(name="王五")
    course1 = await Course.create(name="语文")
    course2 = await Course.create(name="数学")
    await student.courses.add(course1, course2)
    print(f"学生 {student.name} 选择了 {await student.courses.all().count()} 门课程")

async def get_students_by_course_name(name: str):
    course = await Course.get(name=name)
    students = await course.students.all()
    for student in students:
        print(f"选修该课程的学生:{student.name}")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值