Post request for creating a blog post

Git Commit: post request to create blog
Now, we have a record in the user table so we have the author_id field for creating a new blog. Let's create a new blog using a post request. It would be very similar to the previous post, Wanna give it a try? Feel free to try it on your own.

We need 3 new files:

backend/
├─.env
├─alembic/
├─apis/
│ ├─base.py                   
│ └─v1/                       
│   └─route_user.py    
│   └─route_blog.py  #new file   
├─core/
├─db/     
│ ├─repository/                 
│ │ └─user.py 
│ │ └─blog.py        #new file
├─requirements.txt
├─schemas/
│ ├─blog.py          #new file

Type the following code in route_blog.py:

from fastapi import APIRouter, status
from sqlalchemy.orm import Session
from fastapi import Depends

from db.session import get_db
from schemas.blog import ShowBlog, CreateBlog
from db.repository.blog import create_new_blog

router = APIRouter()


@router.post("/blogs",response_model=ShowBlog, status_code=status.HTTP_201_CREATED)
async def create_blog(blog: CreateBlog, db: Session= Depends(get_db)):
    blog = create_new_blog(blog=blog,db=db,author_id=1)
    return blog

We are doing the same thing, we are creating a route that will receive data for blog creation by POST method. It will validate the data received using a schema named CreateBlog. The only catch is that we will not be asking for the slug from the users, rather we will build it from the title provided. Since we want to do the slug generation even before the request body data is validated by Pydantic, we will have to put the pre=True keyword in our validator. So, let's create the schemas required. Type the following in schemas > blog.py.

from typing import Optional
from pydantic import BaseModel, root_validator
from datetime import date



class CreateBlog(BaseModel):
    title: str 
    slug: str 
    content: Optional[str] = None 
    
    @root_validator(pre=True)
    def generate_slug(cls, values):
        if 'title' in values:
            values['slug'] = values.get("title").replace(" ","-").lower()
        return values

        
class ShowBlog(BaseModel):
    title:str 
    content: Optional[str]
    created_at: date

    class Config():
        orm_mode = True

Since we are using a repository pattern and we want to keep the database orm logic completely separated from that of fastapi routes we need to create a make a new function named 'create_new_blog' for creation logic. Let's create this file db > repository > blog.py

from sqlalchemy.orm import Session 
from schemas.blog import CreateBlog
from db.models.blog import Blog


def create_new_blog(blog: CreateBlog, db: Session, author_id:int = 1):
    blog = Blog(**blog.dict(),author_id=author_id)
    db.add(blog)
    db.commit()
    db.refresh(blog)
    return blog

This is yet another example of sqlalchemy orm. We are creating a new record in the database using orm. Still, our fastapi app does not know about this new feature. So, we need to import create_blog route in apis > base.py

from fastapi import APIRouter

from apis.v1 import route_user,route_blog


api_router = APIRouter()
api_router.include_router(route_user.router,prefix="",tags=["users"])
api_router.include_router(route_blog.router,prefix="",tags=["blogs"])


All Done, over and out!

Prev: Our First API … Next: Get Request to …
FastAPITutorial

Brige the gap between Tutorial hell and Industry. We want to bring in the culture of Clean Code, Test Driven Development.

We know, we might make it hard for you but definitely worth the efforts.

Contacts

Refunds:

Refund Policy
Social

Follow us on our social media channels to stay updated.

© Copyright 2022-23 Team FastAPITutorial