一个基于flask的web应用诞生 用户注册功能开发(5)


Posted in Python onApril 11, 2017

下面把角色分为两种,普通用户和管理员用户,至少对于普通用户来说,直接修改DB是不可取的,要有用户注册的功能,下面就开始进行用户注册的开发。

用户表

首先要想好用户注册的时候需要提供什么信息:用户名、密码、昵称、邮箱、生日、性别、自我介绍,下面就按照这些信息修改用户模型:

class User(db.Model):
 __tablename__="users"
 id=db.Column(db.Integer,primary_key=True)
 username=db.Column(db.String(50),unique=True,index=True)
 password=db.Column(db.String(50))
 nickname=db.Column(db.String(50))
 email=db.Column(db.String(100))
 birthday=db.Column(db.DateTime)
 gender=db.Column(db.Integer)
 remark=db.Column(db.String(200))
 role_id=db.Column(db.Integer,db.ForeignKey("roles.id"))

然后使用脚本修改db

python default.py db migrate -m "修改用户表"

回车后界面显示内容为:

一个基于flask的web应用诞生 用户注册功能开发(5)

然后进行db差异的改动

python default.py db upgrade

这时看db中的表结构:

一个基于flask的web应用诞生 用户注册功能开发(5)

已经修改成功

注册界面

然后新建register.html模板,设置登录表单:

{% extends "base.html"%}
{% block content %} <!--具体内容-->
<div class="container">
 <div class="row"></div>
 <div class="row">

  <div>
   <div class="page-header">
    <h1>欢迎您注册</h1>
   </div>
   {% for message in get_flashed_messages() %}
   <div class="alert alert-warning">
    <button type="button" class="close" data-dismiss="alter">×</button>
    {{message}}
   </div>
   {% endfor %}
   <form method="post">
    <div class="form-group">
    <label for="username">用户名</label>
    <input type="text" class="form-control" name="username" id="username" placeholder="请输入用户名">
    </div>
    <div class="form-group">
    <label for="passworld">密码</label>
    <input type="password" class="form-control" name="password" id="passworld" placeholder="请输入密码">
    </div>
    <div class="form-group">
    <label for="email">昵称</label>
    <input type="email" class="form-control" name="nickname" id="nickname" placeholder="请输入昵称">
    </div>
    <div class="form-group">
    <label for="birthday">生日</label>
    <input type="date" class="form-control" name="birthday" id="birthday" placeholder="请输入生日">
    </div>
    <div class="form-group">
    <label >性别</label>
    <label class="form-control">
     <input type="radio" name="gender" value="0" id="gender0"><label for="gender0">男</label>
     <input type="radio" name="gender" value="1" id="gender1"><label for="gender1">女</label>
    </label>
    </div>
    <div class="form-group">
    <label for="email">电子邮箱</label>
    <input type="email" class="form-control" name="email" id="email" placeholder="请输入电子邮箱">
    </div>
    <button type="submit" class="btn btn-default">登录</button>
   </form>
  </div>
 </div>
</div>
{% endblock %}

然后在default.py文件中新增register路由,代码为:

@app.route("/register",methods=["GET"])
def register():
 return render_template("/register.html")

运行界面正常,然后增加post路由:

@app.route("/register",methods=["Post"])
def registerPost():
 user=User();
 user.username=request.form.get("username","")
 user.password = request.form.get("password", "")
 user.birthday = request.form.get("birthday", "")
 user.email = request.form.get("email", "")
 user.gender = request.form.get("gender", "")
 user.nickname = request.form.get("nickname", "")
 user.role_id = 1 #暂时约定公开用户角色为1

 #判断,其中用户名,密码,昵称不能为空
 if(len(user.username.strip())==0):
  flash("用户名不能为空")
  return render_template("/register.html")
 if(len(user.password.strip())==0):
  flash("用户密码不能为空")
  return render_template("/register.html")
 if (len(user.nickname.strip()) == 0):
  flash("用户昵称不能为空")
  return render_template("/register.html")
 db.session.add(user);
 flash("您已注册成功")
 return render_template("/register.html")

代码有点??拢?黄?粒???疽馔寄鼙泶锴宄??δ芤部梢允迪郑??衷诘奈侍饫戳耍?尤胛倚略鲆桓鲎侄危?敲葱枰?薷娜?Υ?耄?tml,form.get,校验),并且尤其是需要修改html,而且html部分没有验证,如果增加客户端验证的话,需要修改的会更多。那么有没有一个针对表单进行优化的工具呢,答案是当然有,轮到wtf登场了。

引入WTF表单框架

和之前一样,首先需要安装插件。

pip3.6 install flask-wtf

然后引入所需的包

from flask.ext.wtf import Form
from wtforms import StringField,PasswordField,SubmitField,RadioField
from wtforms.validators import DataRequired,EqualTo,Length

下面创建一个表单RegisterForm:

class RegisterForm(Form):
 username = StringField("请输入用户名", validators=[DataRequired()])
 password = PasswordField("请输入密码", validators=[DataRequired()])
 repassword=PasswordField("确认密码", validators=[EqualTo("password")])
 nickname= StringField("昵称")
 birthday= DateField("出生日期")
 email= StringField("邮箱地址", validators=[Email()])
 gender= RadioField("性别", choices=[("0", "男"), ("1", "女")], default=0)
 remark= TextAreaField("自我简介")
 submit=SubmitField("提交")

修改register.html模板:

{% extends "base.html"%}
{% block content %} <!--具体内容-->
{% import "bootstrap/wtf.html" as wtf %} <!--导入bootstrap模板 -->
<div class="container">
 <div class="row"></div>
 <div class="row">

  <div>
   <div class="page-header">
    <h1>欢迎您注册</h1>
   </div>
   {% for message in get_flashed_messages() %}
   <div class="alert alert-warning">
    <button type="button" class="close" data-dismiss="alter">×</button>
    {{message}}
   </div>
   {% endfor %}
   {{ wtf.quick_form(form)}} <!--创建表单-->
  </div>
 </div>
</div>
{% endblock %}

执行,输出结果:

一个基于flask的web应用诞生 用户注册功能开发(5)

阿欧,报错了,看看输出是什么错误:

一个基于flask的web应用诞生 用户注册功能开发(5)

注意红线一句,是CSRF错误,CSRF的概念可直接百度,知道问题了,其实也很好修改,在框架中增加一个秘钥就可以有效的防范了,在default.py中增加一行:

app.config['SECRET_KEY'] = "Niu_blog String"

秘钥字符串可自定义

然后再次运行,出现界面:

一个基于flask的web应用诞生 用户注册功能开发(5)

并且包含验证bootstrap的验证样式,接下来继续改造default.py已完成此注册功能

@app.route("/register",methods=["GET","POST"])
def register():
 form=RegisterForm()
 if form.validate_on_submit():
  user=User()
  user.username=form.username.data
  user.password=form.password.data
  user.birthday=form.birthday.data
  user.email=form.email.data
  user.gender=form.gender.data
  user.nickname=form.nickname.data
  user.role_id=1   #暂时约定公开用户角色为1
  db.session.add(user)
 return render_template("/register.html",form=form)

注意此时已删除registerPost方法

好运行测试一下

一个基于flask的web应用诞生 用户注册功能开发(5)

点击提交:

一个基于flask的web应用诞生 用户注册功能开发(5)

阿欧,日期格式为啥不对?这个要从源码里看了:

class DateField(DateTimeField):
 """
 Same as DateTimeField, except stores a `datetime.date`.
 """
 def __init__(self, label=None, validators=None, format='%Y-%m-%d', **kwargs):
  super(DateField, self).__init__(label, validators, format, **kwargs)

 def process_formdata(self, valuelist):
  if valuelist:
   date_str = ' '.join(valuelist)
   try:
    self.data = datetime.datetime.strptime(date_str, self.format).date()
   except ValueError:
    self.data = None
    raise ValueError(self.gettext('Not a valid date value'))

这个是wtforms的field的源码,位于/wtforms/fields/core.py的745行,可以看到,这里支持的日期格式为年-月-日格式,格式限定比较死,并且文本框没有用html5的date而是普通的text,解决办法以后再说,暂时先修改输入,改为1988-2-5,然后点击提交:

一个基于flask的web应用诞生 用户注册功能开发(5)

注意,由于代码中提交成功之后依然是返回到此页,并注入内容,所以显示没有问题,看看db中:

一个基于flask的web应用诞生 用户注册功能开发(5)

记录正常进入db,功能实现完成。

改善登录页

下面改造登录页,首先创建登录表单:

class LoginForm(Form):
 username=StringField("请输入用户名",validators=[DataRequired()])
 password=PasswordField("请输入密码")
 submit=SubmitField("登录")

修改登录模板页:

{% extends "base.html"%}
{% import "bootstrap/wtf.html" as wtf %}
{% block content %} <!--具体内容-->
<div class="container">
 <div class="row"></div>
 <div class="row">

  <div class="col-md-4 col-md-offset-4 col-sm-6 col-sm-offset-3">
   <div class="page-header">
    <h1>欢迎您登陆</h1>
   </div>
   {% for message in get_flashed_messages() %}
   <div class="alert alert-warning">
    <button type="button" class="close" data-dismiss="alter">×</button>
    {{message}}
   </div>
   {% endfor %}
   {{ wtf.quick_form(form)}}
  </div>
 </div>
</div>
{% endblock %}

修改路由方法:

@app.route("/login",methods=["GET","POST"])
def login():
 form=LoginForm()
 if form.validate_on_submit():
  username = form.username.data
  password = form.password.data
  user = User.query.filter_by(username=username, password=password).first()
  if user is not None:
   session["user"] = username
   return render_template("/index.html", name=username, site_name='myblog')
  else:
   flash("您输入的用户名或密码错误")
   return render_template("/login.html",form=form) # 返回的仍为登录页
 return render_template("/login.html",form=form)

重启服务,运行程序,输入zhangji和123后,成功登录首页

回到首页

现在首页白茫茫的一片,什么内容都没有,正常的轻博客应该登录后显示发博按钮,已关注文章等,但首先要记录登录的状态,这些将在下一章说明。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python实现比较两个列表(list)范围
Jun 12 Python
Python爬虫爬验证码实现功能详解
Apr 14 Python
Python中的浮点数原理与运算分析
Oct 12 Python
python3实现字符串的全排列的方法(无重复字符)
Jul 07 Python
详解python while 函数及while和for的区别
Sep 07 Python
python实现简单登陆系统
Oct 18 Python
pyqt5实现俄罗斯方块游戏
Jan 11 Python
python中多个装饰器的调用顺序详解
Jul 16 Python
Python 利用邮件系统完成远程控制电脑的实现(关机、重启等)
Nov 19 Python
python wav模块获取采样率 采样点声道量化位数(实例代码)
Jan 22 Python
Python 开发工具PyCharm安装教程图文详解(新手必看)
Feb 28 Python
tensorflow使用freeze_graph.py将ckpt转为pb文件的方法
Apr 22 Python
一个基于flask的web应用诞生 flask和mysql相连(4)
Apr 11 #Python
一个基于flask的web应用诞生 bootstrap框架美化(3)
Apr 11 #Python
一个基于flask的web应用诞生 使用模板引擎和表单插件(2)
Apr 11 #Python
非递归的输出1-N的全排列实例(推荐)
Apr 11 #Python
一个基于flask的web应用诞生(1)
Apr 11 #Python
Python 文件处理注意事项总结
Apr 10 #Python
python非递归全排列实现方法
Apr 10 #Python
You might like
《逃离塔科夫》——“萌新劝退,老手自嗨”的硬核FPS游戏
2020/04/03 其他游戏
php中目录操作opendir()、readdir()及scandir()用法示例
2019/06/08 PHP
清除网页历史记录,屏蔽后退按钮!
2008/12/22 Javascript
测试你的JS的掌握程度的代码
2009/12/09 Javascript
Array.prototype 的泛型应用分析
2010/04/30 Javascript
客户端 使用XML DOM加载json数据的方法
2010/09/28 Javascript
基于Jquery的仿照flash放大图片效果代码
2011/03/16 Javascript
JQuery实现用户名无刷新验证的小例子
2013/03/22 Javascript
javascript实现动态模态绑定grid过程代码
2014/09/22 Javascript
JQuery仿小米手机抢购页面倒计时效果
2014/12/16 Javascript
浅析Bootstrip的select控件绑定数据的问题
2016/05/10 Javascript
JavaScript每天必学之数组和对象部分
2016/09/17 Javascript
基于js 本地存储(详解)
2017/08/16 Javascript
JS常见构造模式实例对比分析
2018/08/27 Javascript
vue中$refs, $emit, $on, $once, $off的使用详解
2019/05/26 Javascript
mpvue实现小程序签到金币掉落动画(api实现)
2019/10/17 Javascript
JavaScript实现轮播图片完整代码
2020/03/07 Javascript
[04:42]2015国际邀请赛CDEC战队晋级之路
2015/08/13 DOTA
Python中for循环详解
2014/01/17 Python
Python写的PHPMyAdmin暴力破解工具代码
2014/08/06 Python
使用IPython来操作Docker容器的入门指引
2015/04/08 Python
详解在Python程序中使用Cookie的教程
2015/04/30 Python
python使用xmlrpclib模块实现对百度google的ping功能
2015/06/02 Python
Python中time模块与datetime模块在使用中的不同之处
2015/11/24 Python
详解python 3.6 安装json 模块(simplejson)
2019/04/02 Python
PyQt5多线程防卡死和多窗口用法的实现
2020/09/15 Python
CSS3结构性伪类选择器九种写法
2012/04/18 HTML / CSS
HTML中fieldset标签概述及使用方法
2013/02/01 HTML / CSS
飞利浦法国官网:Philips法国
2019/07/10 全球购物
英国儿童设计师服装和玩具购物网站:Zac & Lulu
2020/10/19 全球购物
英智兴达软件测试笔试题
2016/10/12 面试题
基层干部2014全国两会学习心得体会
2014/03/10 职场文书
八年级英语教学计划
2015/01/23 职场文书
创业计划书之溜冰场
2019/10/25 职场文书
MySQL 百万级数据的4种查询优化方式
2021/06/07 MySQL
Python可视化学习之matplotlib内置单颜色
2022/02/24 Python