一个基于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的print用法示例
Feb 11 Python
Python字符串转换成浮点数函数分享
Jul 24 Python
Python编程中的文件操作攻略
Oct 16 Python
Python实现的排列组合计算操作示例
Oct 13 Python
对命令行模式与python交互模式介绍
May 12 Python
在Python中画图(基于Jupyter notebook的魔法函数)
Oct 28 Python
python3实现在二叉树中找出和为某一值的所有路径(推荐)
Dec 26 Python
pytorch实现线性拟合方式
Jan 15 Python
python 弧度与角度互转实例
Apr 15 Python
在pytorch中动态调整优化器的学习率方式
Jun 24 Python
flask开启多线程的具体方法
Aug 02 Python
Python基础之常用库常用方法整理
Apr 30 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
我的论坛源代码(六)
2006/10/09 PHP
供参考的 php 学习提高路线分享
2011/10/23 PHP
Linux下CoreSeek及PHP扩展模块的安装
2012/09/23 PHP
CodeIgniter图像处理类的深入解析
2013/06/17 PHP
PHP与JavaScript针对Cookie的读写、交互操作方法详解
2017/08/07 PHP
PHP PDOStatement::rowCount讲解
2019/02/01 PHP
PHP架构及原理知识点详解
2019/12/22 PHP
javascript SocialHistory 检查访问者是否访问过某站点
2008/08/02 Javascript
使用JS进行目录上传(相当于批量上传)
2010/12/05 Javascript
为你的网站增加亮点的9款jQuery插件推荐
2011/05/03 Javascript
jQuery获取Radio,CheckBox选择的Value值(示例代码)
2013/12/12 Javascript
基于js与flash实现的网站flv视频播放插件代码
2014/10/14 Javascript
个人总结的一些JavaScript技巧、实用函数、简洁方法、编程细节
2015/06/10 Javascript
JS+CSS实现自适应选项卡宽度的圆角滑动门效果
2015/09/15 Javascript
学习JavaScript设计模式之装饰者模式
2016/01/19 Javascript
jQuery简单实现上下,左右滑动的方法
2016/06/01 Javascript
一种基于浏览器的自动小票机打印实现方案(js版)
2016/07/26 Javascript
纯js实现悬浮按钮组件
2016/12/17 Javascript
微信小程序 增、删、改、查操作实例详解
2017/01/13 Javascript
原生和jQuery的ajax用法详解
2017/01/23 Javascript
easyUI下拉列表点击事件使用方法
2017/05/18 Javascript
angular之ng-template模板加载
2017/11/09 Javascript
nodejs express配置自签名https服务器的方法
2018/05/22 NodeJs
Python爬虫实现抓取京东店铺信息及下载图片功能示例
2018/08/07 Python
Python清空文件并替换内容的实例
2018/10/22 Python
python flask 如何修改默认端口号的方法步骤
2019/07/12 Python
python中将两组数据放在一起按照某一固定顺序shuffle的实例
2019/07/15 Python
python 采用paramiko 远程执行命令及报错解决
2019/10/21 Python
Python经纬度坐标转换为距离及角度的实现
2020/11/01 Python
结合 CSS3 transition transform 实现简单的跑马灯效果的示例
2018/02/07 HTML / CSS
求职简历的自我评价怎样写好
2013/10/07 职场文书
医学求职自荐信
2014/06/21 职场文书
11.9消防日宣传标语
2014/10/08 职场文书
云台山导游词
2015/02/03 职场文书
导游词之四川熊猫基地
2020/01/13 职场文书
HTML怎么设置下划线?html文字加下划线方法
2021/12/06 HTML / CSS