《我用Python写网站04》用户登录、注册

上一篇:我用Python写网站《三》
欢迎来我的论坛讨论Python搭建博客网站的问题和经验。www.ahoh.club
本系列所有文章都会同步到这里,如果不想关注博主,就来这里阅读吧!

通过本文,应该掌握:

  • flask-wtf插件
  • flask-login插件
  • bootstrap-flask插件
  • 用户注册
  • 用户登录

Flask-wtf管理表单

写在前面

上一篇已经完成了项目结构的搭建,还通过注册功能简单的检验了一下框架运行是否正常。
本文,就用Flask-wtf插件统一管理表单。

用户注册

首先安装插件:

(venv)~/ahoh$ pip install flask-wtf

使用Flask-wtf需要先创建表单类,这里算是一个新的实体,为了方便管理,先在app目录下创建一个forms.py文件,专门管理表单。

编辑forms.py内容如下:

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField
from wtforms.validators import DataRequired, EqualTo, Length


class RegisterForm(FlaskForm):
    '''
        注册表单
    '''
    username = StringField(
        label='用户名',
        validators=[DataRequired(message='用户名不能为空!'), Length(
            min=3, max=25, message='用户名长度在3-25个字符之间!')]
    )
    password = PasswordField(
        label='密码',
        validators=[DataRequired(message='密码不能为空'), Length(
            min=6, max=25, message='密码需要6-25个字符')]
    )
    confirm = PasswordField(
        label='确认密码',
        validators=[EqualTo('password', message='两次密码不一致')])
        
    submit = SubmitField(label='注册')

这样一个表单就做好了,然后我们还要重写/auth/register视图,修改内容如下:


@bp.route('/register', methods=('GET', 'POST'))
def register():
    register_form = RegisterForm() # 从request获取表单
    if register_form.validate_on_submit():  # 验证表单完整性
        username = register_form.username.data
        exists = User.query.filter_by(username=username).first() # 验证存在性
        if exists:
            emsg = '用户名已存在'
            flash(emsg) # 提示错误信息
            return render_template('auth/register.html', form=register_form)

        password = generate_password_hash(register_form.password.data)  # 密码加密
        u = User(username=username, password=password) # 创建对象
        db.session.add(u)                              # 插入数据
        db.session.commit()
        return redirect(url_for('auth.login'))         # 跳登录页

    return render_template('auth/register.html', form=register_form)

前端的HTML页面也要同步修改,由于为了美观性,这里再添加一个新的插件:bootstrap-flask

同样,先安装插件:

(venv)~/ahoh$ pip install bootstrap-flask

然后配置插件,先在exts.py中创建插件对象:

from flask_bootstrap import Bootstrap5
bootstrap = Bootstrap5() # 我这里用的是bootstrap5 

我个人不喜欢旧版本的插件,所以都是最新版的插件,虽然bootstrap5当前还不稳定,但是我就是要用,大家可以用4或者3这个完全不影响。

最后在__init__.pycreate_app()函数中插入初始化代码:

from .exts import bootstrap
bootstrap.init_app(app)

这里bootstrap-flask就配置好了,最后在编辑一下register.html文件:

{% extends 'base.html' %}
{% from 'bootstrap5/form.html' import render_form %}

{% block body_content %}
{{ render_form(form) }}
{% endblock %}

然后启动服务器,访问http://localhost:5000/auth/register,是不是和下图一样呢?

启动服务器之前,设置环境变量export FLASK_ENV=development会进入调试模式,服务器在代码修改后自动重启,就不需要一直手动重启代码了!

wtf注册页面
这还有一个非常明显的问题,bootstrap样式还没有用上!
这是因为,我们还没有引入bootstrap样式文件,修改base.html如下:

<!DOCTYPE html>
<html lang="en">

<head>
    {% block head %}
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    {% block styles %}
    <!-- Bootstrap CSS -->
    {{ bootstrap.load_css() }}
    <link rel="stylesheet" href="{{url_for('static',filename='style.css')}}" />
    {% endblock %}
    <title>{% block title %}{{title}}{% endblock %} - My Webpage</title>

    {% endblock %}
</head>

<body>
    <div id="main">
        {% block body_content %}

        {% endblock %}
    </div>

    <div id="footer">
        {% block footer %}
        {% endblock %}
    </div>
    {% block scripts %}
    <!-- Optional JavaScript -->
    {{ bootstrap.load_js() }}
    {% endblock %}
</body>
</html>

刷新页面,就能看到效果了!
bootstrap注册页
这里表单组件距离页面边框太近,可以把它放在.container中。

如果在输入字段的时候,没有按照要求填写,还会触发表单提醒:
不能为空验证
密码不一致验证
美中不足的是,我们的用户名已存在提示并不能显示出来。

register.html中添加以下代码:

{% with messages = get_flashed_messages() %}
    {% if messages %}
        {% for message in messages %}
        <div class="alert alert-warning" role="alert">
            {{message}}
          </div>
        {% endfor %}
    {% endif %}
{% endwith %}

效果如下:

用户名已存在提示
cssjs的童鞋可以自己写个炫酷的效果,这里就简单起见,不在深究了!

Flask-Login插件实现用户登录

flask-login插件实现了用户登录功能,本着绝不多敲一行代码的原则,我们直接使用插件解决登录问题,当然想学习的童鞋,可以系统学习登录功能的实现,这里是官网文档,有登录实现的案例。

首先,还是要先配置flask-login插件,下载插件:

(venv)~/ahoh$ pip install flask-login

然后在exts.py中添加代码:

from flask_login import LoginManager
login_manager = LoginManager()
login_manager.login_view = 'auth.login'

__init__.py中的create_app()函数中注册插件:

from .exts import login_manager
login_manager.init_app(app)

models.pyUser类中,添加父类UserMixin

from flask_login import UserMixin
class User(TimestampMixin, UserMixin, db.Model):
	... ...

然后在文末,添加一个load_user()方法,如下:

@login_manager.user_loader
def load_user(userid):
    return User.query.filter_by(id=userid).first()

到此为止,flask-login插件就配置完毕了,稍微有点复杂相比于其他插件,但是这是值得的!

然后,开始创建登录的form,在forms.py文件中,追加以下代码:

class NameLoginForm(FlaskForm):
    '''
        用户名登录表单
    '''
    username = StringField(
        label='用户名',
        validators=[DataRequired(message='用户名不能为空')])
    password = PasswordField(
        label='密码',
        validators=[DataRequired(message='密码不能为空')])
    remember = BooleanField(label='记住我')
    submit = SubmitField(label="登录")
    pass

然后,编辑视图函数(/auth/login),代码如下:

@bp.route('/login', methods=('GET', 'POST'))
def login():
    '''
        默认登录方式,用户名
    '''
    login_form = NameLoginForm()            # 获取表单
    if login_form.validate_on_submit():     # 表单验证
        username = login_form.username.data
        password = login_form.password.data
        u = User.query.filter_by(username=username).first()
        emsg = None
        if u is None:
            emsg = '用户名不存在'               # 用户不存在
        elif not check_password_hash(u.password, password):  # 密码检查
            emsg = '密码错误'
        if emsg is None:  # 登录成功
            remember = login_form.remember.data
            login_user(u, remember=remember)        # 记住我
            return redirect(url_for('blog.index'))
        flash(emsg)

    return render_template('auth/login.html', form=login_form)

记住我功能,允许服务器向浏览器写入cookie,即使关掉浏览器,再进入网站后,仍然不需要登录。

最后,新建templates/auth/login.html,编辑内容如下:

{% extends 'base.html' %}
{% from 'bootstrap5/form.html' import render_form %}

{% block body_content %}
<div class="container">
    {% with messages = get_flashed_messages() %}
    {% if messages %}
    {% for message in messages %}
    <div class="alert alert-warning" role="alert">
        {{message}}
    </div>
    {% endfor %}
    {% endif %}
    {% endwith %}
    {{ render_form(form) }}
</div>
{% endblock %}

最后,就可以访问http://localhost:5000/auth/login,看看到底有什么效果吧!
登录页面

登录成功之后,就会跳转到首页,当前,我们的首页还是白板,后面有了博客之后,就要添加上了!

Flask-Login实现用户登出

auth.py文件末追加以下代码,实现登出后自当跳转登录页。

@bp.route('/logout')
@login_required
def logout():
    logout_user()
    return redirect(url_for('auth.login'))

没错,就是这么朴实无华。

写在最后

为了方便安装引用的Python包,我就把所有的包写在了requirements.txt文件里,写入的命令是:

(venv)~/ahoh$ pip freeze > requirements.txt

然后,如果需要安装插件的时候,比如刚刚创建虚拟环境,就可以使用:

(venv)~/ahoh$ pip install -r requirements.txt

一条指令,安装所有的包。

当前项目结构:

ahoh/
├── README.en.md
├── README.md
├── app
│   ├── __init__.py
│   ├── auth.py
│   ├── blog.py
│   ├── exts.py
│   ├── forms.py
│   ├── models.py
│   ├── settings.py
│   ├── static
│   │   └── style.css
│   └── templates
│       ├── auth
│       │   ├── login.html
│       │   └── register.html
│       └── base.html
├── migrations
│   └── versions
│       ├── 4b1edc23409f_.py
├── requirements.txt
└── venv

欢迎来我的论坛讨论Python搭建博客网站的问题和经验。www.ahoh.club
本系列所有文章都会同步到这里,如果不想关注博主,就来这里阅读吧!

下一篇《我用Python写网站05》文章发表

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@魏大大

我们都没有打赏的习惯

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值