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

news2025/1/22 21:09:34

文本用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 db
    db.init_app(app)

    # 注册认证(auth)蓝图
    from . import auth
    app.register_blueprint(auth.bp)

    # 注册博客(写博文、看博文等)蓝图
    from . import blog
    app.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_db


def 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.data


def test_login(client, auth):
    assert client.get('/auth/login').status_code == 200
    response = auth.login()  # 登录 test/test 用户
    assert response.headers['Location'] == '/'
    
    # 在请求之外访问 session 会引发错误,所以使用with上下文
    with client:
        client.get('/')
        assert session['user_id'] == 1
        assert 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.data


def 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请求永久重定向到https
    rewrite ^/(.*) 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.coloradmin.cn/o/1165079.html

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

相关文章

Linux设置ssh免密登录

ssh连接其他服务器 基本语法 ssh 另一台机器的ip地址 连接后输入连接主机用户的密码,即可成功连接。 输入exit 可以登出; 由于我配置了主机映射所以可以不写ip直接写映射的主机名即可,Linux配置主机映射的操作为 vim /etc/hosts # 我自己…

Linux上编译sqlite3库出现undefined reference to `sqlite3_column_table_name‘

作者:朱金灿 来源:clever101的专栏 为什么大多数人学不会人工智能编程?>>> 在Ubuntu 18上编译sqlite3库后在运行程序时出现undefined reference to sqlite3_column_table_name’的错误。网上的说法是说缺少SQLITE_ENABLE_COLUMN_M…

【使用Python编写游戏辅助工具】第四篇:Windows窗口操作

前言 这里是【使用Python编写游戏辅助工具】的第四篇:Windows窗口操作。本文主要介绍使用Python来实现Windows窗口的各种操作。 Windows窗口操作是游戏辅助功能中不可或缺的一部分。 Windows窗口操作指的是与Windows操作系统中的窗口进行交互和控制的操作&#xff…

Docker安装ElasticSearch7.8.0

Docker安装ElasticSearch7.8.0 1:docker可能会拉取不了es,此时可以配置一个很好用的镜像源(daocloud),下载非常快: curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.…

iTerm2 自动连接服务器配置

iTerm2 自动连接服务器配置 创建ssh_conf.sh配置文件 touch ssh_conf.sh编辑配置文件内容 #!/usr/bin/expect -f set user root set host 119.xxx.xxx.xxx set port 22 set password xxxx set timeout 30 spawn ssh -p $port $user$host expect "$user$hosts password:…

测试用例设计方法 —— 场景法详解

场景法是通过运用场景来对系统的功能点或业务流程的描述,从而提高测试效果的一种方法。 场景法一般包含基本流和备用流,从一个流程开始,通过描述经过的路径来确定的过程,经过遍历所有的基本流和备用流来完成整个场景。 场景主要…

玻色量子“天工量子大脑”亮相中关村论坛,大放异彩

2023年5月25日至30日,2023中关村论坛(科博会)在北京盛大召开。中关村论坛(科博会)是面向全球科技创新交流合作的国家级平台行业盛会,由科技部、国家发展改革委、工业和信息化部、国务院国资委、中国科学院、…

【Linux学习笔记】进程概念(上)

1. 冯诺依曼体系结构2. 操作系统的作用3. 进程 1. 冯诺依曼体系结构 如图,这是一个冯诺依曼体系结构简图 其中这里的存储器指的是内存! 用通俗的话来解释这个图,就是数据从输入设备进入,然后进入到存储器,CPU从存储器…

【PWN · heap | UAF】[BJDCTF 2020]YDSneedGirlfriend

一篇裸的、便于学习UAF的题目和笔记 前言 UAF-释放后重用,这一题和wiki上教学的那一题一样,是纯的裸UAF题目 一、题目 二、分析 题目中del函数,在释放申请的堆块后,并没有将置零,存在UAF漏洞。 分析add函数&#xf…

Tailwind CSS vs 现代CSS,Tailwind CSS 会像CSS-in-JS 一样亡?

本文是 关于Tailwind CSS 与 现代 CSS之间比较的文章。文章中作者详细比较了这两种CSS开发方法的优缺点。他指出,Tailwind CSS是一种基于类的CSS框架,提供了快速开发网站的便利性,但可能导致HTML代码的臃肿。另一方面,现代CSS方法…

[双指针] (四) LeetCode 18.四数之和

[双指针] (四) LeetCode 18.四数之和 文章目录 [双指针] (四) LeetCode 18.四数之和题目解析解题思路代码实现总结 18. 四数之和 题目解析 (1) 从一个数组中找一个目标值target (2) target nums[a] nums[b] nums[c] nums[d] 解题思路 和上一道题三数之和一样, 我们把四…

刷到这篇文章的老师,就是老天在帮你

作为一名奋斗在教育战线的老师,是否曾在成绩查询这个环节中倍感头大? 统计是个繁琐又重要的工作,但有了正确的工具,一切都变得无所谓! 什么是成绩查询? 成绩查询,顾名思义,就是学生…

uni-app 应对微信小程序最新隐私协议接口要求的处理方法

这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 一,问题起因 最新在开发小程序的时候,调用微信小程序来获取用户信息的时候经常报错一个问题 fail api scope is not declared in the privacy agreement,api更具公告…

Linux | 文件系统

目录 前言 一、预备知识 二、文件相关的系统调用 1、C语言的文件操作 2、系统调用接口 (1)open函数 (2)close函数 (3)write函数 (4)read函数 3、代码实操 三、深入理解文…

k8s:endpoint

在 Kubernetes 中,Endpoint 是一种 API 对象,它用于表示集群内某个 Service 的具体网络地址。换句话说,它连接到一组由 Service 选择的 Pod,从而使它们能够提供服务。每个 Endpoint 对象都与相应的 Service 对象具有相同的名称&am…

python判断图片主颜色

一 、 问题:python判断图片主颜色 python判断图片主颜色(HSV) 二 、 项目背景: app选项是否能被点击,判断执行逻辑。做自动化测试的朋友肯定遇到好多次,按钮属性无法判别时,就需要自己将app选…

shell script中的数值运算declare和$((运算式 ))

linux中变量定义默认是字符串类型,如要进行数值运算,需要先声明变量类型,或者通过固定格式来计算 看案例 如果不通过固定格式,直接 echo 55 如图,结果显示的55本身 可以写成 declare -i var#声明变量integrate类型&…

网络架构学习之FCNVMB(基于U-Net架构)

目录 一、U-Net介绍 1.1 网络简单介绍 1.2 网络特点 二、FCNVMB介绍 2.1 文章简介 2.2 网络简单介绍 2.3 代码介绍 2.4 跳跃连接 2.5 训练过程 2.6 FCNVMB与InversionNet的比较 一、U-Net介绍 1.1 网络简单介绍 U-Net是基于全卷积网络下一个语义分割应用于生物医学的深…

PC端视频编辑处理的全方位解决方案

视频已经成为企业传播信息、展示品牌形象的重要工具。然而,制作高质量的视频并非易事,需要专业的技术和设备。这就是美摄科技发挥作用的地方。我们为企业提供一站式的PC端视频编辑处理解决方案,帮助企业轻松制作出专业级别的视频。 美摄科技…

Kubernetes 架构

Kubernetes 架构 Kubernetes 最初源于谷歌内部的 Borg,提供了面向应用的容器集群部署和管理系统。Kubernetes 的目标旨在消除编排物理 / 虚拟计算,网络和存储基础设施的负担,并使应用程序运营商和开发人员完全将重点放在以容器为中心的原语上进行自助运营。Kubernetes 也提…