史上最详细注释,用flask写一个博客系统

文本用flask写个博客系统,源码带有详细注释,通俗易懂,拿去就能用。博客效果如下,博客首页:

在这里插入图片描述

这个博客麻雀虽小,但五脏俱全。有如下功能:

  1. 博客文章浏览
  2. 用户注册
  3. 用户登录/登出
  4. 发文章/修改文章/删除文章

为了简单,没有用MySQL数据,使用了Sqlite数据库。博客来自flask官方教程,用来学习前后端开发,基于模板的后端开发,也能够学习python后端框架flask。因为例子够简单,适合初学者入门,当然前提是,你得有python编程基础。好了,项目的源代码已经传到这里了 flaskr,打开连接看readme.md文档,就知道怎么部署这个博客了(部署就是把博客跑起来!)。源代码添加了详细的注释,方便初学的朋友学习食用。

比如flaksr的主文件:

import os
from flask import Flask# 应用工厂函数
def create_app(test_config=None):# 设置配置相对于实例文件夹(instance folder),# flask从实例文件夹读取配置,而不是flask应用的根目录,# __name__是让flask知道自己的位置以设置一些路径,如应用程序的根目录和静态文件目录app = Flask(__name__, instance_relative_config=True)# 设置app默认配置app.config.from_mapping(# 保护flask和扩展(extensions)的数据安全SECRET_KEY='dev',# sqlite文件保存路径DATABASE=os.path.join(app.instance_path, 'flaskr.sqlite'),)# 加载真正的配置if test_config is None:# config.py文件也存放在实例文件夹中app.config.from_pyfile('config.py', silent=True)else:# 加载测试配置app.config.from_mapping(test_config)# 创建实例文件夹try:os.makedirs(app.instance_path)except OSError:pass# 一个简单的路由@app.route('/hello')def hello():return 'Hello, World!'# 初始化数据库表from . import dbdb.init_app(app)# 注册认证(auth)蓝图from . import authapp.register_blueprint(auth.bp)# 注册博客(写博文、看博文等)蓝图from . import blogapp.register_blueprint(blog.bp)# 添加一条映射关系:/ -> index,# 让url_for('index')返回/,让url_for('blog.index')也返回/(即blog.py的@bp.route('/'))app.add_url_rule('/', endpoint='index')return app# 进入flask_tutorial目录,运行app并开启调试模式:
# flask --app flaskr run --debug# 进入flask_tutorial目录,初始化数据库表:
# flask --app flaskr init-db

还带有pytest测试目录tests,比如tests/test_auth.py文件用来测试认证相关的功能:

import pytest
from flask import g, session
from flaskr.db import get_dbdef test_register(client, app):# 测试获取注册页是否符合预期assert client.get('/auth/register').status_code == 200# 测试提交表单给注册页response = client.post(# 用字典形式传递数据,测试客户端会转换为表单数据给视图函数'/auth/register', data={'username': 'a', 'password': 'a'})# 如果注册成功,会跳转到登录页,此时响应头中会有Location字段assert response.headers['Location'] == '/auth/login'with app.app_context():assert get_db().execute('SELECT * FROM user WHERE username="a"',).fetchone() is not None# 使用pytest参数化测试装饰器,
# 第一个参数指定被装饰的test_register_validate_input测试用例会有三个参数,
# 测试用例的client参数是fixture装饰过的函数,它有参数app,app也是被fixture
# 装饰过的函数,因此pytest会依次:调用app->返回值给client->调用client->
# 返回值给test_register_validate_input。
# 第二个参数元组中有三组数据,pytest会分别传递给测试用例,以便把三种情况都测试一遍,
# 利用参数化测试的好处是不用把测试用例test_register_validate_input重复写三遍
@pytest.mark.parametrize(('username', 'password', 'message'), (('', '', b'Username is required.'),('a', '', b'Password is required.'),('test', 'test', b'already registered'),)
)
def test_register_validate_input(client, username, password, message):response = client.post('/auth/register',data={'username': username, 'password': password})# response.data是bytes类型,# 测试注册失败的各种情况,看响应体中是否包含对应的错误提示信息assert message in response.datadef test_login(client, auth):assert client.get('/auth/login').status_code == 200response = auth.login()  # 登录 test/test 用户assert response.headers['Location'] == '/'# 在请求之外访问 session 会引发错误,所以使用with上下文with client:client.get('/')assert session['user_id'] == 1assert g.user['username'] == 'test'@pytest.mark.parametrize(('username', 'password', 'message'), (('a', 'test', b'Incorrect username.'),('test', 'a', b'Incorrect password.'),)
)
def test_login_validate_input(auth, username, password, message):response = auth.login(username, password)assert message in response.datadef test_logout(client, auth):auth.login()with client:auth.logout()assert 'user_id' not in session

所有的文件,包括源码文件,测试文件,部署说明都在 这里 了。

部署到云服务器,可以用nginx做web服务器,博客代码跑在wsgi服务器上,比如waitress,或者Gunicorn等等。

nginx配置文件可以这样写,创建一个文件flaskr.conf,内容如下:

server {listen 80 default_server;server_name _;# 把所有http请求永久重定向到httpsrewrite ^/(.*) https://$host/$1 permanent;
}server {listen 443 ssl;server_name fk.izhaojie.com;    index index.html;# f这是最关键的部分,让nginx把请求转发给flask后端,由wsgi服务处理location / {proxy_pass http://127.0.0.1:8080;}
}

完!

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

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

相关文章

vue:js中合并对象的方法

目前比较常用的一共有三种 1、使用object.assign() 它可以将一个或多个对象的属性复制到目标对象中&#xff0c;第一个参数就是目标对象&#xff0c;这里举个例子&#xff1a; <template><div>{{data}}</div> </template> <script> export de…

陪诊接单系统|陪诊系统助力您获取更好的服务

为了解决陪诊过程中的种种瓶颈和问题&#xff0c;我们开发了一款创新的陪诊接单系统&#xff0c;旨在为客户提供更加高效、专业的陪诊服务。该系统凭借其独特的功能和特点&#xff0c;助力您获取更好的陪诊服务体验。 陪诊系统功能&#xff1a; 1、诊前约号&#xff1a;人工带…

MySql优化经验分享

一条sql的具体执行过程 连接 我们怎么查看MySQL当前有多少个连接&#xff1f; 可以用show status命令&#xff0c;模糊匹配Thread&#xff0c; Show global status like "Thread%" show global variables like wait timeout;—非交互式超时时间&#xff0c;如JDBC…

【数据结构】树家族

目录 树的相关术语树家族二叉树霍夫曼树二叉查找树 BST平衡二叉树 AVL红黑树伸展树替罪羊树 B树B树B* 树 当谈到数据结构中的树时&#xff0c;我们通常指的是一种分层的数据结构&#xff0c;它由节点&#xff08;nodes&#xff09;组成&#xff0c;这些节点之间以边&#xff08…

记一次大数据事故@用了很久的虚拟机环境突然不能联网了

记一次大数据事故用了很久的虚拟机环境突然不能联网了 背景 今天打开自己电脑上的虚拟机环境打算练习一下flink&#xff0c;结果发现vmware里虚拟机能正常开机&#xff0c;也能正常进图os&#xff0c;但是就是不能ping通主机&#xff0c;主机也不能ping通虚拟机 探查 1、…

@Tag和@Operation标签失效问题。SpringDoc 2.2.0(OpenApi 3)和Spring Boot 3.1.1集成

问题 Tag和Operation标签失效 但是Schema标签有效 pom依赖 <!-- 接口文档--><!--引入openapi支持--><dependency><groupId>org.springdoc</groupId><artifactId>springdoc-openapi-starter-webmvc-ui</artifactId><vers…

c语言练习(9周)(16~20)

输入12个一位整数&#xff0c;创建二维数组a[3][4]&#xff0c;显示二维数组及各列的平均值&#xff0c;平均值四舍五入到小数点后一位。 题干输入12个一位整数&#xff0c;创建二维数组a[3][4]&#xff0c;显示二维数组及各列的平均值&#xff0c;平均值四舍五入到小数点后一…

RIP路由配置

RIP路由配置步骤与命令&#xff1a; 1.启用RIP路由&#xff1a;router rip 2.通告直连网络&#xff1a;network 直连网络 3.启用RIPv2版本&#xff1a;version 2 4.禁用自动汇总&#xff1a;no auto-summary 注意&#xff1a;静态路由通告远程网络&#xff0c;动态路由通告…

Web - Servlet详解

目录 前言 一 . Servlet简介 1.1 动态资源和静态资源 1.2 Servlet简介 二 . Servlet开发流程 2.1 目标 2.2 开发过程 三 . Servlet注解方式配置 ​编辑 四 . servlet生命周期 4.1 生命周期简介 4.2 生命周期测试 4.3 生命周期总结 五 . servlet继承结构 5.1 ser…

Pytorch 注意力机制解析与代码实现

目录 什么是注意力机制1、SENet的实现2、CBAM的实现3、ECA的实现4、CA的实现 什么是注意力机制 注意力机制是深度学习常用的一个小技巧&#xff0c;它有多种多样的实现形式&#xff0c;尽管实现方式多样&#xff0c;但是每一种注意力机制的实现的核心都是类似的&#xff0c;就…

【Kubernetes部署】二进制部署单Master Kurbernetes集群 超详细

二进制部署K8s 一、基本架构和系统初始化操作1.1 基本架构1.2 系统初始化操作 二、部署etcd集群2.1 证书签发Step1 下载证书制作工具Step2 创建k8s工作目录Step3 编写脚本并添加执行权限Step4 生成CA证书、etcd 服务器证书以及私钥 2.2 启动etcd服务Step1 上传并解压代码包Step…

面试算法51:节点值之和最大的路径

题目 在二叉树中将路径定义为顺着节点之间的连接从任意一个节点开始到达任意一个节点所经过的所有节点。路径中至少包含一个节点&#xff0c;不一定经过二叉树的根节点&#xff0c;也不一定经过叶节点。给定非空的一棵二叉树&#xff0c;请求出二叉树所有路径上节点值之和的最…

分体式离子风刀和整体式离子风刀分别有哪些优缺点

离子风刀是一种利用高速旋转的离子风扇产生的离子风来清洁和干燥物体表面的设备。根据离子风扇的安装方式&#xff0c;离子风刀可以分为分体式离子风刀和整体式离子风刀。下面是它们各自的优缺点&#xff1a; 分体式离子风刀的优点&#xff1a; 安装方便&#xff1a;分体式离子…

电压放大器可用于什么场合

电压放大器是电子器件中常见的一种放大器类型&#xff0c;它可以将输入信号的电压放大到更大的幅度&#xff0c;以满足特定应用的需求。电压放大器广泛应用于多个领域和场合&#xff0c;下面将详细介绍一些使用电压放大器的场景。 音频放大器&#xff1a;音频放大器是电压放大器…

(1)(1.11) LeddarTech Leddar One

文章目录 前言 1 连接到自动驾驶仪 2 参数说明 前言 Leddar One 激光雷达(Leddar One Lidar)是一款重量轻、价格合理的激光雷达&#xff0c;测距 40m&#xff0c;更新频率 70hz&#xff0c;光束为 3 度漫射。有关详细信息&#xff0c;请参阅数据表(datasheet)。 &#xff0…

2023-11-03 LeetCode每日一题(填充每个节点的下一个右侧节点指针 II)

2023-11-03每日一题 一、题目编号 117. 填充每个节点的下一个右侧节点指针 II二、题目链接 点击跳转到题目位置 三、题目描述 给定一个二叉树&#xff1a; struct Node { int val; Node *left; Node *right; Node *next; } 填充它的每个 next 指针&#xff0c;让这个指针…

ArcGIS Pro怎么生成高程点

一般情况下&#xff0c;我们从公开渠道获取到的高程数据都是DEM数据&#xff0c;但是如果要用到CAD等软件内则需要用到高程点&#xff0c;那么如何从DEM提取高程点呢&#xff0c;这里为大家介绍一下生成方法&#xff0c;希望能对你有所帮助。 数据来源 本教程所使用的数据是…

喝酒聚会摇色子小程序源码系统+石头剪刀布+大转盘 带完整的部署教程

来咯来咯&#xff0c;大家都知道摇色子是一种古老而受欢迎的饮酒游戏。在当代年轻人的聚会中&#xff0c;常常都使用摇骰子这种方法来喝酒的。今天罗峰要给大家介绍是一款非常受欢迎的小程序源码系统喝酒聚会摇色子小程序源码系统&#xff0c;还有石头剪刀布&#xff0c;大转盘…

怎么让重要文件自动备份到OneDrive?

可以让文件自动备份到OneDrive吗&#xff1f; OneDrive是比较受欢迎的云存储之一&#xff0c;主要用于存储文件和个人数据&#xff0c;随时随地都能够在多个设备&#xff08;例如Android、台式机或笔记本电脑、平板电脑等&#xff09;之间同步和共享文件。 因此&…

SSL证书在网购中的重要性

近年来&#xff0c;互联网的快速发展使得线上服务范围不断延伸&#xff0c;这其中网络购物更是在全球范围内都呈现上升趋势。然而病毒攻击&#xff0c;网络钓鱼攻击和恶意软件攻击无处不在&#xff0c;网上购物的安全性受到极大威胁。为了保护网络购物的安全&#xff0c;构建可…