FastAPI(六十五)实战开发《在线课程学习系统》基础架构的搭建

在之前三篇,我们分享的就是需求的分析,基本接口的整理,数据库链接的配置。这次我们分享项目的基本框架,目录结构大致如下:

common目录:

通用目录,放一些通用的处理

models目录:

数据库表模型放在这里(你也可以把数据库相关的都放在这个目录下)

routers目录:

放所有接口的地方

test目录:

放测试用例的地方

settings目录:

放配置文件的地方

middlewares目录:

放所有中间件的地方,比如mysql,redis,mongodb等(主要是数据库操作相关)

Dockerfile:

docker打包文件

main:

程序运行主文件

整体的架构设计完毕后,就可以进行相关开发了,这里我们把之前设计的数据库模型相关放到modles目录下的modles.py下:

复制代码
"""
-*- encoding=utf-8 -*-
Time: 2024/7/19 14:18
Author: lc
Email: 15101006331@163.com
File: models.py
"""
from sqlalchemy import Column, Integer, String, ForeignKey, Boolean, Text, DateTime
from sqlalchemy import MetaData
from sqlalchemy.inspection import inspect
from datetime import datetime

from sqlalchemy.orm import DeclarativeMeta

from middlewares.mysql.database import Base, engine


class Role(Base):
    """角色"""
    __tablename__ = "roles"

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String(length=8), unique=True, index=True)  # 角色名称


class User(Base):
    """用户基础表"""
    __tablename__ = "users"

    id = Column(Integer, primary_key=True, index=True)
    username = Column(String(length=32), unique=True, index=True)  # 用户名
    password = Column(String(length=252))  # 密码
    status = Column(Integer, default=0)  # 删除,0正常
    job_num = Column(Integer, nullable=True)  # 工号
    student_num = Column(Integer, nullable=True)  # 学号
    age = Column(Integer)  # 年龄
    sex = Column(String(length=8), default="男")  # 性别
    role = Column(Integer, ForeignKey('roles.id'))  # 角色
    add_time = Column(DateTime, default=datetime.now())


class Course(Base):
    """课程"""
    __tablename__ = "courses"

    id = Column(Integer, primary_key=True, index=True)
    name = Column(String(length=252), unique=True, index=True)  # 课程名称
    icon = Column(String(length=252), nullable=True)  # icon
    desc = Column(String(length=252), nullable=True)  # 描述
    status = Column(Boolean, default=False)  # 状态
    onsale = Column(Boolean, default=False)  # 是否上架
    catalog = Column(Text, nullable=True)  # 目录
    owner = Column(Integer, ForeignKey('users.id'))  # 拥有者
    like_num = Column(Integer, default=0)  # 点赞


class StudentCourse(Base):
    """学生课程"""
    __tablename__ = "student_courses"

    id = Column(Integer, primary_key=True, index=True)
    student = Column(Integer, ForeignKey('users.id'))  # 学生
    course = Column(Integer, ForeignKey('courses.id'))  # 课程
    add_time = Column(DateTime, default=datetime.now())
    update_time = Column(DateTime, default=datetime.now())
    status = Column(Integer, default=0)  # 1.删除,0.正常


class CourseComment(Base):
    """课程评论"""
    __tablename__ = "course_comments"

    id = Column(Integer, primary_key=True, index=True)
    course = Column(Integer, ForeignKey('courses.id'))  # 课程
    user = Column(Integer, ForeignKey('users.id'))  # 评论人
    pid = Column(Integer)  # 回复
    add_time = Column(DateTime, default=datetime.now())
    top = Column(Boolean, default=False)  # 是否置顶
    context = Column(Text)
    status = Column(Boolean, default=0)  # 1删除0正常


class Message(Base):
    __tablename__ = "messages"

    id = Column(Integer, primary_key=True, index=True)
    send_user = Column(Integer, ForeignKey('users.id'))  # 发送者
    accept_user = Column(Integer, ForeignKey('users.id'))  # 接收者
    read = Column(Boolean, default=False)  # 是否已读,接收者是否已读
    send_time = Column(String(length=252))  # 发送时间
    pid = Column(Integer)  # 回复者
    add_time = Column(DateTime, default=datetime.now())  # 添加时间
    context = Column(Text)
    status = Column(Integer, default=0)  # 1删除0正常


def create_tables():
    global_dict = globals()
    classes = [v
               for k, v in global_dict.items()
               if callable(v) and isinstance(v, DeclarativeMeta) and hasattr(v, "__tablename__")]
    metadata = MetaData()
    for _cls in classes:
        if not inspect(engine).has_table(_cls.__tablename__, schema=None, metadata=metadata):
           _cls.__table__.create(bind=engine)
           print(f"表:'{_cls.__tablename__}' 创建完成!")
        else:
            print(f"表:'{_cls.__tablename__}' 已存在!")


if __name__ == '__main__':
    create_tables()

之前配置的链接mysql数据库的配置放在对应的database.py中

复制代码
"""
-*- encoding=utf-8 -*-
Time: 2024/7/19 14:22
Author: lc
Email: 15101006331@163.com
File: database.py
"""
from sqlalchemy import create_engine
from sqlalchemy.orm import declarative_base, sessionmaker
from settings.config import MYSQL_CONFIG

conn = "mysql+pymysql://{username}:{password}@{host}:{port}/{database}?charset=utf8".format(
    username=MYSQL_CONFIG["username"], password=MYSQL_CONFIG["password"], host=MYSQL_CONFIG["host"],
    port=MYSQL_CONFIG["port"], database=MYSQL_CONFIG["database"])
engine = create_engine(conn)

# 该类的每个实例都是一个数据库会话,该类本身还不是数据库会话,但是一旦我们创建了SessionLocal的实例,这个实例将是实际的数据库会话
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

# 创建数据库基类
Base = declarative_base()


def create_db():
    """每个请求处理完毕后关闭当前连接,不同的请求使用不同的链接"""
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

接下来我们的开发只需要关注主逻辑的处理即可,准备放到对应的crud.py和schemas.py文件中,其中crud主要是逻辑处理详细代码,schemas中主要是参数模型以及响应结果模型。

common中我们对json和log做了统一的处理,对应可以参考:

FastAPI 学习之路(五十九)封装统一的json返回处理工具

FastAPI 学习之路(六十)打造系统的日志输出

相关推荐
颂love1 小时前
健康打卡系统项目总结
fastapi·sqlalchemy·全栈开发·dify集成
展示猪肝5 小时前
Vue2 + FastAPI + Dify 实现 AI 医疗预检分诊助手:从问诊追问到医生审核闭环
人工智能·vue·fastapi·dify
辞忧九千七7 小时前
前后端分离架构实战与项目落地:AI智能学习笔记管理系统
python·html·axios·css3·fastapi·dify
深兰科技7 小时前
深兰科技签约乌兹别克斯坦智慧城市项目,推动中国AI出海规模化
人工智能·beautifulsoup·numpy·智慧城市·fastapi·matplotlib·深兰科技
码界筑梦坊8 小时前
118-基于Python的游戏账号数据可视化分析系统
python·游戏·信息可视化·毕业设计·pandas·fastapi
rising start8 小时前
InsightEdu - 轻量智能学习平台
javascript·axios·css3·html5·fastapi·orm·dify
小李云雾10 小时前
慧校坊-二手校园交易平台-------项目总结
数据库·后端·程序人生·fastapi·项目
我叫张小白。11 小时前
劳动力招聘管理系统:全栈实战(Vue3+FastAPI+WebSocket+Dify)
websocket·vue·毕业设计·状态模式·fastapi·dify·智能体
csdn小瓯20 小时前
LangGraph自适应工作流路由机制:从关键词匹配到智能决策的完整实现
人工智能·fastapi·langgraph
PieroPc1 天前
CAMWATCH — 局域网摄像头监控系统 Fastapi + html
前端·python·html·fastapi·监控