个人图书管理系统

from fastapi import FastAPI,HTTPException
from pydantic import BaseModel,Field
from datetime import datetime
from typing import List,Optional,Literal

app=FastAPI(
    title="个人图书收藏管理系统",
    description="实现了对图书管理的增删改查",
    version="1.0.0"
)
current_id=1
books_list=[]

class Book(BaseModel):
    id:Optional[int]=Field(default=None,description="序号,由系统生成")
    title:str=Field(...,description="书名")
    author:str=Field(...,description="作者")
    publication_year:Optional[int]=Field(default=None,description="出版年份")
    reading_status:Literal["已读","未读"]=Field(...,description="(已读/未读)")
    rating:Optional[int]=Field(default=None,ge=1,le=5,description="(1-5星)")
    add_time:datetime=Field(default_factory=datetime.now,description="添加时间")


#添加新书到收藏
@app.post(
    "/books/",
    summary="添加新书",
    response_model=Book
)
def add_book(book:Book):
    global books_list,current_id
    new_book={
        "id":current_id,
        "title":book.title,
        "author":book.author,
        "publication_year":book.publication_year,
        "reading_status":book.reading_status,
        "rating":book.rating,
        "add_time":datetime.now()
    }
    books_list.append(new_book)
    current_id+=1

    return new_book

#查看所有收藏的书籍
@app.get(
    "/books/",
    summary="查看收藏书籍",
    response_model=List[Book]
)
def check_books():
    return books_list

#根据id查看单本书籍详情
@app.get(
    "/books/{book_id}",
    summary="根据id查看单本书籍详情",
    response_model=Book
)
def get_book_by_id(book_id:int):
    for book in books_list:
        if book["id"]==book_id:
            return book

    raise HTTPException(status_code=404,detail="该书未找到")

#更新书籍信息
@app.put(
    "/books/{book_id}",
    summary="更新书籍",
    response_model=Book
)
def update_book(book_id:int, updated_book:Book):
    global books_list
    for i,book in enumerate(books_list):
        if book["id"]==book_id:
            books_list[i]={
                "id":book_id,
                "title":updated_book.title,
                "author":updated_book.author,
                "publication_year":updated_book.publication_year,
                "reading_status":updated_book.reading_status,
                "rating":updated_book.rating,
                "add_time":book["add_time"]
            }

            return books_list[i]

    raise HTTPException(status_code=404,detail="该书未找到")


#删除书籍
@app.delete(
    "/books/{book_id}",
    summary="删除书籍",
    description="根据id删除选中的书籍"
)
def delete_book(book_id:int):
    global books_list
    for i,book in enumerate(books_list):
        if book["id"]==book_id:
            books_list.pop(i)
            return{
                "status":"success",
                "message":f"编号{book_id}已删除"
            }

    raise HTTPException(status_code=404,detail="该书未找到")

遇到的问题与解决方法

  1. 如何让阅读状态只限于(已读/未读)?

    使用Literal,将填入的内容只局限于(已读/未读)

  2. 如何来控制评分的范围?

    使用ge,le;ge是大于等于,le是小于等于

  3. 我要怎么做才能让每次添加书籍后,书籍的序号能够自增,不用在添加的时候去自己输入?

    首先使用Optional将id的值设置为可选,再定义一个全局变量current_id,让它的值初始化为1,因为此时收藏里是没有书的,当用户每添加一次书籍,current_id的值就会加一

  4. 怎么做才能在删除和更新书籍内容时精确的匹配到目标?

    可使用遍历,在添加书籍时,创建一个books_list列表(但是,books_list中的元素是字典),作为容器来存储用户存入的书籍信息;在更新和删除时,系统会得到一个名为book_id的int类型变量,然后遍历整个books_list来查找跟book_id相等的book["id"];但是只使用for book in books_list,我们虽能实现能否找到要删除的目标,却不能实现后续的删除/更新工作。

    我们可以使用enumrate,这个方法在遍历迭代对象时(例如books_list),可以同时获取元素的索引以及对应的值,所以我们可以使用:for i ,book in enumrate(books_list) 在取得books_list中元素的同时,取得对应的下标索引。这样,当我们遍历完整个列表后,就可以很方便的根据下标索引来进行删除和更新

posted @ 2025-10-31 20:05  神也忧伤  阅读(4)  评论(0)    收藏  举报