当前位置: 首页 > news >正文

【FastAPI】8.FastAPI结合Jinja2模板完成一个待办列表

代码结构

. #根目录
└── todo #module名称
    ├── static # 静态文件
    │   ├── logo.png # 测试用logo
    │   └── style.css # 代码样式
    ├── templates
    │   └── todo.html# 前端页面
    ├── main.py # 系统入口及API接口
    └── models.py # 实体映射

前端样式

#todo_list{
  border :solid 1px #0b2e13;
  border-collapse:collapse;
}

#todo_list #header{
  background-color:#1e7e34;
  color:#white;
}

#todo_list #header th{
  padding: 5px 10px;
  border:solid 1px #0b2e13;
}

#todo_list #th{
  padding: 5px 10px;
  border:solid 1px #0b2e13;
}

Jinja2的前端html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Todo List</title>
  <link rel="stylesheet" href="/static/style.css">
</head>
<body>
<h1>todo list</h1>
<form action="/addTodo" method="post">
  <div>
    <label for="name">待办名称:</label>
    <input type="text" name="name" required>
  </div>
  <div>
    <label for="priority">优先级:</label>
    <select name="priority" required>
      <option value="1">1</option>
      <option value="2">2</option>
      <option value="3">3</option>
      <option value="4">4</option>
      <option value="5">5</option>
    </select>
  </div>
  <button type="submit">添加</button>
</form>
<table id = "todo_list">
  <thead>
  <tr id="header">
    <th>id</th>
    <th>名称</th>
    <th>是否完成</th>
    <th>优先级</th>
    <th>创建日期</th>
  </tr>
  </thead>
  <tbody>
    <!-- 解析后端返回的参数并渲染表格 -->
  {% for todo in todos %}
  <tr>
    <td>{{ todo.id }}</td>
    <td>{{ todo.name }}</td>
    <td>{{ todo.is_completed }}</td>
    <td>{{ todo.priority }}</td>
    <td>{{ todo.created_at }}</td>
    <td>
      <!--如果未完成,显示标记为完成按钮,并提供post方法,标记为已完成-->
      {% if not todo.is_completed %}
      <form action="/todo/{{ todo.id }}/complete" method="post">
        <button type="submit">标记为完成</button>
      </form>
      {% else %}
      <a href="/completeTodo/{{ todo.id }}">已完成</a>
      {% endif %}
      <!--删除操作-->
      <form action="/todo/{{ todo.id }}/delete" style="display:inline" method="post">
        <button type="submit">删除</button>
      </form>
    </td>
  </tr>
  {% endfor %}
  </tbody>
</table>
</body>
</html>

main函数

from datetime import datetime

import  uvicorn
from fastapi import FastAPI, Request, Form
from starlette.responses import HTMLResponse,RedirectResponse
from tortoise.contrib.fastapi import register_tortoise
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
from tortoise.exceptions import DoesNotExist

from todo.models import Todo

app = FastAPI()
# 静态文件目录
app.mount("/static", StaticFiles(directory="static"), name="static")

# html 页面目录
templates = Jinja2Templates(directory="templates")
try:
    register_tortoise(
        app,
        db_url="mysql://root:[PWD]@[IP]:3306/tortoise_fast_api",  # 替换为你的数据库名称
        modules={"models": ["todo.models"]},  # 指定包含的 models 模块
        generate_schemas=False,  # 不自动生成表结构
        add_exception_handlers=True  # 添加异常处理程序
    )
    print("Tortoise ORM registered successfully.")
except Exception as e:
    print(f"Failed to register Tortoise ORM: {e}")

# 返回类定义为HTMLResponse,返回html页面
@app.get("/todos",response_class=HTMLResponse)
async def get_todo_list(request:Request):
  """
    使用 await Todo.all().order_by("-created_at") 获取所有待办事项并按创建时间降序排序。
    使用 templates.TemplateResponse 渲染 todo.html 模板,并传递请求对象和待办事项列表。
  """
  todos:list[Todo] = await Todo.all().order_by("-created_at")
  return templates.TemplateResponse("todo.html",{"request":request,"todos":todos})


@app.post("/addTodo",response_class=HTMLResponse)
async def add_todo(request:Request,name:str =Form(...),priority:str =Form(...)):
  await Todo.create(name=name,priority=priority,created_at = datetime.now())
  return RedirectResponse("/todos",status_code=303)


@app.post("/todo/{id}/complete", response_class=RedirectResponse)
async def complete_todo(id: int):
  todo = await Todo.get(id=id)
  if not todo:
    return RedirectResponse("/todos", status_code=303)
  todo.is_completed = True
  await todo.save()
  return RedirectResponse("/todos", status_code=303)


@app.post("/todo/{id}/delete", response_class=RedirectResponse)
async def delete_todo(id: int):
  try:
    todo = await Todo.get(id=id)
    await todo.delete()
  except DoesNotExist:
    pass
  return RedirectResponse("/todos", status_code=303)
if __name__ == "__main__":
    uvicorn.run(app,port=8888)

models 定义实体

from tortoise import fields

from tortoise import Model

class Todo(Model):
    id = fields.IntField(pk=True,description="待办ID")
    name = fields.CharField(max_length=255,description="待办名称")
    is_completed = fields.BooleanField(default=False,description="是否完成")
    priority = fields.CharField(max_length=10,description="优先级")
    created_at = fields.DatetimeField(description="创建时间")

    class Meta:
        table = "todo"
        table_description = "待办表"

相关文章:

  • 【数据结构-并查集】力扣721. 账户合并
  • Pycharm 2024在解释器提供的python控制台中运行py文件
  • DDD该怎么去落地实现(3)通用的仓库和工厂
  • 用大模型学大模型04-模型可视化与数据可视化
  • [数据结构]二叉搜索树详解
  • Spring——Spring开发实战经验(4)
  • SpringBoot 的核心只有几张图
  • Ubuntu 24.04.1 LTS 本地部署 DeepSeek 私有化知识库
  • C语言中的强制类型转换:原理、用法及注意事项
  • 1.buuctf [BJDCTF2020]EasySearch
  • Hadoop之HDFS的使用
  • 从零开始:Gitee 仓库创建与 Git 配置指南
  • 服务器硬件知识--------linux系统初识and安装
  • Linux csplit 命令实现日志文件的拆分
  • 软考高级《系统架构设计师》知识点(五)
  • Spring事务原理的具体实现,以及包括源码以及具体在实际项目中的使用。
  • 【etcd】etcd_APIs 简单KV、watch、lease、txn命令
  • 数据结构-顺序表
  • 东方财富股吧发帖与评论爬虫
  • 基于腾讯云TI-ONE 训练平台快速部署和体验 DeepSeek 系列模型
  • 量子传感新技术“攻克”退相干难题
  • 烟花、美食和购物优惠都安排上了,上海多区开启热闹模式
  • 解放日报头版聚焦“人民城市”:共建共享展新卷
  • 新造古镇丨上海古镇朱家角一年接待164万境外游客,凭啥?
  • 国家发改委:我国能源进口来源多元,企业减少甚至停止自美能源进口对国内能源供应没有影响
  • 玉渊谭天丨中方减少美国农产品进口后,舟山港陆续出现巴西大豆船