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

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

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

我们来看下之前的页面。

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

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

python 复制代码
<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文件,内容如下:

markup 复制代码
{% extends "base.html" %}
{% block title %}
    用户注册
{% endblock %}

{% block content %}
{% endblock content %}

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

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

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

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

python 复制代码
{% 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中的跳转链接。

python 复制代码
<a class="nav-link text-white" href="/users/register">注册</a>

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

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

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

python 复制代码
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,更改代码如下:

python 复制代码
@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。

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

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

喜好的打赏下呗~

相关推荐
东方小月5 分钟前
从零开发一个 Coding Agent(三):EventStream 事件流通道设计与实现
前端·人工智能·后端
卫子miao7 分钟前
如何评价当前大语言模型的记忆机制?
后端·架构
神奇小汤圆36 分钟前
为什么 AQS 成为 Java 并发的基石?
后端
无垠的广袤1 小时前
【工业树莓派 CM0 Dev Board】扩展板设计
linux·python·嵌入式硬件·pcb设计·模块化·传感器
Yolanda_20221 小时前
在vscode终端中可使用pip,但是cmd终端中找不到命令 pip问题的解决
vscode·python·conda·pip
星栈1 小时前
MCP 从 stdio 迁到 SSE,踩了 5 个传输层坑
人工智能·后端·架构
Conan在掘金2 小时前
鸿蒙报错速查:struct 里嵌 enum 声明就炸,根因 + 真解法
后端
2301_764441332 小时前
用动力学系统(微分方程)为 Kernberg 的客体关系单元提供数学化的操作定义,把“自体—客体“这对心理结构建模成一个二维耦合系统
数据结构·python·算法·数学建模
dogstarhuang2 小时前
用 Doubao-Seed-Evolving + Python 免费写一个网页正文提取工具(实战教程)
爬虫·python·ai编程
回家路上绕了弯2 小时前
Java双数据源实战全指南:Spring Boot多数据源配置、原理与踩坑避坑
后端