一个基于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的Flask框架中web表单的教程
Apr 20 Python
python3 模拟登录v2ex实例讲解
Jul 13 Python
Python读csv文件去掉一列后再写入新的文件实例
Dec 28 Python
Python中使用__new__实现单例模式并解析
Jun 25 Python
解决Python3 抓取微信账单信息问题
Jul 19 Python
Django 缓存配置Redis使用详解
Jul 23 Python
python实现登录密码重置简易操作代码
Aug 14 Python
python3 pathlib库Path类方法总结
Dec 26 Python
使用Python来做一个屏幕录制工具的操作代码
Jan 18 Python
Python中import导入不同目录的模块方法详解
Feb 18 Python
利用python实现逐步回归
Feb 24 Python
Django 实现对已存在的model进行更改
Mar 28 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
wordpress之wp-settings.php
2007/08/17 PHP
php 将bmp图片转为jpg等其他任意格式的图片
2009/06/21 PHP
用PHP将网址字符串转换成超链接(网址或email)
2010/05/25 PHP
PHP中ltrim()函数的用法与实例讲解
2019/03/28 PHP
Jquery 常用方法经典总结
2010/01/28 Javascript
javascript向flash swf文件传递参数值注意细节
2012/12/11 Javascript
jquery实现兼容浏览器的图片上传本地预览功能
2013/10/14 Javascript
Javascript快速排序算法详解
2014/12/03 Javascript
JS、jQuery中select的用法详解
2016/04/21 Javascript
JS实现可编辑的后台管理菜单功能【附demo源码下载】
2016/09/13 Javascript
js实现手机发送验证码功能
2017/03/13 Javascript
JS实现无缝循环marquee滚动效果
2017/05/22 Javascript
详解webpack 如何集成第三方js库
2017/06/29 Javascript
简单实现js拖拽效果
2017/07/25 Javascript
详解Axios统一错误处理与后置
2018/09/26 Javascript
JS使用栈判断给定字符串是否是回文算法示例
2019/03/04 Javascript
使用vue自定义指令开发表单验证插件validate.js
2019/05/23 Javascript
Jquery动态列功能完整实例
2019/08/30 jQuery
一次微信小程序内地图的使用实战记录
2019/09/09 Javascript
[09:59]DOTA2-DPC中国联赛2月7日Recap集锦
2021/03/11 DOTA
Python根据区号生成手机号码的方法
2015/07/08 Python
浅谈python字符串方法的简单使用
2016/07/18 Python
利用python获取当前日期前后N天或N月日期的方法示例
2017/07/30 Python
python数字图像处理之高级形态学处理
2018/04/27 Python
Django实现登录随机验证码的示例代码
2018/06/20 Python
对python3新增的byte类型详解
2018/12/04 Python
python根据文章标题内容自动生成摘要的实例
2019/02/21 Python
详解django+django-celery+celery的整合实战
2019/03/19 Python
python 发送json数据操作实例分析
2019/10/15 Python
关于windows下Tensorflow和pytorch安装教程
2020/02/04 Python
Helly Hansen工作服美国官方网上商店:为最恶劣的环境
2019/09/04 全球购物
XMLHttpRequest对象在IE和Firefox中创建方式有没有不同
2016/03/23 面试题
销售人员工作自我评价
2014/09/21 职场文书
高中教师个人工作总结
2015/02/10 职场文书
2015年档案室工作总结
2015/05/23 职场文书
JS前端可视化canvas动画原理及其推导实现
2022/08/05 Javascript