一个基于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自动化构建工具scons使用入门笔记
Mar 10 Python
全面理解Python中self的用法
Jun 04 Python
Python简单生成随机姓名的方法示例
Dec 27 Python
十分钟利用Python制作属于你自己的个性logo
May 07 Python
获取python的list中含有重复值的index方法
Jun 27 Python
python读取各种文件数据方法解析
Dec 29 Python
Python学习笔记之视频人脸检测识别实例教程
Mar 06 Python
opencv python在视屏上截图功能的实现
Mar 05 Python
django 装饰器 检测登录状态操作
Jul 02 Python
使用OpenCV实现道路车辆计数的使用方法
Jul 15 Python
详解Selenium-webdriver绕开反爬虫机制的4种方法
Oct 28 Python
基于Python爬取搜狐证券股票过程解析
Nov 18 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
PHP 关于访问控制的和运算符优先级介绍
2013/07/08 PHP
PHP入门之常量简介和系统常量
2014/05/12 PHP
php使用标签替换的方式生成静态页面
2015/05/21 PHP
PHP实现计算器小功能
2020/08/28 PHP
控制打印时页眉角的代码
2007/02/08 Javascript
javascript实现的动态文字变换
2007/07/28 Javascript
根据出生日期自动取得星座的js代码
2010/07/20 Javascript
jQuery实现行文字链接提示效果的方法
2015/03/10 Javascript
手机端转盘抽奖代码分享
2015/09/10 Javascript
js命名空间写法示例
2015/12/18 Javascript
JS使用正则表达式实现关键字替换加粗功能示例
2016/08/03 Javascript
jQuery的deferred对象使用详解
2016/09/25 Javascript
jquery做个日期选择适用于手机端示例
2017/01/10 Javascript
详解Angularjs在控制器(controller.js)中使用过滤器($filter)格式化日期/时间实例
2017/02/17 Javascript
Vue-Router实现组件间跳转的三种方法
2017/11/07 Javascript
使用React代码动态生成栅格布局的方法
2020/05/24 Javascript
vue a标签点击实现赋值方式
2020/09/07 Javascript
[42:48]完美世界DOTA2联赛PWL S3 Magma vs INK ICE 第二场 12.11
2020/12/16 DOTA
跟老齐学Python之集合的关系
2014/09/24 Python
jupyter notebook引用from pyecharts.charts import Bar运行报错
2020/04/23 Python
python 列表中[ ]中冒号‘:’的作用
2019/04/30 Python
python3实现猜数字游戏
2020/12/07 Python
python爬取盘搜的有效链接实现代码
2019/07/20 Python
使用python写的opencv实时监测和解析二维码和条形码
2019/08/14 Python
Python实现检测文件的MD5值来查找重复文件案例
2020/03/12 Python
Python实现读取并写入Excel文件过程解析
2020/05/27 Python
澳大利亚头发和美容产品购物网站:OZ Hair & Beauty
2020/03/27 全球购物
师范生自荐信范文
2013/10/06 职场文书
工程项目建议书范文
2014/03/12 职场文书
中队活动总结
2014/08/27 职场文书
党员评议表自我评价范文
2014/10/20 职场文书
2014幼儿园中班工作总结
2014/11/10 职场文书
2015年资料员工作总结
2015/04/25 职场文书
单位提档介绍信
2015/10/22 职场文书
初中信息技术教学反思
2016/02/16 职场文书
如何避免mysql启动时错误及sock文件作用分析
2022/01/22 MySQL