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

news2024/11/28 10:42:45

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

    

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

    我们来看下之前的页面。

    

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

   修改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 db


class 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.name


class 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次校验输入,添加验证码等等功能。后面有时间的话我们会一步步教大家怎么去增加这些校验的功能。

    喜好的打赏下呗~

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

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

相关文章

js 获取数组的最大值与最小值

let arr [1, 2, 5, 8, 10, 100, -1] 1. 使用Math的静态方法max/min Math.max()函数返回给定的一组数中的最大值。 它的语法&#xff1a;Math.max(value1[, value2, ...]) 使用此方法&#xff0c;需要注意&#xff0c;如果没有参数的话&#xff0c;则返回-Infinity。如果有任一…

海外服务器的韧性有多重要?带你了解亚马逊云科技的前世今生

在“第四次工业革命”的浪潮中&#xff0c;云计算已经成为众多互联网企业发展业务灵活性和创新性的核心引擎。然而&#xff0c;随之而来的是各个行业对云服务器&#xff0c;尤其是海外服务器的韧性和可靠性的需求不断提升。在这个充满挑战和竞争的行业环境下&#xff0c;亚马逊…

Vatee万腾的数字创新征途:vatee科技力量的独特奇点

在数字化的时代浪潮中&#xff0c;Vatee万腾如一颗耀眼的明星&#xff0c;以其独特的科技奇点引领着数字创新的征途。无论是在人工智能、大数据、云计算&#xff0c;还是智能化领域&#xff0c;Vatee万腾都展现出了与众不同的创新力量&#xff0c;为科技征途描绘了独一无二的奇…

linux下的工具---gdb

一、gdb简介 GDB,是The GNU Project Debugger 的缩写&#xff0c;是 Linux 下功能全面的调试工具。 GDB支持断点、单步执行、打印变量、观察变量、查看寄存器、查看堆栈等调试手段。 程序的发布方式有两种&#xff0c;debug模式和release模式 Linux gcc/g出来的二进制程序&am…

神经网络的分类

神经网络可以分为三种主要类型&#xff1a;前馈神经网络、反馈神经网络 和 图神经网络。 一、前馈神经⽹络 前馈神经⽹络&#xff08;feedforward neural network&#xff09;是⼀种简单的神经⽹络&#xff0c;也被称为多层感知机&#xff08;multi-layer perceptron&#xff…

亚马逊云科技实现了奇瑞捷豹路虎SAP系统的上云目标并保持成本优化

11月23日&#xff0c;“2023第八届IDC中国数字化转型年度盛典”正式开启并揭晓“2023 IDC中国未来企业大奖-卓越奖”获奖企业&#xff0c;奇瑞捷豹路虎汽车有限公司&#xff08;以下简称“奇瑞捷豹路虎”&#xff09;凭借“基于云原生的智慧化运营平台”项目&#xff0c;继获得…

2024年最安全的10个Linux桌面发行版

选择合适的 Linux 发行版很重要。 Linux 发行版是一切计算的基石&#xff0c;也是诸君管理硬件组件及交互的重要工具。如果没有强大的安全措施&#xff0c;你的系统很容易受到攻击。值得庆幸的是&#xff0c;Linux 生态系统提供了一系列选项&#xff0c;允许用户根据自己的特定…

Single Patterns : 就一个单例模式调得我蛋疼,1. 单例类的继承树即扩展 2. 系统中单例类的注册及查询,属实有意思!

Intent Ensure a class only has one instance, and provide a global point of access to it. // DesignPatterns.cpp: 定义应用程序的入口点。 //#include "DesignPatterns.h"#include <list> #include <utility> using namespace std;class Single…

计算机视觉面试题-03

1、简单介绍一下sigmoid&#xff0c;relu&#xff0c;softplus&#xff0c;tanh&#xff0c;RBF及其应用场景 这里简单介绍几个激活函数及其应用场景&#xff1a; Sigmoid 函数&#xff08;Logistic 函数&#xff09;&#xff1a; 公式&#xff1a; s i g m a ( x ) 1 1 e …

2.7V 到 5.5V、 12Bit 单通道数模转换器MS5221/5221M

产品简述 MS5221/5221M 是一款 12bit 单通道输出的电压型 DAC &#xff0c;接口 采用三线串口模式&#xff0c;可以兼容 TMS320 、 SPI 、 QSPI 和 Microwire 串 口。 MS5221/5221M 数据有 16bit &#xff0c;包括控制字节&#xff0c;和 12bitDAC 数 据。 MS5221/5221M 电…

CloudCompare 二次开发1

一、在源码中添加插件文件 修改cmakelist 二、插件文件内容 MyPlugin 1、修改程序名称 2、 修改cMakeList 3、 修改cpp和.h 4、修改qc 5、修改json 三、重新编译 cmake 插件 如果不打√那个生成的程序里面没有这个插件显示 generate 然后生成 结果 四、结果显示 dll …

SAS Planet软件介绍与使用教程

软件情况 SAS Planet是一位俄罗斯爱好者创建的的开源应用&#xff0c;该应用可以浏览与下载主流网络地图&#xff0c;包括Google地图、Google地球、Bing地图、Esri 地图、Yandex地图等。 该软件是基于Pascal开发的应用&#xff0c;目前已在github上开源&#xff0c;并使用了GP…

统计学之假设检验

- 原假设和备择假设&#xff1a; - 第一类错误&#xff08;α错误&#xff09;&#xff1a;H0以真为假 *重点关注 第二类错误&#xff08;β错误&#xff09;&#xff1a;H0以假为真 - 假设检验流程&#xff1a; 提出H0和H1&#xff1b;计算检验统计量Z&#xff1…

运维01:云计算

云计算的类型 分类&#xff1a;公有云、私有云、混合云 云计算的服务模式 服务模式分3种&#xff1a; ①IaaS&#xff08;Infrastructure as a Service&#xff09;&#xff1a;基础设施即服务 ②PaaS&#xff08;Platform as a Service&#xff09;&#xff1a;平台即服务…

数据结构——利用堆进行对数组的排序

今天文章的内容是关于我们如何利用堆的特性对我们的数组进行排序&#xff0c;还有就是我们的TopK的问题&#xff0c;这次我们放在的是文件种&#xff0c;我们放入一亿个数字&#xff0c;然后我们取出一亿个数字中最大的十个数&#xff0c;利用上章堆的问题进行解决。 首先就是我…

函数指针数组指针数组传参的本质字符指针

&#x1f680; 作者&#xff1a;阿辉不一般 &#x1f680; 你说呢&#xff1a;不服输的你&#xff0c;他们拿什么赢 &#x1f680; 专栏&#xff1a;爱上C语言 &#x1f680;作图工具&#xff1a;draw.io(免费开源的作图网站) 如果觉得文章对你有帮助的话&#xff0c;还请点赞…

​ 云计算的尽头是轻量应用服务器?带你了解亚马逊Lightsail的卓越优势

很多小伙伴可能都在好奇&#xff0c;轻量应用服务器有什么特点&#xff1f;为什么相较于普通的云服务器&#xff0c;很多用户现在都更青睐于轻量应用服务器?这个“轻”就是它独特的优势所在。轻量应用服务器以其“开箱即用、应用优质、轻松上手、投入划算、运维便捷和稳定可靠…

最近得了一场病 差点要了我的命

最近得了一场病&#xff0c;前后持续了有十多天&#xff0c;时至今日感觉脑袋还是昏昏沉沉的不在状态&#xff0c;感觉像是药吃的&#xff0c;毕竟连着吃了十多天西药&#xff0c;可能人也吃傻了吧&#xff0c;中间还挂了五天水&#xff0c;算是补充了能量。 起因是和老婆去吃…

【Shell】Shell基础学习

一、shell脚本 (1)第一个shell脚本 #!/bin/bash #this is a comment echo "hello world"一个shell脚本永远以“#!”开头,这是一个脚本开始的标记,它是告诉系统执行这个文件需要用某个解释器,后面的/bin/bash就是指明解释器的具体位置。 “#”开头是注释 …

MBA-历年数学题

xx题 甲从1&#xff0c;2&#xff0c;3中抽取一数&#xff0c;记为α;乙从1&#xff0c;2&#xff0c;3&#xff0c;4中抽取一数&#xff0c;记为b规定当a>b或a1<b时甲获胜&#xff0c;则甲获胜的概率为&#xff1f; 倍数题 若实数a&#xff0c;b&#xff0c;c满足a∶b…