你的第一个博客-第一弹

使用 Flask 开发博客

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

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

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

    pip install Flask Flask-SQLAlchemy Flask-WTF Flask-Login email-validator 
    
  2. 项目结构:

    项目结构如下:

    /blog/templatesbase.htmlcreate_post.htmledit_post.htmlindex.htmllayout.htmllogin.htmlregister.htmlpost.html/static/cssstyle.cssapp.pymodels.pyforms.py
    
  3. 创建数据库模型 (models.py):

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

# models.py
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime  # 导入 datetime
from 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)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 = titleself.content = contentself.user = user  # author 参数应该作为 user
  1. 创建 Flask 应用 (app.py):

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

# 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 datetimeapp = 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.datapost.content = form.content.datadb.session.commit()flash('Your post has been updated!', 'success')return redirect(url_for('index'))# 使用现有的博客数据填充表单elif request.method == 'GET':form.title.data = post.titleform.content.data = post.contentreturn 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 扩展来创建用户注册、登录和文章发布的表单。

# forms.py
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, TextAreaField
from wtforms.validators import DataRequired, Length, Email, EqualToclass 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 模板来展示博客页面。

    <!-- 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 应用:

    python app.py
    

展示效果
在这里插入图片描述

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/890262.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LLaMA-Factory(一)环境配置及包下载

LLaMA-Factory(一&#xff09;环境配置及包下载 本机配置1. git下载2.创建虚拟环境3. 下载官方包内依赖4. 下载bitsandbytes5. 启动项目6. 可能出现问题1&#xff1a;pip install 出现 error: subprocess-exited-with-error 错误7. 可能出现问题2&#xff1a; ModuleNotFoundEr…

clickhouse-题库

1、clickhouse介绍以及架构 clickhouse一个分布式列式存储数据库&#xff0c;主要用于在线分析查询 2、列式存储和行式存储有什么区别&#xff1f; 行式存储&#xff1a; 1&#xff09;、数据是按行存储的 2&#xff09;、没有建立索引的查询消耗很大的IO 3&#xff09;、建…

计算机网络:运输层 —— TCP 的选择确认(SACK)

文章目录 TCP 的选择确认协商与启用工作机制接收方发送方 TCP 的选择确认 在 TCP 传输过程中&#xff0c;由于网络拥塞、链路故障等因素&#xff0c;数据可能会出现丢失或乱序的情况。传统的 TCP 确认机制是累积确认&#xff0c;TCP 接收方只能对按序收到的数据中的最高序号给…

HTML语法规范

HTML语法规则 HTML 标签是由尖括号包围的关键词&#xff0c;标签通常是成对出现的&#xff0c;例如 <html> 和 </html>&#xff0c;称为双标签 。标签对中的第一个标签是开始标签&#xff0c;第二个标签是结束标签单标签比较少&#xff0c;例如<br />&#x…

STL 剖析

STL 六大组件 「STL 六大组件的交互关系」 Container 通过 Allocator 取得数据储存空间Algorithm 通过 Iterator 存取 Container 内容Functor 可以协助 Algorithm 完成不同的策略变化Adapter 可以修饰或套接 Functor、Iterator 配置器(allocator) 配置器&#xff1a;负责空间…

Y3编辑器教程8:资源管理器与存档、防作弊设置

文章目录 一、资源管理器简介1.1 界面介绍1.2 资源商店1.3 AI专区1.3.1 AI文生图1.3.2 AI图生图1.3.3 立绘头像 二、导入导出2.1 文件格式2.2 模型导入2.2.1 模型制作后导出2.2.2 模型文件导入Y3编辑器2.2.3 Y3编辑器角色、装饰物模型要求 2.3 纹理导入2.4 材质贴图2.4.1 材质支…

DL作业11 LSTM

习题6-4 推导LSTM网络中参数的梯度&#xff0c; 并分析其避免梯度消失的效果 LSTM&#xff08;长短期记忆网络&#xff09;是一种特殊的循环神经网络&#xff08;RNN&#xff09;&#xff0c;旨在解决普通 RNN 在处理长序列时遇到的梯度消失和梯度爆炸问题。它通过设计多个门…

面试题整理9----谈谈对k8s的理解1

谈谈对k8s的理解 1. Kubernetes 概念 1.1 Kubernetes是什么 Kubernetes 是一个可移植、可扩展的开源平台&#xff0c;用于管理容器化的工作负载和服务&#xff0c;方便进行声明式配置和自动化。Kubernetes 拥有一个庞大且快速增长的生态系统&#xff0c;其服务、支持和工具的…

解决MySQL安装难题:vcruntime140_1.dll文件丢失修复指南

在安装MySQL的过程中&#xff0c;用户可能会遇到一个常见的问题&#xff1a;“找不到vcruntime140_1.dll&#xff0c;无法继续执行代码”。这个错误提示表明系统缺少一个关键的动态链接库文件&#xff0c;这对于运行依赖于它的应用程序至关重要。本文将详细介绍vcruntime140_1.…

【前后端】HTTP网络传输协议

近期更新完毕&#xff0c;建议关注、收藏&#xff01; http请求 URL 严格意义上应该是URI http or https http不加密不安全&#xff1b;https加密协议&#xff08;公网使用&#xff09; http端口号80 https端口号443GET or POST GET和POST是HTTP请求的两种基本方法. 因为POST需…

多线程 - 自旋锁

个人主页&#xff1a;C忠实粉丝 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 C忠实粉丝 原创 多线程 - 自旋锁 收录于专栏[Linux学习] 本专栏旨在分享学习Linux的一点学习笔记&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 概述 原理 优点与…

thinkphp5验证码captcha无法显示

排查思路 是否开启gd2以及gd2排查bom排查代码清除缓存 开启gd/gd2 找到php.ini 开启dg2库 去掉前面的;注释&#xff0c;有的可能会带.dll后缀影响不大 然后通过生成图片验证是否成功 查看是否存在bom 修改为utf-8即可&#xff0c;如果你的代码携带bom也需要排查一下 代码问…

Flutter组件————FloatingActionButton

FloatingActionButton 是Flutter中的一个组件&#xff0c;通常用于显示一个圆形的按钮&#xff0c;它悬浮在内容之上&#xff0c;旨在吸引用户的注意力&#xff0c;并代表屏幕上的主要动作。这种按钮是Material Design的一部分&#xff0c;通常放置在页面的右下角&#xff0c;但…

#{ }和${ } 、参数处理

目录 #{ }和${ } 参数处理 入参-parameterType 使用Map 使用Bean / List<Bean> 使用多参数 Param注解&#xff08;命名参数&#xff09; 出参-resultType 返回Map / List<Map> 返回Map<String,Map> 属性名不一致-resultMap结果映射 #{ }和${ }…

MySQL数据库——门诊管理系统数据库数据表

门诊系统数据库his 使用图形化工具或SQL语句在简明门诊管理系统数据库his中创建数据表&#xff0c;数据表结构见表2-3-9&#xff5e;表2-3-15所示。 表2-3-9 department&#xff08;科室信息表&#xff09; 字段名称 数据类型 长度 是否为空 说明 dep_ID int 否 科室…

Gin-vue-admin(4):项目创建前端一级页面和二级页面

目录 创建一级页面创建二级页面 创建一级页面 view目录下新建一个my&#xff0c;Index.vue <template></template><script> export default {name:My, } </script><script setup> import {ref} from vue const myNameref("name") &…

ABAP SQL 取日期+时间最新的一条数据

我们在系统对接的时候&#xff0c;外部系统可能会推送多个数据给到我们。 我们 SAP 系统的表数据中日期和时间是作为主键的&#xff0c;那么如果通过 ABAP SQL 取到最新日期的最新时间呢。 解决方案&#xff1a; 方式 1&#xff1a;SELECT MAX 可以通过两个 SELECT MAX 来取…

【面试 - 遇到的问题】Vue 里 router-view 使用 key + 关闭页面后重新打开页面-获取的数据赋值到旧组件问题(钩子执行顺序)

目录 【1】问题描述【2】问题排查前 - 页面渲染、tag 页签渲染 逻辑梳理页面渲染【借用别人的描述】<router-view :key"key" />1. 不设置key 属性2. 设置 key 属性值为 $route.path/page/1 > /page/2/page?id1 > /page?id2, 3. 设置 key 属性值为 $rou…

应该连续学一个科目,还是多学科切换?

https://www.zhihu.com/question/333420829https://www.zhihu.com/question/333420829

excel 使用vlook up找出两列中不同的内容

当使用 VLOOKUP 函数时&#xff0c;您可以将其用于比较两列的内容。假设您要比较 A 列和 B 列的内容&#xff0c;并将结果显示在 C 列&#xff0c;您可以在 C1 单元格中输入以下公式&#xff1a; 这个公式将在 B 列中的每个单元格中查找是否存在于 A 列中。如果在 A 列中找不到…