Many-to-many relationships

Adding an API route to like posts

Want more?

This lesson for enrolled students only. Join the course to unlock it!

You can see the code changes implemented in this lecture below.

If you have purchased the course in a different platform, you still have access to the code changes per lecture here on Teclado. The lecture video and lecture notes remain locked.
Join course for $30

Modified files

storeapi/routers/post.py
--- 
+++ 
@@ -2,10 +2,12 @@
 from typing import Annotated

 from fastapi import APIRouter, Depends, HTTPException
-from storeapi.database import comment_table, database, post_table
+from storeapi.database import comment_table, database, like_table, post_table
 from storeapi.models.post import (
     Comment,
     CommentIn,
+    PostLike,
+    PostLikeIn,
     UserPost,
     UserPostIn,
     UserPostWithComments,
@@ -96,3 +98,22 @@
         "post": post,
         "comments": await get_comments_on_post(post_id),
     }
+
+
+@router.post("/like", response_model=PostLike, status_code=201)
+async def like_post(
+    like: PostLikeIn, current_user: Annotated[User, Depends(get_current_user)]
+):
+    logger.info("Liking post")
+
+    post = await find_post(like.post_id)
+    if not post:
+        raise HTTPException(status_code=404, detail="Post not found")
+
+    data = {**like.model_dump(), "user_id": current_user.id}
+    query = like_table.insert().values(data)
+
+    logger.debug(query)
+
+    last_record_id = await database.execute(query)
+    return {**data, "id": last_record_id}
storeapi/tests/routers/test_post.py
--- 
+++ 
@@ -21,6 +21,17 @@
     response = await async_client.post(
         "/comment",
         json={"body": body, "post_id": post_id},
+        headers={"Authorization": f"Bearer {logged_in_token}"},
+    )
+    return response.json()
+
+
+async def like_post(
+    post_id: int, async_client: AsyncClient, logged_in_token: str
+) -> dict:
+    response = await async_client.post(
+        "/like",
+        json={"post_id": post_id},
         headers={"Authorization": f"Bearer {logged_in_token}"},
     )
     return response.json()
@@ -85,6 +96,18 @@
     )

     assert response.status_code == 422
+
+
+@pytest.mark.anyio
+async def test_like_post(
+    async_client: AsyncClient, created_post: dict, logged_in_token: str
+):
+    response = await async_client.post(
+        "/like",
+        json={"post_id": created_post["id"]},
+        headers={"Authorization": f"Bearer {logged_in_token}"},
+    )
+    assert response.status_code == 201


 @pytest.mark.anyio
storeapi/models/post.py
--- 
+++ 
@@ -27,3 +27,12 @@
 class UserPostWithComments(BaseModel):
     post: UserPost
     comments: list[Comment]
+
+
+class PostLikeIn(BaseModel):
+    post_id: int
+
+
+class PostLike(PostLikeIn):
+    id: int
+    user_id: int