Fastapi0.115.6之Tortoise ORM0.23.0、Redis7.2.1基本增删改查大全【亲测可用,仅供参考】

自己在有限的时间里写了一个Fastapi之Tortoise ORM增删改查大全,如有写错的地方还请多多指点。接口功能有可能不全,我会迭代的。主要是方便查找。先放出来一下浏览器的接口文档截图

一、models或ORM数据表文件

from tortoise.models import Model
from tortoise import fields

class P_user(Model):
    p_id = fields.IntField(pk=True)
    p_user = fields.CharField(null=False, unique=True, max_length=12, index=True, description='用户账号')
    p_pass = fields.CharField(null=False, unique=True, max_length=100, description='用户密码')
    role = fields.IntField(null=False, description="角色")
    permissions = fields.IntField(null=False, description="权限")
    created_at = fields.DatetimeField(auto_now_add=True, description="创建日期")
    is_deleted = fields.BooleanField(default=False, description="软删除")
    OAuth2client_id = fields.CharField(null=True, max_length=255, description="OAuth2client_id")
    OAuth2client_secret = fields.CharField(null=True, max_length=255, description="OAuth2client_secret")

    class Meta:
        db_table = 'p_user'
        verbose_name = '用户信息表'
        verbose_name_plural = '用户信息表'


class P_info(Model):
    p_id = fields.IntField(pk=True)
    infoa = fields.CharField(null=False, unique=True, max_length=12, index=True, description='第一种信息')
    infob = fields.CharField(null=False, unique=True, max_length=12, index=True, description='第二种信息')
    infoc = fields.JSONField(null=True, description='第三种信息')

    class Meta:
        db_table = 'p_info'
        verbose_name = '批量信息表'
        verbose_name_plural = '批量信息表'


class P_Login(Model):
    p_id = fields.IntField(pk=True)
    p_user = fields.CharField(null=False, unique=True, max_length=18, description="用户账号")
    p_pass = fields.CharField(null=False, unique=True, max_length=100, description='用户密码')
    p_pic = fields.CharField(null=False, max_length=48, description="用户头像")
    is_deleted = fields.BooleanField(default=False, description="软删除")

    class Meta:
        db_table = 'p_login'
        verbose_name = '用户登录表'
        verbose_name_plural = '用户登录表'

# 一对一关系
class IDCard(Model):
    id = fields.IntField(pk=True)
    content = fields.CharField(max_length=50, unique=True)

    class Meta:
        table = "id_card"

# 一对一关系
class Person(Model):
    id = fields.IntField(pk=True)
    name = fields.CharField(max_length=50)
    id_card = fields.OneToOneField("models.IDCard", related_name="person", on_delete=fields.OnDelete.CASCADE
)

    class Meta:
        table = "person"


# 一对多关系
class Users(Model):
    id = fields.IntField(pk=True)
    username = fields.CharField(max_length=255, unique=True)
    posts = fields.ReverseRelation["Post"]

    class Meta:
        table = "users"

# 一对多关系
class Post(Model):
    id = fields.IntField(pk=True)
    title = fields.CharField(max_length=255)
    content = fields.TextField()
    user = fields.ForeignKeyField("models.Users", related_name="posts", on_delete=fields.OnDelete.CASCADE)

    class Meta:
        table = "posts"

链接数据库代码如下:

TORTOISE_ORM = {
    "connections": {
        'default': {
            'engine': 'tortoise.backends.mysql',
            'credentials': {
                'host': '192.168.80.133',
                'port': '3306',
                'user': 'root',
                'password': 'Newmysql55..',
                'database': 'waerhouse',
                'minsize': 1,
                'maxsize': 5,
                'charset': 'utf8mb4',
                "echo": True
            }
        }
    },
    'apps': {
        'models': {
            # 如果你的models在文件夹里,那就在前面把文件夹的名称写在.models的前面
            'models': ['study_ORM.models', "aerich.models"],
            'default_connection': 'default',
        }
    },
    'use_tz': False,
    'timezone': 'Asia/Shanghai'
}

二、基础接口案例

详细代码如下:

import logging
from math import ceil
from typing import Optional, List

import bcrypt
from fastapi import APIRouter, HTTPException, Query, Body, Depends, Request
from fastapi.templating import Jinja2Templates
from pydantic import BaseModel, field_validator
from starlette import status
from study_ORM.models import P_user

# 设置日志记录
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

p_user_api = APIRouter()


# 查询所有用户信息
@p_user_api.get("/A", summary="查询所有信息接口(不带分页功能)")
async def get_all_users():
    users = await P_user.all()
    logger.info("全部信息查询: %s", users)
    return {"操作结果": users}


# 查询单个字段信息
@p_user_api.get("/B", summary="查询单个字段里的信息接口(精准搜索)")
async def get_user_by_username(p_user: str):
    user = await P_user.filter(p_user=p_user)
    logger.info("过滤查询: %s", user)
    return {"操作结果": user}


# 根据ID查询用户信息
@p_user_api.get("/C", summary="按ID号进行查询")
async def get_user_by_id(p_id: int):
    user = await P_user.get(p_id=p_id)
    logger.info("get查询: %s", user.p_user)
    return {"操作结果": user}


# 模糊查询
@p_user_api.get("/D", summary="按某个字段进行模糊查询")
async def get_user_by_partial_username(p_user: str):
    users = await P_user.filter(p_user__icontains=p_user)
    logger.info("模糊查询: %s", users)
    return {"操作结果": users}


# 查询两个字段信息
@p_user_api.get("/E", summary="只查询其中两个字段里的所有信息")
async def get_user_values():
    users = await P_user.all().values("permissions", "p_user")
    logger.info("values查询: %s", users)
    return {"操作结果": users}


# 分页查询
class UserOut(BaseModel):
    total: int
    total_pages: int
    current_page: int
    has_previous: bool
    has_next: bool
    items: List[dict]


@p_user_api.get("/p_users/page", response_model=UserOut, summary="分页接口")
async def get_users(
        page: int = Query(1, ge=1, description="当前页码"),
        limit: int = Query(10, ge=1, le=100, description="每页数量"),
):
    try:
        skip = (page - 1) * limit
        users = await P_user.filter(is_deleted=False).offset(skip).limit(limit)
        total = await P_user.filter(is_deleted=False).count()
        total_pages = ceil(total / limit)

        user_list = [
            {
                "p_id": user.p_id,
                "p_user": user.p_user,
                "p_pass": user.p_pass,
                "role": user.role,
                "permissions": user.permissions,
                "created_at": user.created_at,
                "is_deleted": user.is_deleted,
            }
            for user in users
        ]

        return {
            "total": total,
            "total_pages": total_pages,
            "current_page": page,
            "has_previous": page > 1,
            "has_next": page < total_pages,
            "items": user_list,
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))


# 前后端不分离查询
@p_user_api.get("/index", summary="前后端不分离查询")
async def get_all_users_html(request: Request):
    templates = Jinja2Templates(directory="templates")
    users = await P_user.all()
    return templates.TemplateResponse("index.html", {"request": request, "userinfo": users})


# 用户输入校验模型
class P_userIn(BaseModel):
    p_user: str = Body(..., descr
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值