Skip to content

Commit d3e46dc

Browse files
committed
Best practice for _id
1 parent c8954b3 commit d3e46dc

File tree

2 files changed

+14
-25
lines changed

2 files changed

+14
-25
lines changed

models.py

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from pydantic import BaseModel, Field
44

55
class Book(BaseModel):
6-
id: str = Field(default_factory=uuid.uuid4, alias="_id")
6+
id: str = Field()
77
title: str = Field(...)
88
author: str = Field(...)
99
synopsis: str = Field(...)
@@ -12,28 +12,13 @@ class Config:
1212
allow_population_by_field_name = True
1313
schema_extra = {
1414
"example": {
15-
"_id": "066de609-b04a-4b30-b46c-32537c7f1f6e",
15+
"_id": "6428a5fffe4c6065ecf51cb7",
1616
"title": "Don Quixote",
1717
"author": "Miguel de Cervantes",
1818
"synopsis": "..."
1919
}
2020
}
2121

22-
class BookCreate(BaseModel):
23-
id: str = Field(default_factory=uuid.uuid4, alias="_id")
24-
title: str = Field(...)
25-
author: str = Field(...)
26-
synopsis: str = Field(...)
27-
28-
class Config:
29-
allow_population_by_field_name = True
30-
schema_extra = {
31-
"example": {
32-
"title": "Don Quixote",
33-
"author": "Miguel de Cervantes",
34-
"synopsis": "..."
35-
}
36-
}
3722
class BookCreate(BaseModel):
3823
title: str = Field(...)
3924
author: str = Field(...)

routes.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
from fastapi import APIRouter, Body, Request, Response, HTTPException, status
22
from fastapi.encoders import jsonable_encoder
33
from typing import List
4-
import uuid
4+
from bson import ObjectId
55
from models import Book, BookUpdate, BookCreate
66

77
router = APIRouter()
88

9-
@router.post("/", response_description="Create a new book", status_code=status.HTTP_201_CREATED, response_model=Book)
9+
@router.post("/", response_description="Create a new book", status_code=status.HTTP_201_CREATED)
1010
def create_book(request: Request, book: BookCreate = Body(...)):
1111
book = jsonable_encoder(book)
12-
book["_id"] = str(uuid.uuid4())
1312

1413
# verify if book title already exists
1514
if request.app.database["books"].find_one({"title": book["title"]}):
@@ -21,18 +20,22 @@ def create_book(request: Request, book: BookCreate = Body(...)):
2120
{"_id": new_book.inserted_id}
2221
)
2322

24-
return created_book
23+
created_book['id'] = str(created_book['_id'])
24+
return Book(**created_book)
2525

2626

2727
@router.get("/", response_description="List all books", response_model=List[Book])
2828
def list_books(request: Request):
2929
books = list(request.app.database["books"].find(limit=100))
30+
for book in books:
31+
book['id'] = str(book['_id'])
3032
return books
3133

3234

3335
@router.get("/{id}", response_description="Get a single book by id", response_model=Book)
3436
def find_book(id: str, request: Request):
35-
if (book := request.app.database["books"].find_one({"_id": id})) is not None:
37+
if (book := request.app.database["books"].find_one({"_id": ObjectId(id)})) is not None:
38+
book['id'] = str(book['_id'])
3639
return book
3740

3841
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Book with ID {id} not found")
@@ -44,23 +47,24 @@ def update_book(id: str, request: Request, book: BookUpdate = Body(...)):
4447

4548
if len(book) >= 1:
4649
update_result = request.app.database["books"].update_one(
47-
{"_id": id}, {"$set": book}
50+
{"_id": ObjectId(id)}, {"$set": book}
4851
)
4952

5053
if update_result.modified_count == 0:
5154
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Book with ID {id} not found")
5255

5356
if (
54-
existing_book := request.app.database["books"].find_one({"_id": id})
57+
existing_book := request.app.database["books"].find_one({"_id": ObjectId(id)})
5558
) is not None:
59+
existing_book['id'] = str(existing_book['_id'])
5660
return existing_book
5761

5862
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"Book with ID {id} not found")
5963

6064

6165
@router.delete("/{id}", response_description="Delete a book")
6266
def delete_book(id: str, request: Request, response: Response):
63-
delete_result = request.app.database["books"].delete_one({"_id": id})
67+
delete_result = request.app.database["books"].delete_one({"_id": ObjectId(id)})
6468

6569
if delete_result.deleted_count == 1:
6670
response.status_code = status.HTTP_204_NO_CONTENT

0 commit comments

Comments
 (0)