基于Python的Web应用开发:构建一个简单的Flask博客系统

前天 9阅读

随着互联网技术的发展,Web应用已经成为现代软件开发的重要组成部分。Python作为一种简洁、高效的编程语言,在Web开发领域也占据了重要地位。本文将介绍如何使用Python中的Flask框架来构建一个简单的博客系统。我们将从环境搭建开始,逐步实现用户注册、文章发布、文章展示等基本功能,并在文中嵌入完整的代码示例。


项目概述

本博客系统将包括以下核心功能:

用户注册与登录发布新文章查看所有文章查看单篇文章详情

项目采用前后端分离的基本结构,后端使用Flask框架,数据库使用SQLite(适合初学者和轻量级应用),前端使用HTML+CSS+Bootstrap进行简单渲染。


环境准备

安装依赖

首先确保你已经安装了 Python 和 pip,然后通过 pip 安装 Flask 和 SQLAlchemy:

pip install flask flask-sqlalchemy flask-wtf

我们还将使用 Flask-WTF 来处理表单验证。


项目结构

本项目的目录结构如下:

flask_blog/├── app.py├── config.py├── models.py├── forms.py├── templates/│   ├── base.html│   ├── index.html│   ├── post.html│   └── register.html└── instance/    └── blog.db

配置文件(config.py)

创建 config.py 文件用于存储配置信息:

import osclass Config:    SECRET_KEY = os.environ.get('SECRET_KEY') or 'you-will-never-guess'    SQLALCHEMY_DATABASE_URI = 'sqlite:///blog.db'    SQLALCHEMY_TRACK_MODIFICATIONS = False

模型定义(models.py)

使用 SQLAlchemy 定义两个模型:用户和文章。

from flask_sqlalchemy import SQLAlchemyfrom datetime import datetimefrom flask_login import UserMixindb = SQLAlchemy()class User(UserMixin, db.Model):    id = db.Column(db.Integer, primary_key=True)    username = db.Column(db.String(80), unique=True, nullable=False)    password = db.Column(db.String(120), 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(120), 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)

表单类(forms.py)

使用 Flask-WTF 创建注册和发布文章的表单。

from flask_wtf import FlaskFormfrom wtforms import StringField, PasswordField, TextAreaField, SubmitFieldfrom wtforms.validators import DataRequired, Lengthclass RegisterForm(FlaskForm):    username = StringField("用户名", validators=[DataRequired(), Length(min=3, max=20)])    password = PasswordField("密码", validators=[DataRequired()])    submit = SubmitField("注册")class PostForm(FlaskForm):    title = StringField("标题", validators=[DataRequired()])    content = TextAreaField("内容", validators=[DataRequired()])    submit = SubmitField("发布")

主程序(app.py)

这是整个应用的核心逻辑。

from flask import Flask, render_template, redirect, url_for, request, flashfrom flask_login import LoginManager, login_user, logout_user, login_required, current_userfrom models import db, User, Postfrom forms import RegisterForm, PostFormimport configapp = Flask(__name__)app.config.from_object(config.Config)db.init_app(app)login_manager = LoginManager()login_manager.init_app(app)login_manager.login_view = "login"@login_manager.user_loaderdef load_user(user_id):    return User.query.get(int(user_id))@app.route("/")def index():    posts = Post.query.order_by(Post.date_posted.desc()).all()    return render_template("index.html", posts=posts)@app.route("/register", methods=["GET", "POST"])def register():    form = RegisterForm()    if form.validate_on_submit():        new_user = User(username=form.username.data, password=form.password.data)        db.session.add(new_user)        db.session.commit()        flash("注册成功,请登录!")        return redirect(url_for("login"))    return render_template("register.html", form=form)@app.route("/login", methods=["GET", "POST"])def login():    if request.method == "POST":        username = request.form["username"]        password = request.form["password"]        user = User.query.filter_by(username=username).first()        if user and user.password == password:            login_user(user)            return redirect(url_for("index"))        else:            flash("用户名或密码错误")    return render_template("login.html")@app.route("/logout")@login_requireddef logout():    logout_user()    return redirect(url_for("index"))@app.route("/post/new", methods=["GET", "POST"])@login_requireddef 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()        flash("文章发布成功!")        return redirect(url_for("index"))    return render_template("new_post.html", form=form)@app.route("/post/<int:post_id>")def post(post_id):    post = Post.query.get_or_404(post_id)    return render_template("post.html", post=post)if __name__ == "__main__":    with app.app_context():        db.create_all()    app.run(debug=True)

模板文件(templates/)

base.html(基础布局)

<!DOCTYPE html><html lang="zh-CN"><head>    <meta charset="UTF-8">    <title>{% block title %}{% endblock %}</title>    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"></head><body><nav class="navbar navbar-expand-lg navbar-light bg-light mb-4">    <div class="container-fluid">        <a class="navbar-brand" href="{{ url_for('index') }}">我的博客</a>        <div class="collapse navbar-collapse">            <ul class="navbar-nav me-auto">                {% if current_user.is_authenticated %}                    <li class="nav-item"><a class="nav-link" href="{{ url_for('new_post') }}">发布文章</a></li>                    <li class="nav-item"><a class="nav-link" href="{{ url_for('logout') }}">登出</a></li>                {% else %}                    <li class="nav-item"><a class="nav-link" href="{{ url_for('login') }}">登录</a></li>                    <li class="nav-item"><a class="nav-link" href="{{ url_for('register') }}">注册</a></li>                {% endif %}            </ul>        </div>    </div></nav><div class="container">    {% with messages = get_flashed_messages() %}        {% if messages %}            {% for message in messages %}                <div class="alert alert-info">{{ message }}</div>            {% endfor %}        {% endif %}    {% endwith %}    {% block content %}{% endblock %}</div><script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js"></script></body></html>

index.html(主页)

{% extends "base.html" %}{% block title %}首页 - 我的博客{% endblock %}{% block content %}<h1>欢迎来到我的博客</h1><hr>{% for post in posts %}<div class="card mb-3">    <div class="card-body">        <h5 class="card-title"><a href="{{ url_for('post', post_id=post.id) }}">{{ post.title }}</a></h5>        <p class="card-text">{{ post.content[:100] }}...</p>        <p class="text-muted">作者:{{ post.author.username }} | 时间:{{ post.date_posted.strftime('%Y-%m-%d') }}</p>    </div></div>{% endfor %}{% endblock %}

post.html(文章详情页)

{% extends "base.html" %}{% block title %}{{ post.title }} - 我的博客{% endblock %}{% block content %}<h1>{{ post.title }}</h1><p>{{ post.content }}</p><p class="text-muted">作者:{{ post.author.username }} | 时间:{{ post.date_posted.strftime('%Y-%m-%d') }}</p><a href="{{ url_for('index') }}" class="btn btn-primary">返回首页</a>{% endblock %}

register.html(注册页面)

{% extends "base.html" %}{% block title %}注册 - 我的博客{% endblock %}{% block content %}<h3>注册</h3><form method="POST">    {{ form.hidden_tag() }}    <div class="mb-3">        {{ form.username.label }} {{ form.username(class="form-control") }}    </div>    <div class="mb-3">        {{ form.password.label }} {{ form.password(class="form-control") }}    </div>    <div class="mb-3">        {{ form.submit(class="btn btn-primary") }}    </div></form>{% endblock %}

运行项目

进入项目根目录,运行以下命令启动服务器:

python app.py

访问 http://127.0.0.1:5000,即可看到博客首页。


十、总结

本文通过构建一个简单的博客系统,介绍了如何使用 Flask 框架进行 Web 开发。我们实现了用户注册、登录、文章发布与展示等基本功能,并展示了如何结合 HTML 模板和数据库操作来构建完整的 Web 应用。

当然,该博客系统还非常基础,后续可以扩展的功能包括:

使用加密保存密码(如使用 werkzeug.security)添加评论功能分页显示文章列表实现 RESTful API 接口部署到生产环境(如使用 Gunicorn + Nginx)

希望本文能为初学者提供一个清晰的 Flask Web 开发入门路径。

免责声明:本文来自网站作者,不代表CIUIC的观点和立场,本站所发布的一切资源仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。客服邮箱:ciuic@ciuic.com

目录[+]

您是本站第1138名访客 今日有13篇新文章

微信号复制成功

打开微信,点击右上角"+"号,添加朋友,粘贴微信号,搜索即可!