构建简单的 Flask 博客系统 – 完整的 Flask 开发教程
博客系统是一个经典的 Flask 项目,涉及到很多常见的 Web 开发功能,如用户认证、数据库操作、表单处理等。接下来,我们将分步骤实现一个简单的博客系统,包含以下核心功能:
项目功能
- 用户注册、登录、注销
- 发布、编辑、删除文章
- 评论功能
- 显示所有博客文章
步骤一:环境搭建
首先,你需要创建一个虚拟环境来管理项目的依赖。
- 创建虚拟环境:
python -m venv venv
- 激活虚拟环境:
- Windows:
venv\Scripts\activate - macOS/Linux:
source venv/bin/activate
- 安装 Flask 和必要的扩展:
pip install flask flask-sqlalchemy flask-wtf flask-login
步骤二:项目结构
创建以下的项目文件结构:
/blog
/static
/css
/images
/templates
base.html
index.html
login.html
register.html
post.html
app.py
config.py
app.py:主要的应用代码config.py:配置文件/templates:HTML 模板文件/static:静态文件(例如 CSS、图片等)
步骤三:创建 Flask 应用
首先,在 app.py 中设置 Flask 应用的基本框架。
1. 配置文件 (config.py):
import os
class Config:
SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess'
SQLALCHEMY_DATABASE_URI = 'sqlite:///blog.db'
SQLALCHEMY_TRACK_MODIFICATIONS = False
2. 创建应用实例 (app.py):
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_wtf import FlaskForm
from flask_login import LoginManager
app = Flask(__name__)
app.config.from_object('config.Config')
db = SQLAlchemy(app)
login_manager = LoginManager(app)
login_manager.login_view = 'login' # 设置未登录时跳转到 login 页面
from app import routes # 在 routes.py 中定义路由
步骤四:创建数据库模型
在 app.py 中定义数据库模型(用户、文章和评论)。
from datetime import datetime
from flask_login import UserMixin
# 用户模型
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(120), unique=True, nullable=False)
email = db.Column(db.String(120), unique=True, nullable=False)
password = db.Column(db.String(60), nullable=False)
posts = db.relationship('Post', backref='author', lazy=True) # 一对多关系
# 文章模型
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(100), nullable=False)
content = db.Column(db.Text, nullable=False)
date_posted = db.Column(db.DateTime, default=datetime.utcnow)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
# 评论模型
class Comment(db.Model):
id = db.Column(db.Integer, primary_key=True)
content = db.Column(db.Text, nullable=False)
post_id = db.Column(db.Integer, db.ForeignKey('post.id'), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
post = db.relationship('Post', backref=db.backref('comments', lazy=True)) # 一对多关系
步骤五:创建表单类
使用 Flask-WTF 来处理表单验证。
1. 用户注册表单 (forms.py):
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Email, Length
class RegistrationForm(FlaskForm):
username = StringField('Username', validators=[DataRequired(), Length(min=2, max=20)])
email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password', validators=[DataRequired()])
submit = SubmitField('Sign Up')
2. 用户登录表单 (forms.py):
class LoginForm(FlaskForm):
email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password', validators=[DataRequired()])
submit = SubmitField('Log In')
3. 发布文章表单 (forms.py):
class PostForm(FlaskForm):
title = StringField('Title', validators=[DataRequired()])
content = StringField('Content', validators=[DataRequired()])
submit = SubmitField('Post')
步骤六:路由和视图函数
在 routes.py 文件中定义路由,处理不同的请求。
1. 主页路由:显示所有文章
from flask import render_template
from app import app
from app import db
from app.models import Post
@app.route('/')
def home():
posts = Post.query.all()
return render_template('index.html', posts=posts)
2. 注册路由:
from flask import render_template, url_for, redirect
from flask_login import login_user
from app import app
from app.models import User
from app.forms import RegistrationForm
from app import db
@app.route("/register", methods=['GET', 'POST'])
def register():
form = RegistrationForm()
if form.validate_on_submit():
user = User(username=form.username.data, email=form.email.data, password=form.password.data)
db.session.add(user)
db.session.commit()
login_user(user)
return redirect(url_for('home'))
return render_template('register.html', form=form)
3. 登录路由:
from flask import render_template, redirect, url_for
from flask_login import login_user
from app import app
from app.models import User
from app.forms import LoginForm
@app.route("/login", methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = User.query.filter_by(email=form.email.data).first()
if user and user.password == form.password.data:
login_user(user)
return redirect(url_for('home'))
return render_template('login.html', form=form)
4. 发布文章路由:
from flask import render_template, redirect, url_for
from flask_login import current_user
from app import app
from app.models import Post
from app.forms import PostForm
from app import db
@app.route("/post/new", methods=['GET', 'POST'])
def new_post():
form = PostForm()
if form.validate_on_submit():
post = Post(title=form.title.data, content=form.content.data, author=current_user)
db.session.add(post)
db.session.commit()
return redirect(url_for('home'))
return render_template('post.html', form=form)
步骤七:前端模板
在 templates 文件夹下创建 HTML 模板。
1. 基础模板 (base.html):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Flask Blog</title>
</head>
<body>
<nav>
<a href="{{ url_for('home') }}">Home</a>
<a href="{{ url_for('register') }}">Register</a>
<a href="{{ url_for('login') }}">Login</a>
<a href="{{ url_for('new_post') }}">New Post</a>
</nav>
<div>
{% block content %}{% endblock %}
</div>
</body>
</html>
2. 首页模板 (index.html):
{% extends 'base.html' %}
{% block content %}
<h1>All Posts</h1>
{% for post in posts %}
<div>
<h2>{{ post.title }}</h2>
<p>{{ post.content }}</p>
<p>By {{ post.author.username }} on {{ post.date_posted }}</p>
</div>
{% endfor %}
{% endblock %}
步骤八:运行应用
确保你已经创建了数据库并运行了迁移:
python
>>> from app import db
>>> db.create_all()
然后,你可以通过以下命令启动 Flask 开发服务器:
flask run
结语
这是一个简单的博客系统示例,涵盖了用户认证、文章发布和基础的路由处理。你可以根据自己的需求添加更多功能,例如评论功能、文章编辑与删除、分页、搜索功能等。