博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
web.py开发web 第八章 Formalchemy 服务端验证
阅读量:7068 次
发布时间:2019-06-28

本文共 4691 字,大约阅读时间需要 15 分钟。

hot3.png

    上一章讲了如何使用formalchemy+jinja2创建表单,这一章将要讲formalchemy在服务器端怎么对表单数据验证。我们用前面的User表单来进行举例,User中有几个地方需要验证,下面一一列出来:

  1. name字段必填且数据库内唯一,长度不小于6,不大于20。
  2. email字段必填且数据库内唯一,且为email格式,长度不大于32。
  3. password必填,长度不小于6,不大于32。
  4. confirm password必填且必须与password相等,长度不小于6,不大于32。

    以上为针对User表单需要验证的内容,验证需求中的必填/长度限制在formalchemy的validator中已经内建,那么验证唯一和验证两个password是否相等还需要我们自定义下验证方法,这里是formalchemy关于自定义验证方法的,下面上这两个自定义方法的代码,先在app根目录下创建一个customValidators.py用于存放自定义的验证方法。

customValidators.py

#-*- coding: utf-8 -*-from formalchemy import ValidationError#检验两个字段的值是否相等def customEqual(equal_field, message):    def check(value, field):        if field.is_required() or (not field.is_required() and value):            if getattr(field.parent, equal_field).value != value:                raise ValidationError(message)    return check#检验字段值在数据库中是否唯一,并可设置是否忽略自身值,这在编辑已有信息的时候验证唯一非常有用def customUnique(session, message="此数据已存在", checkSelf=False):    def check(value, field):        model = field.model.__class__        if checkSelf:            query = session.query(model).filter(                (getattr(model, field.name)==value) &                (model.id!=field.model.id)            ).first()        else:            query = session.query(model).filter(getattr(model, field.name)==value).first()        if query:            raise ValidationError(message)    return check
     接下来让我们修改上一章的forms.py,把验证信息加入进去。
forms.py
#-*- coding:utf-8 -*-from formalchemy import config, validators, Field, FieldSetfrom customEngine import Jinja2Enginefrom models import *from customValidators import *class UserForm:    def __init__(self):        #这里的directories是指表单模板存放的地方,我们在第二章提到的templates下创建一个文件夹,命名为form        config.engine = Jinja2Engine(directories=["templates/form"])    #为表单设置label    def setLabel(self):        self.name = self.fs.name.label("User Name")        self.email = self.fs.email.label("Email Address")        self.password = self.fs.password.label("Password")        self.superuser = self.fs.superuser.label("Admin?")    #定义编辑模式下通用的设置,编辑模式包括:新增,修改    def wmode(self, password=None):        self.setLabel()        #因为新增和修改中都需要用户重新确认密码,所以要为表单加入Confirm Password        #如果有指定password的值,说明用户是在修改记录,那么Confirm Password也必须有值        if not password:            self.fs.insert_after(self.fs.password, Field("confirm_password"))        else:            self.fs.insert_after(self.fs.password, Field("confirm_password", value=password))        self.confirm_password = self.fs.confirm_password.label("Re-enter Password")        self.name = self.name.required().validate(            validators.length(min=6, max=20)        )        self.email = self.email.required().email().validate(            validators.email        ).validate(            validators.maxlength(32)        )        self.password = self.password.required().password().validate(            validators.length(min=6, max=32)        )        self.confirm_password = self.confirm_password.required().password().validate(            validators.length(min=6, max=32)        ).validate(            customEqual("password", "密码前后不一致")        )    #定义新增用户时调用的方法    def write_render(self, cls):        #设置Fieldset对象,指定要绑定的sqlalchemy中的表类,并赋予sqlalchemy的session        self.fs = FieldSet(User, session=cls.db)        self.wmode()        #配置表单信息        self.fs.configure(            #表单包含的字段            include=[                self.name.validate(customUnique(cls.db)),                self.email.validate(customUnique(cls.db)),                self.password,                self.confirm_password            ]        )        return self.fs
     为了触发验证,需要提交表单,我们为main.py的showform类添加POST方法,main.py整体修改如下。

main.py

#-*- coding:utf-8 -*-import web, middlewarefrom web.contrib.template import render_jinjafrom models import *from forms import *import sysreload(sys)sys.setdefaultencoding("utf-8")urls = (    "/", "index",    "/form/", "showform",)app = web.application(urls, globals())app.add_processor(middleware.set_orm)render = render_jinja(    'templates',    encoding = 'utf-8',)class BaseView(object):    def __init__(self):        #从web.ctx.orm获取session放入基类的db中        self.db = web.ctx.ormclass index(BaseView):    def GET(self):        return render.index()class showform(BaseView):    def __init__(self):        super(showform, self).__init__()        form = UserForm()        self.fs = form.write_render(self)    def GET(self):        return render.form(form=self.fs)    def POST(self):        data = web.input()        self.fs.rebind(data=data)        if self.fs.validate():            self.fs.sync()            return "success"        return render.form(form=self.fs)if __name__ == "__main__":    app.run()
     下面运行main.py,访问/form/,用各种不规则的数据提交吧,看看验证是否都有作用:)

转载于:https://my.oschina.net/zhengnazhi/blog/122391

你可能感兴趣的文章
NoSuchMethodError: org.hibernate.SessionFactory.openSession
查看>>
textarea自动调整高宽
查看>>
python基础---面向对象高级
查看>>
vim的分屏
查看>>
windows客户端安装
查看>>
关于大型网站技术演进的思考(十八)--网站静态化处理—反向代理(10)
查看>>
Centos7怎么安装gnome桌面及远程桌面VNC
查看>>
mount挂载报错mount:you must specify the filesystem type
查看>>
yaf 模块与控制器
查看>>
Python 模块调用和global的用法
查看>>
Ubuntu 12.04 修改/etc/resolv.conf重启后还原成修改前状态解决办法
查看>>
Python—redis
查看>>
HPE牵手DDN打造整合的高性能服务器存储产品组合
查看>>
mycat分片规则之范围约定规则(auto-sharding-long)
查看>>
windows配置java环境变量
查看>>
python流程处理
查看>>
<kubernetes in action>看书笔记
查看>>
python密码破解工具patator
查看>>
众筹网站Kickstarter不准备上市:转型公益企业
查看>>
OpenStack入门修炼之nova服务(计算节点)的部署与测试(11)
查看>>