YouTip LogoYouTip

Flask Blog Views Blueprint

## View Functions β€” Rendering Article List and Detail Pages In this chapter, you will learn how to use view functions to query data from the database, render the homepage and detail pages, and use Blueprint to split routes. * * * ## Responsibilities of View Functions The responsibilities of Flask view functions are consistent with Django: receive request β†’ query data β†’ render template. ## Example # File path: app.py from flask import Flask, render_template from models import Post, Category @app.route("/") def index(): """Blog homepage: display all articles""" posts = Post.query.order_by(Post.created_at.desc()).all() categories = Category.query.all() return render_template('index.html', posts=posts, categories=categories) * * * ## Path Parameters and Query Parameters | Parameter Type | URL Example | How View Gets It | | --- | --- | --- | | Path Parameter | /post/3 | in route β†’ function parameter | | Query Parameter | /?category=python | request.args.get('key') | Flask route supports multiple type converters: `` (integer), `` (default, does not include /), `` (includes /), ``, etc. * * * ## Article Detail Page ## Example # File path: app.py append from flask import abort @app.route("/post/") def post_detail(post_id): """Article detail page""" # get_or_404 is equivalent to: Post.query.get(post_id) or abort(404) post = Post.query.get_or_404(post_id, description=f'Article #{post_id} does not exist') return render_template('post_detail.html', post=post) ### Custom 404 Error Page ## Example @app.errorhandler(404) def not_found(error): return render_template('404.html'),404 * * * ## Category Filtering ## Example # File path: app.py modify index view from flask import request @app.route("/") def index(): category_slug = request.args.get('category','') keyword= request.args.get('q','')# Search keyword (implemented in Chapter 6) posts_query = Post.query.order_by(Post.created_at.desc()) # Filter by category if category_slug: posts_query = posts_query.join(Category).filter(Category.slug== category_slug) posts = posts_query.all() categories = Category.query.all() return render_template('index.html', posts=posts, categories=categories, category_slug=category_slug,keyword=keyword) > `request.args` is an immutable MultiDict used to read URL query parameters. Use `.get('key', 'default value')` to get it safely, which returns the default value instead of throwing an error when the parameter doesn't exist. * * * ## Blueprint β€” Splitting Routes When view functions increase, piling them all in app.py will get out of control. Blueprint is Flask's route grouping solution: split views by functional module, register through app.register_blueprint(). app/β”œβ”€β”€ blueprints/β”‚ β”œβ”€β”€ __init__.py β”‚ β”œβ”€β”€ main.py # Homepage, about, searchβ”‚ └── posts.py # Article list, detailβ”œβ”€β”€ templates/β”œβ”€β”€ models.py └── __init__.py ## Example # File path: app/blueprints/main.py from flask import Blueprint, render_template, request from app.models import Post, Category # Blueprint('blueprint_name', __name__, url_prefix='/') main_bp = Blueprint('main', __name__) @main_bp.route("/") def index(): """Blog homepage""" category_slug = request.args.get('category','') posts_query = Post.query.order_by(Post.created_at.desc()) if category_slug: posts_query = posts_query.join(Category).filter(Category.slug== category_slug) return render_template('index.html', posts=posts_query.all(), categories=Category.query.all(), category_slug=category_slug) ## Example # File path: app/blueprints/posts.py from flask import Blueprint, render_template, abort from app.models import Post posts_bp = Blueprint('posts', __name__) @posts_bp.route("/post/") def post_detail(post_id): post = Post.query.get_or_404(post_id) return render_template('post_detail.html', post=post) Register Blueprint in the application entry: ## Example # File path: app.py from flask import Flask from app.blueprints.main import main_bp from app.blueprints.posts import posts_bp app = Flask( __name__ ) # Register blueprint: all blueprint view functions will be merged into the same application app.register_blueprint(main_bp) app.register_blueprint(posts_bp) > Blueprint can specify `url_prefix` (e.g., `url_prefix='/blog'`), then all routes within the blueprint will automatically get this prefix. Blueprint can also have its own template and static file directories. * * * ## Creating Homepage and Detail Page Templates ### index.html ## Example {% extends 'base.html' %} {% block title %}TUTORIAL Blog - Homepage{% endblock %} {% block content %}

Latest Articles

All {% for cat in categories %} {{ cat.name }} {% endfor %}
{% if posts %}
{% for post in posts %}
{{ post.category.name }}

{{ post.title }}

{{ post.summary|truncate(80) }}

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

No articles in this category yet.

{% endif %} {% endblock %} > When using Blueprint views in url_for(), the format is `url_for('blueprint_name.function_name')`, e.g., `url_for('posts.post_detail',
← Flask Blog Search PaginationFlask Blog Jinja2 Templates β†’