下面把角色分为两种,普通用户和管理员用户,至少对于普通用户来说,直接修改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 "修改用户表"

回车后界面显示内容为:

然后进行db差异的改动

python default.py db upgrade

这时看db中的表结构:

已经修改成功

注册界面

然后新建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">&times</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")

代码有点啰嗦,不漂亮,但基本意图能表达清楚,功能也可以实现,但现在的问题来了,加入我新增一个字段,那么需要修改三处代码(html,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">&times</button>
{{message}}
</div>
{% endfor %}
{{ wtf.quick_form(form)}} <!--创建表单-->
</div>
</div>
</div>
{% endblock %}

执行,输出结果:

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

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

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

秘钥字符串可自定义

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

并且包含验证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方法

好运行测试一下

点击提交:

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

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,然后点击提交:

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

记录正常进入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">&times</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后,成功登录首页

回到首页

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

一个web应用的诞生(5)--数据表单的更多相关文章

  1. 一个web应用的诞生(4)--数据存储

    上一章实现了登录的部分功能,之所以说是部分功能,是因为用户名和密码写成固定值肯定是不可以的,一个整体的功能,至少需要注册,登录,密码修改等,这就需要提供一个把这些值存储到数据库的能力. 当前的主流数据 ...

  2. Web标准:九、CSS表单设计

    Web标准:九.CSS表单设计 知识点: 1.改变文本框和文本域样式 2.用图片美化按钮 3.改变下拉列表样式 4.用label标签提升用户体验   1)改变文本框和文本域样式 文本框标签:<i ...

  3. 一个web应用的诞生--数据表单

    下面把角色分为两种,普通用户和管理员用户,至少对于普通用户来说,直接修改DB是不可取的,要有用户注册的功能,下面就开始进行用户注册的开发. 用户表 首先要想好用户注册的时候需要提供什么信息:用户名.密 ...

  4. 一个web应用的诞生--数据存储

    上一章实现了登录的部分功能,之所以说是部分功能,是因为用户名和密码写成固定值肯定是不可以的,一个整体的功能,至少需要注册,登录,密码修改等,这就需要提供一个把这些值存储到数据库的能力. 当前的主流数据 ...

  5. 一个web应用的诞生(1)--初识flask

    基于flask的web应用的诞生 Flask是一个非常优秀的web框架,它最大的特点就是保持一个简单而易于扩展的小核心,其他的都有用户自己掌握,并且方便替换,甚至,你可以在社区看到众多开源的,可直接用 ...

  6. 一个web应用的诞生(4)

    上一章实现了登录的部分功能,之所以说是部分功能,是因为用户名和密码写成固定值肯定是不可以的,一个整体的功能,至少需要注册,登录,密码修改等,这就需要提供一个把这些值存储到数据库的能力. 当前的主流数据 ...

  7. 一个web应用的诞生(6)--用户账户

    之前登录注册的功能都已经完成,但是登录成功回到首页发现还是白茫茫的一片,对的,title一直都写得博客,那么最终目的也是写出一个轻博客来,但是,在发表文章之前是不是要先记录一下登录状态呢? 用户登录 ...

  8. 一个web应用的诞生(7)--结构调整

    现在所有的Py代码均写在default.py文件中,很明显这种方法下,一旦程序变的负责,那么无论对于开发和维护来说,都会带来很多问题. Flask框架并不强制要求项目使用特定的组织结构,所以这里使用的 ...

  9. 一个web应用的诞生(8)--博文发布

    这个系统一直号称轻博客,但貌似博客的功能还没有实现,这一章将简单的实现一个博客功能,首先,当然是为数据库创建一个博文表(models\post.py): from .. import db from ...

随机推荐

  1. 如何在Ubuntu中添加中文输入法

    首先打开终端,输入以下命令 打开终端输入以下命令 弹出设置IBus首选项对话框,单击输入法文本框,再单击添加按钮,选中汉语中的拼音,单击添加,设置完毕. 最后单击输入法图标的选项中的首选项中的拼音模式 ...

  2. SOE 部署错误 ClassFactory cannot supply requested class问题及解决方案

    一.问题描述 虽然SOE开发已经老早出来了(ArcGIS 10.1 不再支持DCOM开发,所以以往的基于AO+WebService需要转变思路),不过由于跟工作关联性不是很大,一直未系统学习过.网上下 ...

  3. 404 Note Found队-Alpha2

    目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:丹丹 组员7:家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示组内 ...

  4. Java clone() 浅克隆与深度克隆

    内容转自:http://www.blogjava.net/orangelizq/archive/2007/10/17/153573.html 现在Clone已经不是一个新鲜词语了,伴随着“多莉”的产生 ...

  5. 映射篇:request-String-Object-Map之间相互转化(程序员的成长之路---第5篇)

    为什么写这一篇 问题一:jdbc连接数据库返回的对象是ResultSet,如何把ResultSet对象中的值转换为我们自建的各种实体类? 我估计,80%的程序员会写jdbc数据库连接,但开发项目依然用 ...

  6. H5页面手机端禁止缩放的正确方式

    H5页面禁止手机端缩放是个常见问题了 首先说meta方式 <meta content="width=device-width, initial-scale=1.0, maximum-s ...

  7. Mybatis-smart(Mybatis最终优化方案)

    Hibernate: 我用了Hibernate一年多,可以说是饱经风雨,感受极深,Hibernate看似一个很好的框架,我简单说一下它的使用痛点, 1.作为开发人员,我们应该全新全意关注我们的功能业务 ...

  8. 修改 Hue 默认数据库

    Hue 更改默认数据 1. 需要安装 mysql 一下包 mysql-server mysql-devel mysql-shared mysql-client mysql-python shared ...

  9. ORACLE->SQL*Loader[20180712]

    https://docs.oracle.com/cd/B28359_01/server.111/b28319/ldr_concepts.htm#g1013706       SQL*Loader将外部 ...

  10. jquery里操作json相关的方法和实例

    $.getJSON("/html/aijquery/JSON.js",function(d){     $.each(d,function(i,v){             $( ...