一、準備工作:安裝必要工具和庫¶
在開始前,確保你已經安裝了Python(推薦3.6+版本)。打開終端,執行以下命令安裝Flask及相關擴展:
pip install flask flask-sqlalchemy flask-login flask-wtf flask-bootstrap
- Flask:核心Web框架
- Flask-SQLAlchemy:ORM工具,簡化數據庫操作
- Flask-Login:用戶認證管理
- Flask-WTF:表單處理與驗證
- Flask-Bootstrap:快速美化頁面(基於Bootstrap)
二、項目初始化:搭建目錄結構¶
創建博客項目文件夾,並按以下結構組織文件:
blog_project/
├── app.py # 主程序入口
├── config.py # 配置文件(可選,本教程簡化)
├── models.py # 數據庫模型定義
├── templates/ # HTML模板文件
│ ├── base.html # 基礎模板(導航、頁腳等)
│ ├── index.html # 首頁
│ ├── post_detail.html # 文章詳情頁
│ └── create_post.html # 寫文章頁面
└── static/ # 靜態資源(CSS、JS等)
三、數據庫設計:定義數據模型¶
在models.py中定義用戶和文章的數據庫模型:
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
from werkzeug.security import generate_password_hash, check_password_hash
db = SQLAlchemy() # 初始化SQLAlchemy
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(50), unique=True, nullable=False)
password_hash = db.Column(db.String(128), nullable=False)
# 關聯文章(一個用戶可寫多篇文章)
posts = db.relationship('Post', backref='author', lazy=True)
# 密碼加密存儲
def set_password(self, password):
self.password_hash = generate_password_hash(password)
# 驗證密碼
def check_password(self, password):
return check_password_hash(self.password_hash, password)
class Post(db.Model):
id = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(200), nullable=False)
content = db.Column(db.Text, nullable=False)
timestamp = db.Column(db.DateTime, default=datetime.utcnow)
author_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) # 外鍵關聯用戶
四、應用初始化:配置與核心組件¶
在app.py中初始化Flask應用,配置數據庫和擴展:
from flask import Flask, render_template, redirect, url_for, request, flash
from flask_login import LoginManager, UserMixin, login_user, login_required, logout_user, current_user
from flask_wtf import FlaskForm
from wtforms import StringField, TextAreaField, SubmitField
from wtforms.validators import DataRequired
from models import db, User, Post
from flask_bootstrap import Bootstrap
# 初始化Flask應用
app = Flask(__name__)
app.config['SECRET_KEY'] = 'your-secret-key-here' # 用於加密會話(開發時用隨機字符串)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///blog.db' # SQLite數據庫
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # 關閉不必要的跟蹤
# 初始化擴展
db.init_app(app)
Bootstrap(app) # 啓用Bootstrap美化
# 初始化登錄管理
login_manager = LoginManager(app)
login_manager.login_view = 'login' # 未登錄時跳轉的頁面
# 用戶加載回調(Flask-Login必填)
@login_manager.user_loader
def load_user(user_id):
return User.query.get(int(user_id))
# 創建數據庫表(首次運行時執行)
with app.app_context():
db.create_all()
五、核心功能實現:路由與視圖¶
下面實現博客的核心功能:首頁文章列表、文章詳情、寫文章、用戶登錄。
1. 首頁:展示所有文章¶
在app.py中添加首頁路由:
@app.route('/')
def index():
# 查詢所有文章,按時間倒序排列
posts = Post.query.order_by(Post.timestamp.desc()).all()
return render_template('index.html', posts=posts)
2. 文章詳情頁:展示單篇文章¶
按文章ID查詢並展示單篇文章:
@app.route('/post/<int:post_id>')
def post_detail(post_id):
post = Post.query.get_or_404(post_id) # 若文章不存在返回404
return render_template('post_detail.html', post=post)
3. 寫文章:表單提交與保存¶
使用Flask-WTF定義文章表單,處理用戶輸入:
# 定義文章表單
class PostForm(FlaskForm):
title = StringField('標題', validators=[DataRequired()])
content = TextAreaField('內容', validators=[DataRequired()])
submit = SubmitField('發佈')
@app.route('/create', methods=['GET', 'POST'])
@login_required # 僅登錄用戶可訪問
def create_post():
form = PostForm()
if form.validate_on_submit():
# 創建新文章並關聯當前用戶
post = Post(
title=form.title.data,
content=form.content.data,
author_id=current_user.id # 作者爲當前登錄用戶
)
db.session.add(post)
db.session.commit()
flash('文章發佈成功!', 'success')
return redirect(url_for('index')) # 發佈後跳轉首頁
return render_template('create_post.html', form=form)
4. 用戶登錄與登出¶
使用Flask-Login實現用戶認證:
@app.route('/login', methods=['GET', 'POST'])
def login():
if current_user.is_authenticated: # 若已登錄,直接跳轉首頁
return redirect(url_for('index'))
form = LoginForm() # 需定義LoginForm(此處省略,代碼見下方)
if form.validate_on_submit():
user = User.query.filter_by(username=form.username.data).first()
if user and user.check_password(form.password.data):
login_user(user) # 登錄用戶
return redirect(url_for('index'))
else:
flash('用戶名或密碼錯誤', 'danger')
return render_template('login.html', form=form)
@app.route('/logout')
@login_required
def logout():
logout_user() # 登出用戶
flash('已成功登出', 'info')
return redirect(url_for('index'))
補充:LoginForm定義(在app.py中):
class LoginForm(FlaskForm):
username = StringField('用戶名', validators=[DataRequired()])
password = StringField('密碼', validators=[DataRequired()])
submit = SubmitField('登錄')
六、模板渲染:用Bootstrap美化頁面¶
創建templates/base.html作爲基礎模板,其他頁面繼承此模板:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>{% block title %}個人博客{% endblock %}</title>
<!-- 引入Bootstrap -->
{{ bootstrap.load_css() }}
</head>
<body>
<!-- 導航欄 -->
<nav class="navbar navbar-default">
<div class="container">
<a class="navbar-brand" href="{{ url_for('index') }}">我的博客</a>
<ul class="nav navbar-nav navbar-right">
<li><a href="{{ url_for('index') }}">首頁</a></li>
{% if current_user.is_authenticated %}
<li><a href="{{ url_for('create_post') }}">寫文章</a></li>
<li><a href="{{ url_for('logout') }}">登出</a></li>
{% else %}
<li><a href="{{ url_for('login') }}">登錄</a></li>
{% endif %}
</ul>
</div>
</nav>
<!-- 內容區域 -->
<div class="container">
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
{% for category, message in messages %}
<div class="alert alert-{{ category }}">{{ message }}</div>
{% endfor %}
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</div>
<!-- 頁腳 -->
<div class="navbar navbar-default navbar-fixed-bottom text-center">
<div class="container">
<p class="text-muted">© 2023 個人博客系統</p>
</div>
</div>
{{ bootstrap.load_js() }}
</body>
</html>
1. 首頁模板templates/index.html¶
{% extends "base.html" %}
{% block title %}首頁 - 我的博客{% endblock %}
{% block content %}
<h2 class="text-center">最新文章</h2>
{% for post in posts %}
<div class="panel panel-default">
<div class="panel-body">
<h3><a href="{{ url_for('post_detail', post_id=post.id) }}">{{ post.title }}</a></h3>
<p class="text-muted">作者: {{ post.author.username }} | 發佈時間: {{ post.timestamp.strftime('%Y-%m-%d %H:%M') }}</p>
<p>{{ post.content[:100] }}... <a href="{{ url_for('post_detail', post_id=post.id) }}">閱讀全文</a></p>
</div>
</div>
{% endfor %}
{% endblock %}
2. 文章詳情模板templates/post_detail.html¶
{% extends "base.html" %}
{% block title %}{{ post.title }} - 我的博客{% endblock %}
{% block content %}
<h2 class="text-center">{{ post.title }}</h2>
<p class="text-muted">作者: {{ post.author.username }} | 發佈時間: {{ post.timestamp.strftime('%Y-%m-%d %H:%M') }}</p>
<hr>
<div class="well">{{ post.content }}</div>
<a href="{{ url_for('index') }}" class="btn btn-primary">返回首頁</a>
{% endblock %}
3. 寫文章模板templates/create_post.html¶
{% extends "base.html" %}
{% import "bootstrap/wtf.html" as wtf %}
{% block title %}寫文章 - 我的博客{% endblock %}
{% block content %}
<div class="col-md-6 col-md-offset-3">
<h2>寫新文章</h2>
{{ wtf.quick_form(form, button_map={'submit': 'primary'}) }}
</div>
{% endblock %}
七、運行與測試¶
在終端執行以下命令啓動博客系統:
python app.py
訪問 http://127.0.0.1:5000 即可看到首頁。若需發佈文章,需先註冊(本教程簡化了註冊功能,可自行擴展)或直接修改數據庫添加用戶。
八、總結與擴展¶
本教程實現了博客系統的核心功能:
- 首頁展示文章列表
- 文章詳情頁
- 登錄用戶可發佈文章
- 頁面美化(Bootstrap)
可擴展方向:
1. 添加用戶註冊功能
2. 實現文章編輯/刪除
3. 評論系統
4. 分類與標籤功能
5. 文章搜索
通過這個項目,你將掌握Flask的基礎使用、數據庫操作、用戶認證和模板渲染,爲後續開發更復雜的Web應用打下基礎。