本記事について
この記事はプログラミング初学者の私が学んでいく中でわからない単語や概要を分かりやすくまとめたものです。
もし不正などありましたらコメントにてお知らせいただければ幸いです。
タスクの一覧を取得する
database.py
async def db_get_todos() -> list: # 一覧が返ってくるようにlist型を定義
todos = [] # MongoDBから返ってくるデータを受ける配列
# タスクの一覧を受け取る処理
for todo in await collection_todo.find().to_list(length=100): # lengthで最大件数を定義
todos.append(todo_serializer(todo)) # for文で展開した物をtodosに格納
return todos
-
collection_todo.find()
motorのメソッド('find()') - 'find()'はmotorのインスタンスを作ってくれるもの
-
to_list
実行するときに通信が行われるのでasync
が必要になる
route_todo.py
@router.get("/api/todo", response_model=List[Todo]) # 一覧取得なのでList型で返ってくる
async def get_todos():
res = await db_get_todos()
return res
特定の情報を取得
database.py
from bson import ObjectId
async def db_get_single_todo(id: str) -> Union[dict, bool]: # 取得したいidをstringで取得、返り値はdict,boolを返す
todo = await collection_todo.find_one({"_id": ObjectId(id)}) # ObjectIdに変換
if todo:
return todo_serializer(todo)
return False
-
from bson import ObjectId
Mongo DBではBsonとうフォーマット保存されている
route_todo.py
@router.get("/api/todo/{id}", response_model=Todo) # 一つしか返ってこない
async def get_single_todo(id: str):
res = await db_get_single_todo(id)
if res:
return res
raise HTTPException(
status_code=404, detail=f"Task of ID:{id} doesn't exist"
)
前回と合わせたコード
database.py
from decouple import config
from typing import Union # 選択肢が2つ以上の場合に使える
import motor.motor_asyncio # こちらでMongoDB連携のために使う
from bson import ObjectId # MongoDB内でBsonフォーマット保存されているため
MONGO_API_KEY = config('MONGO_API_KEY') # configを使って環境変数読み込む
client = motor.motor_asyncio.AsyncIOMotorClient(MONGO_API_KEY) # MongoDB連携 APIのキーを渡す
database = client.API_DB # MongoDBの名前と一致
collection_todo = database.todo # MongoDBの名前と一致
collection_user = database.user # MongoDBの名前と一致
# insert_oneを辞書型で返すために必要な関数
def todo_serializer(todo) -> dict:
return {
"id": str(todo["_id"]),
"title": todo["title"],
"description": todo["description"]
}
async def db_create_todo(data: dict) -> Union[dict, bool]: # Unionで選択肢をdict, bool選べるようにしている
todo = await collection_todo.insert_one(data) # insert_oneの返り値 insertResult(インスタンス)返り値になる
new_todo = await collection_todo.find_one({"_id": todo.inserted_id}) # find_oneでidを取得
# find_oneのあるなし判定
if new_todo:
return todo_serializer(new_todo)
return False
async def db_get_todos() -> list: # 一覧が返ってくるようにlist型を定義
todos = [] # MongoDBから返ってくるデータを受ける配列
# タスクの一覧を受け取る処理
for todo in await collection_todo.find().to_list(length=100): # lengthで最大件数を定義
todos.append(todo_serializer(todo)) # for文で展開した物をtodosに格納
return todos
async def db_get_single_todo(id: str) -> Union[dict, bool]: # 取得したいidをstringで取得、返り値はdict,boolを返す
todo = await collection_todo.find_one({"_id": ObjectId(id)}) # ObjectIdに変換
if todo:
return todo_serializer(todo)
return False
route_todo.py
from fastapi import APIRouter # routerを作るのに必要
from fastapi import Response, Request, HTTPException # 11行目、21行目の関数
from fastapi.encoders import jsonable_encoder # jsonable_encoder型で受け取ったデータを辞書型にするために必要
from schemas import Todo, TodoBody # 型定義
from database import db_create_todo, db_get_todos, db_get_single_todo # database.pyで作った関数
from starlette.status import HTTP_201_CREATED # ステータスコードを上書きするのに必要
from typing import List # Listを使うため
router = APIRouter() # インスタンス化
@router.post("/api/todo", response_model=Todo)
async def create_todo(request: Request, response: Response, data:TodoBody): # 実行されたときの関数を定義
todo = jsonable_encoder(data) # 受け取ったdataを辞書型にする
res = await db_create_todo(todo)
response.status_code = HTTP_201_CREATED # ステータスコードの上書き
# jsonable_encoder型存在していたらデータを存在しなければnoneを返すので判定する
if res:
return res
# noneの場合の例外処理
raise HTTPException(
status_code=404, detail="Create task failed"
)
@router.get("/api/todo", response_model=List[Todo]) # 一覧取得なのでList型で返ってくる
async def get_todos():
res = await db_get_todos()
return res
@router.get("/api/todo/{id}", response_model=Todo) # 一つしか返ってこない
async def get_single_todo(id: str):
res = await db_get_single_todo(id)
if res:
return res
raise HTTPException(
status_code=404, detail=f"Task of ID:{id} doesn't exist"
)
参考