当前位置: 首页 > news >正文

FLASK博客系列9——你想成为我的新用户吗?

    距离上次发文好久好久了。 先说声抱歉,拖更的毛病我会改掉的。

    

    上次我们教大家如何用后台去管理用户和新增文章,但始终都是单机操作,怎么让你的朋友也来加入你的小站呢?今天我们来为我们的网站增添一个新功能,实现用户的注册。

    我们来看下之前的页面。

    

    已经有模有样的了。那我们就把用户的注册放在右上角吧。

   修改templates/header.html为如下内容。为我们的导航栏添加一个注册按钮。

<nav class="navbar navbar-expand-sm navbar-dark bg-dark"><a class="navbar-brand" href="#" style="font-size: 1.5rem;">我的个人博客</a><div class="navbar-collapse collapse" id="navbarNav"><ul class="navbar-nav ml-md-auto"><li class="nav-item"><a class="nav-link text-white" href="#">注册</a></li></ul></div>
</nav>

    我们来看下效果。还行吧,风格统一。

    接着来写下注册的界面。我们在templates文件夹下新建一个文件夹users。接着新建一个register.html文件,内容如下:

{% extends "base.html" %}
{% block title %}用户注册
{% endblock %}{% block content %}
{% endblock content %}

    有了页面,但是我们还是得通过flask去渲染,这时候就需要再添加一个注册的接口了。

    打开app.py,添加如下内容:

@app.route('users/register', methods=['GET', 'POST'])
def register():if request.method =='GET':return render_template("users/register.html")else:pass

    当GET请求时,我们则渲染注册页面,POST请求时,则注册用户信息。好啦。接着就是继续完成注册页面的前端部分。

{% extends "base.html" %}
{% block title %}用户注册
{% endblock %}
{% block content %}<div class="container col-5" style="margin-top: 10vh"><form method="post" class="form-horizontal "><div class="form-group"><h2 class="text-center ">加入我们</h2></div><div class="form-group"><label for="username" class="col-sm-2 text-right" style="display: inline-block;">用户名: </label><div class="col-sm-9 "   style="display: inline-block;"><input type="text" name="username" class="form-control" id="username" value=""  required placeholder="请输入用户名"/></div></div><div class="form-group"><label for="email" class="col-sm-2 control-label text-right" style="display: inline-block;">邮箱: </label><div class="col-sm-9"  style="display: inline-block;"><input type="email" name="email" class="form-control" id="email" value="" autocomplete="off" required placeholder="请输入邮箱"/></div></div><div class="form-group"><label for="password" class="col-sm-2 control-label text-right" style="display: inline-block;">密码: </label><div class="col-sm-9"  style="display: inline-block;"><input type="password" name="password" class="form-control" id="password" value="" autocomplete="off" required placeholder="请输入密码"/></div></div><div class="form-group"><div class="col-sm-10" style="margin: 0 auto;"><button class="btn btn-lg btn-primary btn-block register-btn" type="submit">注册</button></div></div></form></div>
{% endblock content %}

    别忘了修改header.html中的跳转链接。

<a class="nav-link text-white" href="/users/register">注册</a>

    好了,我们来到首页,点击注册看下。

    不错,这是我们要的效果 。接下来我们来把注册的逻辑补上。这里有个问题,我们之前定义数据库模型的时候,只设计了用户id,用户名,并没有邮箱,密码这2个, 那怎么办呢?没错,让我们来回顾下,往User模型类添加这2个字段。然后做数据库迁移,最后再来写我们的注册,开干。

    

    打开models.py,增加2个字段。

from config import dbclass User(db.Model):  # 表名将会是 user(自动生成,小写处理)id = db.Column(db.Integer, primary_key=True, autoincrement=True)  # 主键name = db.Column(db.String(20), nullable=False)  # 用户名# 给这个article模型添加一个author属性(关系表),User为要连接的表,backref为定义反向引用# lazy表示禁止自动查询,后面可以直接操作这个对象。只可以用在一对多和多对多关系中,不可以用在一对一和多对一中articles = db.relationship('Article', backref=db.backref('user'), lazy='dynamic')password = db.Column(db.String(200), nullable=False)email = db.Column(db.String(88), nullable=False)def __repr__(self):return self.nameclass Article(db.Model):# 也可以自定义表名__tablename__ = 'article'# id 主键 自增id = db.Column(db.Integer, primary_key=True, autoincrement=True)# 文章标题 非空title = db.Column(db.String(100), nullable=False)# 文章正文 非空content = db.Column(db.Text, nullable=False)# 关联表,这里要与相关联的表的类型一致, user.id 表示关联到user表下的id字段author_id = db.Column(db.Integer, db.ForeignKey('user.id'))

    接着对模型进行迁移。执行如下命令,将模型生成迁移文件。

python manage.py db migrate

    执行完命令后,你可以在migrations/versions下看到多了一个迁移文件。 这样就完成了吗?看到这里回忆一下,还需要怎么操作?emmmm。这时候你的数据库里是还没有创建表的。必须执行下面的语句。

python manage.py db upgrade

    好啦,是时候写下逻辑了。打开app.py,更改代码如下:

    

@app.route('/users/register', methods=['GET', 'POST'])
def register():error = None  # 错误if request.method == 'POST':  # 只有POST请求才是注册用户user = models.User()  # 实例化User类,后边可以拿来增删改查username = request.form.get("username", "")  # 从表单获取注册的用户名if user.query.filter(models.User.name == username).first():  # 判断用户名是否已经存在error = "用户已存在"  # 存在则报错。else:  # 不存在则新增。user.name = username  # 新增的用户名user.password = request.form.get("password", "")  # 新增的用户密码user.email = request.form.get("email", "")  # 用户的邮箱db.session.add(user)  # 新增用户db.session.commit()  # 提交到数据库return redirect(url_for('index'))  # 跳转到首页return render_template("users/register.html", error=error)

    好了,我们来注册个测试用户来试试看看吧。

    

    点击注册,可以看到成功跳转到首页。关于登录的,我们后面再讲,这个阶段重在理解逻辑,熟悉框架。我们打开数据库看看。

    

    可以看到,我们成功添加了一个新用户。但是细心的朋友会发现,数据库竟然明文存储了用户的密码。这不仅对数据不安全,万一被脱库了,那用户的信息人人皆知。作为一名合格的码农,我们当然要对它进行加密再存储。这方面Flask都为我们准备好了,它使用的是哈希加密。这里主要使用werkzeug的generate_password_hash,check_password_hash。

    我们将原来新增用户密码的代码按照下面的代码进行修改。

from werkzeug.security import generate_password_hash# user.password = request.form.get("password", "")  # 原来新增用户密码的代码
password = request.form.get("password", "")  # 新增的用户密码
user.password = generate_password_hash(password)  # 密码加密后再存储。

    我们再来新增一个用户test1,注册成功后同样的我们来看下数据库。

    

    我们可以看到密码被加密了,这下次安全了。

pbkdf2:sha256:150000$hEBNa3fz$45a8f9f6b8ffc54797d7380e2f8d671cccf685735b62abcfdd7417f83e2349b2

    好啦。今天给我们的博客网站增加了注册功能。当然这不是最好的办法,但把注册的原理给大家讲述了。大家可以根据喜好,比如新增手机号,昵称等,甚至可以对密码做2次校验输入,添加验证码等等功能。后面有时间的话我们会一步步教大家怎么去增加这些校验的功能。

    喜好的打赏下呗~

相关文章:

FLASK博客系列9——你想成为我的新用户吗?

距离上次发文好久好久了。 先说声抱歉&#xff0c;拖更的毛病我会改掉的。 上次我们教大家如何用后台去管理用户和新增文章&#xff0c;但始终都是单机操作&#xff0c;怎么让你的朋友也来加入你的小站呢&#xff1f;今天我们来为我们的网站增添一个新功能&#xff0c;实现用户…...

用通俗的方法讲解:大模型微调训练详细说明(附理论+实践代码)

本文内容如下 介绍了大模型训练的微调方法&#xff0c;包括prompt tuning、prefix tuning、LoRA、p-tuning和AdaLoRA等。 介绍了使用deepspeed和LoRA进行大模型训练的相关代码。 给出了petals的介绍&#xff0c;它可以将模型划分为多个块&#xff0c;每个用户的机器负责其中一…...

现代化工安全保障迎来巡查无人机新时代

当今现代化工企业呈现出规模不断扩大&#xff0c;设备逐渐趋向大型化的局面&#xff0c;由此导致化工安全生产面临日益严峻的挑战。然而&#xff0c;随着巡查无人机技术的成熟&#xff0c;这种新的高效手段正在提高化工安全检测的工作效率。 一、传统化工安全巡检存在弊端 化工…...

关于web前端通过js获取后端mysql数据库数据的一个方法

关于web前端通过js获取后端mysql数据库数据的一个方法 问题引入 关于html的教程很多&#xff0c;关于mysql的教程也很多&#xff0c;那么怎么让html展示mysql的数据呢&#xff1f; 一言以蔽之 前端通过js向后端发起一个http请求&#xff0c;后端响应这个请求并返回数据 实…...

如何下载IEEE出版社的Journal/Conference/Magazine的LaTeX/Word模板

当你准备撰写一篇学术论文或会议论文时&#xff0c;使用IEEE&#xff08;电气和电子工程师协会&#xff09;的LaTeX或Word模板是一种非常有效的方式&#xff0c;它可以帮助你确保你的文稿符合IEEE出版的要求。无论你是一名研究生生或一名资深学者&#xff0c;本教程将向你介绍如…...

京东数据运营-京东数据开放平台-鲸参谋10月粮油调味市场品牌店铺销售数据分析

鲸参谋监测的京东平台10月份料油调味市场销售数据已出炉&#xff01; 根据鲸参谋数据显示&#xff0c;今年10月份&#xff0c;京东平台粮油调味市场的销量将近4600万&#xff0c;环比增长约10%&#xff0c;同比降低约20%&#xff1b;销售额将近19亿&#xff0c;环比增长约4%&am…...

ThermalLabel SDK for .NET 13.0.23.1113 Crack

ThermalLabel SDK for .NET 是一个 .NET 典型类库&#xff0c;它允许用户和开发人员创建非常创新的条码标签并将其发布在 zebra ZPL、EPL、EPSON ESC、POS 以及 Honeywell intermec 指纹中通过在 VB.NET 或 C# 上编写 .NET 纯代码来实现热敏打印机&#xff0c;以实现项目框架的…...

[Java学习日记]网络编程

目录 一.常见的软件架构、网络编程三要素、IP 二.利用UDP发送与接收数据 三.改聊天室 四.组播案例 五.TCP通信案例 一.常见的软件架构、网络编程三要素、IP 网络编程&#xff1a;在网络通信协议下&#xff0c;不同的计算机上运行的程序进行的数据传输 在Java中可以使用java…...

spring boot mybatis TypeHandler 看源码如何初始化及调用

目录 概述使用TypeHandler使用方式在 select | update | insert 中加入 配置文件中指定 源码分析配置文件指定Mapper 执行query如何转换 结束 概述 阅读此文 可以达到 spring boot mybatis TypeHandler 源码如何初始化及如何调用的。 spring boot 版本为 2.7.17&#xff0c;my…...

数据结构基础(带头节点的双向循环链表)

完整代码 DLinkList.hDLinkList.ctest.c DLinkList.h #pragma once #include <stdio.h> #include <stdlib.h> #include <assert.h>typedef int ElemType;// SList - 单链表 // DList - 双链表 // 带头节点的双向循环链表 - 最优链表结构&#xff0c;任意位置…...

STM32CubeMx+MATLAB Simulink点灯程序

STM32CubeMxMATLAB点灯程序 ✨要想实现在MATLAB Simulink环境下使用STM32&#xff0c;前提是已经搭建好MATLAB环境并且安装了必要的Simulink插件&#xff0c;以及对应的STM32支持包。 &#x1f33f;需要准备一块所安装支持包支持的STM32开发板. &#x1f516;具体支持包详情页…...

【深度学习】gan网络原理生成对抗网络

【深度学习】gan网络原理生成对抗网络 GAN的基本思想源自博弈论你的二人零和博弈&#xff0c;由一个生成器和一个判别器构成&#xff0c;通过对抗学习的方式训练&#xff0c;目的是估测数据样本的潜在分布并生成新的数据样本。 1.下载数据并对数据进行规范 transform tran…...

springboot参数汇总

multipart multipart.enabled 开启上传支持&#xff08;默认&#xff1a;true&#xff09; multipart.file-size-threshold: 大于该值的文件会被写到磁盘上 multipart.location 上传文件存放位置 multipart.max-file-size最大文件大小 multipart.max-request-size 最大请求…...

【算法刷题】Day9

文章目录 611. 有效三角形的个数题干&#xff1a;题解&#xff1a;代码&#xff1a; LCR 179. 查找总价格为目标值的两个商品题干&#xff1a;题解&#xff1a;代码&#xff1a; 1137. 第 N 个泰波那契数题干&#xff1a;原理&#xff1a;1、状态表示&#xff08;dp表里面的值所…...

LangChain的函数,工具和代理(三):LangChain中轻松实现OpenAI函数调用

在我之前写的两篇博客中:OpenAI的函数调用,LangChain的表达式语言(LCEL)中介绍了如何利用openai的api来实现函数调用功能&#xff0c;以及在langchain中如何实现openai的函数调用功能&#xff0c;在这两篇博客中&#xff0c;我们都需要手动去创建一个结构比较复杂的函数描述变量…...

WiFi概念介绍

WiFi概念介绍 1. 什么是WLAN2. 什么是Wi-Fi3. Wi-Fi联盟4. WLAN定义范围5. WiFi协议体系6. 协议架构7. WiFi技术的发展7.1 IEEE802.117.2 802.11标准和补充 8. 术语 1. 什么是WLAN Wireless Local Area Network&#xff0c;采用802.11无线技术进行互连的一组计算机和相关设备。…...

如何优雅的进行业务分层

1.什么是应用分层 说起应用分层&#xff0c;大部分人都会认为这个不是很简单嘛 就controller&#xff0c;service, mapper三层。 看起来简单&#xff0c;很多人其实并没有把他们职责划分开&#xff0c;在很多代码中&#xff0c;controller做的逻辑比service还多,service往往当…...

C++的std命名空间

总以为自己懂了&#xff0c;可是仔细想想&#xff0c;多问自己几个问题&#xff0c;发现好像又不是很清楚 命名空间&#xff08;Namespace&#xff09;是C中一种用于解决命名冲突问题的机制&#xff0c;它能够将全局作用域划分为若干个不同的区域&#xff0c;每个区域内可以有…...

unity学习笔记

一、射线检测 如何让鼠标点击某个位置&#xff0c;游戏角色就能移动到该位置&#xff1f; 实现的原理分析&#xff1a;我们能看见游戏的东西就是摄像机拍摄到的东西&#xff0c;所以摄像机的镜平面就是当前能看到的了。 那接下来我们可以让摄像机发射一条射线&#xff0c;鼠标…...

使用SpringBoot和ZXing实现二维码生成与解析

一、ZXing简介 ZXing是一个开源的&#xff0c;用Java实现的多种格式的1D/2D条码图像处理库。它包含了用于解析多种格式的1D/2D条形码的工具类&#xff0c;目标是能够对QR编码&#xff0c;Data Matrix, UPC的1D条形码进行解码。在二维码编制上&#xff0c;ZXing巧妙地利用构成计…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

vscode(仍待补充)

写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh&#xff1f; debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

1.3 VSCode安装与环境配置

进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件&#xff0c;然后打开终端&#xff0c;进入下载文件夹&#xff0c;键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...

[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

关于 WASM:1. WASM 基础原理

一、WASM 简介 1.1 WebAssembly 是什么&#xff1f; WebAssembly&#xff08;WASM&#xff09; 是一种能在现代浏览器中高效运行的二进制指令格式&#xff0c;它不是传统的编程语言&#xff0c;而是一种 低级字节码格式&#xff0c;可由高级语言&#xff08;如 C、C、Rust&am…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

图表类系列各种样式PPT模版分享

图标图表系列PPT模版&#xff0c;柱状图PPT模版&#xff0c;线状图PPT模版&#xff0c;折线图PPT模版&#xff0c;饼状图PPT模版&#xff0c;雷达图PPT模版&#xff0c;树状图PPT模版 图表类系列各种样式PPT模版分享&#xff1a;图表系列PPT模板https://pan.quark.cn/s/20d40aa…...