你的第一个博客-第一弹

使用 Flask 开发博客

Flask 是一个轻量级的 Web 框架,适合小型应用和学习项目。我们将通过 Flask 开发一个简单的博客系统,支持用户注册、登录、发布文章等功能。

步骤:
  1. 安装 Flask 和其他必要库:

    在开发博客之前,首先需要安装 Flask。可以使用 pip 安装 Flask 和其他依赖:

    bash 复制代码
    pip install Flask Flask-SQLAlchemy Flask-WTF Flask-Login email-validator 
  2. 项目结构:

    项目结构如下:

    /blog
        /templates
            base.html
            create_post.html
            edit_post.html
            index.html
            layout.html
            login.html
            register.html
            post.html
        /static
            /css
                style.css
        app.py
        models.py
        forms.py
    
  3. 创建数据库模型 (models.py):

    使用 Flask 的 SQLAlchemy 扩展来进行数据库操作。我们首先定义用户和文章的数据库模型。

python 复制代码
# models.py
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime  # 导入 datetime
from flask_login import UserMixin

db = SQLAlchemy()

class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(80), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    password = db.Column(db.String(120), nullable=False)
    date_registered = db.Column(db.DateTime, default=datetime.utcnow)
    is_active = db.Column(db.Boolean, default=True)  # 默认值设置为True,表示用户激活

    def get_id(self):
        return str(self.id)  # 或者返回其他唯一标识符,如 email 等
    posts = db.relationship('Post', back_populates='user', 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)
    
    # 修改 backref 名称,避免与 User 模型中的属性冲突
    user = db.relationship('User', back_populates='posts')
    def __init__(self, title, content, user):
        self.title = title
        self.content = content
        self.user = user  # author 参数应该作为 user
  1. 创建 Flask 应用 (app.py):

    app.py 中初始化 Flask 应用,配置数据库,处理用户请求和路由。

python 复制代码
# app.py
from flask import Flask, render_template, url_for, redirect, request, flash
from models import db, User, Post
from flask_login import LoginManager, login_user, login_required, current_user, logout_user
from forms import RegistrationForm, LoginForm, PostForm
from datetime import datetime

app = Flask(__name__)
app.config['SECRET_KEY'] = '123456'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///site.db'
db.init_app(app)

with app.app_context():
    db.create_all()  # 创建数据库表

login_manager = LoginManager(app)
login_manager.login_view = 'login'

@login_manager.user_loader
def load_user(user_id):
    return db.session.get(User, int(user_id))

@app.route('/')
def index():
    posts = Post.query.all()
    print(current_user.is_authenticated)
    return render_template('index.html', posts=posts)

@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()
        flash('Your account has been created!', 'success')
        return redirect(url_for('login'))
    return render_template('register.html', form=form)

@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        user = User.query.filter_by(username=form.username.data).first()
        if user and user.password == form.password.data:
            login_user(user)
            return redirect(url_for('index'))
        else:
            flash('Login Unsuccessful. Please check username and password', 'danger')
    return render_template('login.html', form=form)

@app.route('/logout')
def logout():
    logout_user()
    return redirect(url_for('index'))

@app.route('/post/new', methods=['GET', 'POST'])
@login_required
def new_post():
    form = PostForm()
    if form.validate_on_submit():
        post = Post(title=form.title.data, content=form.content.data, user=current_user)
        db.session.add(post)
        db.session.commit()
        flash('Your post has been created!', 'success')
        return redirect(url_for('index'))
    return render_template('create_post.html', title='New Post', 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)

@app.route('/post/edit/<int:post_id>', methods=['GET', 'POST'])
@login_required
def edit_post(post_id):
    post = Post.query.get_or_404(post_id)
    
    # 确保只能编辑自己的博客
    if post.user != current_user:
        flash('You cannot edit this post.', 'danger')
        return redirect(url_for('index'))

    form = PostForm()

    if form.validate_on_submit():
        post.title = form.title.data
        post.content = form.content.data
        db.session.commit()

        flash('Your post has been updated!', 'success')
        return redirect(url_for('index'))

    # 使用现有的博客数据填充表单
    elif request.method == 'GET':
        form.title.data = post.title
        form.content.data = post.content

    return render_template('edit_post.html', title='Edit Post', form=form, post=post)

@app.route("/post/delete/<int:post_id>", methods=["Get", `"POST"])
def delete_post(post_id):
    post = Post.query.get_or_404(post_id)
    db.session.delete(post)
    db.session.commit()
    flash("Post has been deleted!", "success")
    return redirect(url_for('index'))  # 或者返回其他页面


if __name__ == '__main__':
    app.run(debug=True)
  1. 创建表单 (forms.py):

    使用 Flask-WTF 扩展来创建用户注册、登录和文章发布的表单。

python 复制代码
# forms.py
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, TextAreaField
from wtforms.validators import DataRequired, Length, Email, EqualTo

class RegistrationForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired(), Length(min=2, max=20)])
    email = StringField('Email', validators=[DataRequired(), Email()])
    password = PasswordField('Password', validators=[DataRequired()])
    confirm_password = PasswordField('Confirm Password', validators=[DataRequired(), EqualTo('password')])

class LoginForm(FlaskForm):
    username = StringField('Username', validators=[DataRequired()])
    password = PasswordField('Password', validators=[DataRequired()])

class PostForm(FlaskForm):
    title = StringField('Title', validators=[DataRequired()])
    content = TextAreaField('Content', validators=[DataRequired()])
  1. 创建模板 (HTML):

    templates 文件夹中,创建 HTML 模板来展示博客页面。

    html 复制代码
    <!-- index.html -->
    {% extends 'base.html' %}
    {% block content %}
    <h1>Blog Posts</h1>
    <ul>
        {% for post in posts %}
        <li>
            <h2>{{ post.title }}</h2>
            <p>{{ post.content }}</p>
            <p><small>Posted on {{ post.date_posted }}</small></p>
        </li>
        {% endfor %}
    </ul>
    {% endblock %}
  2. 运行应用:

    启动 Flask 应用:

    bash 复制代码
    python app.py

展示效果

上面最简单的博客就搭建完成了,但博主怎么能止步于此呢,进一步实现相关的html页面来进一步完善吧,尽请期待第二弹。

文学和科学相比,的确没什么用处,但文学最大的用处,也许就是它没有用处

相关推荐
深度学习lover1 小时前
[项目代码] YOLOv8 遥感航拍飞机和船舶识别 [目标检测]
python·yolo·目标检测·计算机视觉·遥感航拍飞机和船舶识别
水木流年追梦2 小时前
【python因果库实战10】为何需要因果分析
开发语言·python
m0_675988233 小时前
Leetcode2545:根据第 K 场考试的分数排序
python·算法·leetcode
凡人的AI工具箱5 小时前
每天40分玩转Django:Django测试
数据库·人工智能·后端·python·django·sqlite
qyq15 小时前
Django框架与ORM框架
后端·python·django
企业软文推广5 小时前
企业如何选择媒体发稿平台及相关事项?媒介盒子分享
python
No0d1es6 小时前
GESP CCF python二级编程等级考试认证真题 2024年12月
开发语言·python·青少年编程·gesp·ccf·二级
大霞上仙6 小时前
selenium 在已打开浏览器上继续调试
python·selenium·测试工具
CodeClimb6 小时前
【华为OD-E卷-开心消消乐 100分(python、java、c++、js、c)】
java·python·华为od