上一篇:我用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__.py
的create_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
会进入调试模式,服务器在代码修改后自动重启,就不需要一直手动重启代码了!
这还有一个非常明显的问题,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>
刷新页面,就能看到效果了!
这里表单组件距离页面边框太近,可以把它放在.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 %}
效果如下:
懂css
和js
的童鞋可以自己写个炫酷的效果,这里就简单起见,不在深究了!
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.py
的User
类中,添加父类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。
本系列所有文章都会同步到这里,如果不想关注博主,就来这里阅读吧!