YouTip LogoYouTip

Fastapi Blog Routers Views

\\\\\\ ## Routing and Article List, Detail Page\\\\\\ \\\\\\ In this chapter, you will learn to split routes using APIRouter to implement the homepage article list and article detail page.\\\\\\ \\\\\\ * * *\\\\\\ \\\\\\ ## APIRouter β€” FastAPI's Route Splitting Solution\\\\\\ \\\\\\ APIRouter is equivalent to Flask's Blueprint and Django's include().\\\\\\ \\\\\\ ## Example\\\\\\ \\\\\\ # File path: routers/posts.py\\\\\\ \\\\\\ from fastapi import APIRouter, Depends, HTTPException, Request\\\\\\ \\\\\\ from sqlalchemy.orm import Session\\\\\\ \\\\\\ from database import get_db\\\\\\ \\\\\\ from models import Post, Category\\\\\\ \\\\\\ from schemas import PostResponse\\\\\\ \\\\\\ router = APIRouter(\\\\\\ \\\\\\ prefix="/posts",# All routes automatically prefixed with /posts\\\\\\ \\\\\\ tags=# Swagger Grouping tag in documentation\\\\\\ \\\\\\ )\\\\\\ \\\\\\ @router.get("/{post_id}", response_model=PostResponse, name="post_detail")\\\\\\ \\\\\\ def post_detail(post_id: int, db: Session = Depends(get_db)):\\\\\\ \\\\\\ """Article Detail (JSON API)"""\\\\\\ \\\\\\ post = db.query(Post).filter(Post.id== post_id).first()\\\\\\ \\\\\\ if not post:\\\\\\ \\\\\\ raise HTTPException(status_code=Basic Query0Basic Query, detail="Post not found")\\\\\\ \\\\\\ return post\\\\\\ \\\\\\ Mount APIRouter in main.py:\\\\\\ \\\\\\ ## Example\\\\\\ \\\\\\ from routers.posts import router as posts_router\\\\\\ \\\\\\ from routers.categories import router as categories_router\\\\\\ \\\\\\ app.include_router(posts_router)\\\\\\ \\\\\\ app.include_router(categories_router)\\\\\\ \\\\\\ * * *\\\\\\ \\\\\\ ## Rendering the Article List Page\\\\\\ \\\\\\ ## Example\\\\\\ \\\\\\ # File path: routers/posts.py\\\\\\ \\\\\\ from fastapi import APIRouter, Depends, Request, Query\\\\\\ \\\\\\ from fastapi.templating import JinjaArticle List + Category FilterTemplates\\\\\\ \\\\\\ from sqlalchemy.orm import Session\\\\\\ \\\\\\ from database import get_db\\\\\\ \\\\\\ from models import Post, Category\\\\\\ \\\\\\ router = APIRouter()\\\\\\ \\\\\\ templates = JinjaArticle List + Category FilterTemplates(directory="templates")\\\\\\ \\\\\\ @router.get("/", name="index")\\\\\\ \\\\\\ def index(\\\\\\ \\\\\\ request: Request,\\\\\\ \\\\\\ category: str | None= Query(None),# Query parameter: optional\\\\\\ \\\\\\ db: Session = Depends(get_db)\\\\\\ \\\\\\ ):\\\\\\ \\\\\\ """Home:ArticleList + Category Filter"""\\\\\\ \\\\\\ # Basic Query\\\\\\ \\\\\\ posts_query = db.query(Post).order_by(Post.created_at.desc())\\\\\\ \\\\\\ # Category Filter\\\\\\ \\\\\\ if category:\\\\\\ \\\\\\ posts_query = posts_query.join(Category).filter(Category.slug== category)\\\\\\ \\\\\\ posts = posts_query.all()\\\\\\ \\\\\\ categories = db.query(Category).all()\\\\\\ \\\\\\ return templates.TemplateResponse("index.html",{\\\\\\ \\\\\\ "request": request,\\\\\\ \\\\\\ "posts": posts,\\\\\\ \\\\\\ "categories": categories,\\\\\\ \\\\\\ "category_slug": category or""\\\\\\ \\\\\\ })\\\\\\ \\\\\\ > `str | None = Query(None)` is Python Article Details (JSON API).Category Filter0+ type union syntax, equivalent to `Optional`. FastAPI will automatically: Category Filter. Make the parameter optional; Article List + Category Filter. Mark it as optional in the Swagger documentation; Article Details (JSON API). Not throw an error when not passed.\\\\\\ \\\\\\ * * *\\\\\\ \\\\\\ ## Rendering the Article Detail Page\\\\\\ \\\\\\ ## Example\\\\\\ \\\\\\ # File path: routers/posts.py Append\\\\\\ \\\\\\ @router.get("/post/{post_id}", name="post_detail")\\\\\\ \\\\\\ def post_detail(request: Request, post_id: int, db: Session = Depends(get_db)):\\\\\\ \\\\\\ """Article Detail Page"""\\\\\\ \\\\\\ post = db.query(Post).filter(Post.id== post_id).first()\\\\\\ \\\\\\ if not post:\\\\\\ \\\\\\ raise HTTPException(status_code=Basic Query0Basic Query, detail="Post not found")\\\\\\ \\\\\\ return templates.TemplateResponse("post_detail.html",{\\\\\\ \\\\\\ "request": request,\\\\\\ \\\\\\ "post": post\\\\\\ \\\\\\ })\\\\\\ \\\\\\ > Note the distinction: The same route can provide both JSON API (declaring response_model) and HTML page (returning TemplateResponse). The common practice is: API routes are placed under /api/ prefix, page routes are placed under the root path.\\\\\\ \\\\\\ * * *\\\\\\ \\\\\\ ## Creating Homepage and Detail Page Templates\\\\\\ \\\\\\ ## Example\\\\\\ \\\\\\ \\\\\\ \\\\\\ {% extends 'base.html' %}\\\\\\ \\\\\\ {% block title %}TUTORIAL Home - Home{% endblock %}\\\\\\ \\\\\\ {% block content %}\\\\\\ \\\\\\ Latest Posts\\\\\\ \\\\\\
\\\\\\ \\\\\\ All\\\\\\ \\\\\\ {% for cat in categories %}\\\\\\ \\\\\\ \\\\\\ \\\\\\ {{ cat.name }}\\\\\\ \\\\\\ \\\\\\ \\\\\\ {% endfor %}\\\\\\ \\\\\\
\\\\\\ \\\\\\ {% if posts %}\\\\\\ \\\\\\
\\\\\\ \\\\\\ {% for post in posts %}\\\\\\ \\\\\\ \\\\\\ \\\\\\
\\\\\\ \\\\\\
\\\\\\ \\\\\\ {{ post.category.name }}\\\\\\ \\\\\\ {{ post.title }}\\\\\\ \\\\\\

{{ post.summary|truncate(Grouping tag in documentation0) }}

\\\\\\ \\\\\\ {{ post.created_at.strftime('%Y-%m-%d') }}\\\\\\ \\\\\\
\\\\\\ \\\\\\
\\\\\\ \\\\\\
\\\\\\ \\\\\\ {% endfor %}\\\\\\ \\\\\\
\\\\\\ \\\\\\ {% else %}\\\\\\ \\\\\\

No articles in this category yet.

\\\\\\ \\\\\\ {% endif %}\\\\\\ \\\\\\ {% endblock %}\\\\\\ \\\\\\ ## Example\\\\\\ \\\\\\ \\\\\\ \\\\\\ {% extends 'base.html' %}\\\\\\ \\\\\\ {% block title %}{{ post.title }} - TUTORIAL Home{% endblock %}\\\\\\ \\\\\\ {% block content %}\\\\\\ \\\\\\
\\\\\\ \\\\\\ {{ post.category.name }}\\\\\\ \\\\\\ {{ post.title }}\\\\\\ \\\\\\ \\\\\\ \\\\\\
{{ post.content|safe }}
\\\\\\ \\\\\\ ← Return Home\\\\\\ \\\\\\
\\\\\\ \\\\\\ {% endblock %}\\\\\\ \\\\\\ * * *\\\\\\ \\\\\\ ## Chapter Summary\\\\\\ \\\\\\ In this chapter, you completed the core route development for FastAPI: APIRouter splits routes by module (prefix + tags), query parameters are declared using Query() + type hints, TemplateResponse renders pages, and Basic Query0Basic Query exception handling.\\\\\\ \\\\\\ The blog now has three complete pages: homepage article list, category filtering, and detail page.
← Fastapi Blog Search PaginationFastapi Blog Sqlalchemy β†’