热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

web.py开发web第八章Formalchemy服务端验证方法

本文介绍了在web.py开发中使用Formalchemy进行服务端表单数据验证的方法。以User表单为例,详细说明了对各字段的验证要求,包括必填、长度限制、唯一性等。同时介绍了如何自定义验证方法来实现验证唯一性和两个密码是否相等的功能。该文提供了相关代码示例。



2019独角兽企业重金招聘Python工程师标准>>> 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, FieldSet
from customEngine import Jinja2Engine
from 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, middleware
from web.contrib.template import render_jinja
from models import *
from forms import *
import sys
reload(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.orm
class 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



推荐阅读
  • Python3爬虫入门:pyspider的基本使用[python爬虫入门]
    Python学习网有大量免费的Python入门教程,欢迎大家来学习。本文主要通过爬取去哪儿网的旅游攻略来给大家介绍pyspid ... [详细]
  • 使用Python构建网页版图像编辑器
    本文详细介绍了一款基于Python开发的网页版图像编辑工具,具备多种图像处理功能,如黑白转换、铅笔素描效果等。 ... [详细]
  • 本文介绍了如何使用 Python 的 Pyglet 库加载并显示图像。Pyglet 是一个用于开发图形用户界面应用的强大工具,特别适用于游戏和多媒体项目。 ... [详细]
  • MVC模式下的电子取证技术初探
    本文探讨了在MVC(模型-视图-控制器)架构下进行电子取证的技术方法,通过实际案例分析,提供了详细的取证步骤和技术要点。 ... [详细]
  • 本文探讨了使用Python实现监控信息收集的方法,涵盖从基础的日志记录到复杂的系统运维解决方案,旨在帮助开发者和运维人员提升工作效率。 ... [详细]
  • 本文回顾了作者在求职阿里和腾讯实习生过程中,从最初的迷茫到最后成功获得Offer的心路历程。文中不仅分享了个人的面试经历,还提供了宝贵的面试准备建议和技巧。 ... [详细]
  • binlog2sql,你该知道的数据恢复工具
    binlog2sql,你该知道的数据恢复工具 ... [详细]
  • 本文介绍了如何使用Node.js通过两种不同的方法连接MongoDB数据库,包括使用MongoClient对象和连接字符串的方法。每种方法都有其特点和适用场景,适合不同需求的开发者。 ... [详细]
  • Python网络编程:深入探讨TCP粘包问题及解决方案
    本文详细探讨了TCP协议下的粘包现象及其产生的原因,并提供了通过自定义报头解决粘包问题的具体实现方案。同时,对比了TCP与UDP协议在数据传输上的不同特性。 ... [详细]
  • 本文由chszs撰写,详细介绍了Apache Mina框架的核心开发流程及自定义协议处理方法。文章涵盖从创建IoService实例到协议编解码的具体步骤,适合希望深入了解Mina框架应用的开发者。 ... [详细]
  • 笔记说明重学前端是程劭非(winter)【前手机淘宝前端负责人】在极客时间开的一个专栏,每天10分钟,重构你的前端知识体系& ... [详细]
  • 本文基于Java官方文档进行了适当修改,旨在介绍如何实现一个能够同时处理多个客户端请求的服务端程序。在前文中,我们探讨了单客户端访问的服务端实现,而本篇将深入讲解多客户端环境下的服务端设计与实现。 ... [详细]
  • 深入解析Unity3D游戏开发中的音频播放技术
    在游戏开发中,音频播放是提升玩家沉浸感的关键因素之一。本文将探讨如何在Unity3D中高效地管理和播放不同类型的游戏音频,包括背景音乐和效果音效,并介绍实现这些功能的具体步骤。 ... [详细]
  • 随着Linux操作系统的广泛使用,确保用户账户及系统安全变得尤为重要。用户密码的复杂性直接关系到系统的整体安全性。本文将详细介绍如何在CentOS服务器上自定义密码规则,以增强系统的安全性。 ... [详细]
  • Asynchronous JavaScript and XML (AJAX) 的流行很大程度上得益于 Google 在其产品如 Google Suggest 和 Google Maps 中的应用。本文将深入探讨 AJAX 在 .NET 环境下的工作原理及其实现方法。 ... [详细]
author-avatar
郭怡如珮尧琼江
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有