zoukankan      html  css  js  c++  java
  • deform表单

    安装deform

    pip install pyramid_deform
    pip install js.deform

    deform表单库介绍

    与pyramid同属Pylons Project表单库

    Colander:定义表单结构

    Peppercom:序列化和反序列化

    Chameleon:模板引擎

    development.ini里导入pyramid_deform

    [app:main]
    use = egg:MyShop
    
    pyramid.reload_templates = true
    pyramid.debug_authorization = true
    pyramid.debug_notfound = false
    pyramid.debug_routematch = false
    pyramid.default_locale_name = en
    pyramid.includes =
        pyramid_debugtoolbar
        pyramid_tm
        pyramid_layout
        pyramid_deform

    创建lib/deforms.py文件

    # -*- coding:UTF-8 -*-
    import colander
    import deform
    from js.deform import deform as deform_static
    
    class LoginFormSchema(colander.MappingSchema):  # 定义一个LoginFormSchema表单结构 MappingSchema表示一个映射类型
        username = colander.SchemaNode(colander.Str())  # colander.SchemaNode相当于定义的Column
        password = colander.SchemaNode(colander.Str(),
                                       widget=deform.widget.PasswordWidget()  # 使密码密文显示
                                       )
        email = colander.SchemaNode(colander.Str(),
                                    validator=colander.Email()  # 验证器 验证邮箱是否合法
                                    )

    在需要的视图views里导入

    如login.py中

    # -*- coding:UTF-8 -*-
    from pyramid.response import Response
    from pyramid.view import view_config, view_defaults
    from pyramid.httpexceptions import HTTPFound, HTTPBadRequest, HTTPServerError, 
        HTTPForbidden, HTTPUnauthorized
    from pyramid.security import remember, forget
    from myshop.lib import category, user, deforms
    from base import CBase
    
    ctrl = 'login'
    
    # @view_config(route_name='home', renderer='templates/mytemplate.pt')
    @view_defaults(route_name='/')
    class login(CBase):
        def __init__(self, request):
            CBase.__init__(self, request)
            self.request.title = u'登录'
    
        @view_config(match_param=('ctrl=%s' % ctrl, 'action=view'),
                     renderer="login.html")
                     # renderer="string")
        def view(self):
            deforms.deform_static.need()  # 使用deform必须步骤
            schema = deforms.LoginFormSchema()  # 声明一个schema
            # 声明一个表单
            form = deforms.deform.Form(schema,
                                       buttons=('submit',))  # 表单上需要哪些按钮
     
            return {
                'title':'login',
                'form':form.render(),  #显示表单
            }

    模板login.html中显示声明的表单

    <%inherit file="layout/login_base.html"/>
    <%block name="log_c">
        <div class="log_c">
            ${form | n}
        </div>
    </%block>

    显示如下:

     后台验证表单

    # -*- coding:UTF-8 -*-
    from pyramid.response import Response
    from pyramid.view import view_config, view_defaults
    from pyramid.httpexceptions import HTTPFound, HTTPBadRequest, HTTPServerError, 
        HTTPForbidden, HTTPUnauthorized
    from pyramid.security import remember, forget
    from myshop.lib import category, user, deforms
    from base import CBase
    
    ctrl = 'login'
    
    # @view_config(route_name='home', renderer='templates/mytemplate.pt')
    @view_defaults(route_name='/')
    class login(CBase):
        def __init__(self, request):
            CBase.__init__(self, request)
            self.request.title = u'登录'
    
        @view_config(match_param=('ctrl=%s' % ctrl, 'action=view'),
                     renderer="login.html")
                     # renderer="string")
        def view(self):
            deforms.deform_static.need()  # 使用deform必须步骤
            schema = deforms.LoginFormSchema()  # 声明一个schema
            # 声明一个表单
            form = deforms.deform.Form(schema,
                                       buttons=('submit',))  # 表单上需要哪些按钮
    
            if 'submit' in self.request.POST:
                try:
                    appstruct = form.validate(self.request.POST.items())  # 对用户提交的内容进行有效性验证
                except deforms.deform.ValidationFailure, e:
                    return {
                        'title':'login',
                        'form':e.render()  # 如果校验失败会提示错误信息
                    }
                user_info = user.get_user_by_name(name=appstruct['username'])  # appstruct['username'] 获取表单的username
                if not user_info:
                    return {
                        'title': 'login',
                        'form': form.render(),
                    }
                if user_info.password != appstruct['password']:  # 获取form传过来的密码
                    return {
                        'title': 'login',
                        'form': form.render(),
                    }
                headers = remember(self.request, user_info.id)
                return HTTPFound(location='/', headers=headers)
    
            return {
                'title':'login',
                'form':form.render(),  #显示表单
            }

     自定义验证器验证

    1.用户名验证--字段级别验证 node

    自定义验证器lib/validators.py

    # -*- coding:UTF-8 -*-
    import colander
    import deform
    from myshop.lib import user
    
    def username_validator(node, value):
        user_info = user.get_user_by_name(name=value)
        if not user_info:
            raise colander.Invalid(node, u'用户名%s不存在' % value)

    deforms.py中导入验证器

    # -*- coding:UTF-8 -*-
    import colander
    import deform
    from js.deform import deform as deform_static
    import validators
    
    class LoginFormSchema(colander.MappingSchema):  # 定义一个LoginFormSchema表单结构 MappingSchema表示一个映射类型
        username = colander.SchemaNode(colander.Str(),  # colander.SchemaNode相当于定义的Column
                                       validator = validators.username_validator  # 用自定义的验证器验证数据
                                       )

    视图函数login.py中验证用户是否存在可以删除了,在验证器中验证

            if 'submit' in self.request.POST:
                try:
                    appstruct = form.validate(self.request.POST.items())  # 对用户提交的内容进行有效性验证
                except deforms.deform.ValidationFailure, e:
                    return {
                        'title':'login',
                        'form':e.render()  # 如果校验失败会提示错误信息
                    }
                user_info = user.get_user_by_name(name=appstruct['username'])
                # if not user_info:
                #     return {
                #         'title': 'login',
                #         'form': form.render(),
                #     }

    2.密码验证--表单级别验证 form

    lib/validators.py声明一个password_validator

    def password_validator(form, value):
        username = value['username']
        password = value['password']
        user_info = user.get_user_by_name(name=username)
        if user_info.password != password:
            raise colander.Invalid(form, u'用户名密码不正确')

    视图函数login.py中声明Schema对象时应用表单验证

    # -*- coding:UTF-8 -*-
    from pyramid.response import Response
    from pyramid.view import view_config, view_defaults
    from pyramid.httpexceptions import HTTPFound, HTTPBadRequest, HTTPServerError, 
        HTTPForbidden, HTTPUnauthorized
    from pyramid.security import remember, forget
    from myshop.lib import category, user, deforms, validators
    from base import CBase
    
    ctrl = 'login'
    
    # @view_config(route_name='home', renderer='templates/mytemplate.pt')
    @view_defaults(route_name='/')
    class login(CBase):
        def __init__(self, request):
            CBase.__init__(self, request)
            self.request.title = u'登录'
    
        @view_config(match_param=('ctrl=%s' % ctrl, 'action=view'),
                     renderer="login.html")
                     # renderer="string")
        def view(self):
            deforms.deform_static.need()  # 使用deform必须步骤
            schema = deforms.LoginFormSchema(validator=validators.password_validator)  # 声明一个schema   # validator指定表单级别验证
            # 声明一个表单
            form = deforms.deform.Form(schema,
                                       buttons=('submit',),  # 表单上需要哪些按钮
    
                                       )
    
            if 'submit' in self.request.POST:
                try:
                    appstruct = form.validate(self.request.POST.items())  # 对用户提交的内容进行有效性验证
                except deforms.deform.ValidationFailure, e:
                    return {
                        'title':'login',
                        'form':e.render()  # 如果校验失败会提示错误信息
                    }

     此上不难看出,重复查询user_info的次数过多,如何能一次查询多次使用

    定义TypeUser(),这里我直接在lib/deforms.py中定义了 也可以另写

    # -*- coding:UTF-8 -*-
    import colander
    import deform
    from js.deform import deform as deform_static
    import validators
    
    from myshop.models import User
    from myshop.lib import user
    
    class TypeUser(object):
        def serialize(self, node, appstruct):  # 序列化给表单
            if appstruct is colander.null:  # 固定用法,如果colander为null 则返回null
                return colander.null
            if not isinstance(appstruct, User):  # 判断appstruct类型与数据库的User类型是否相同
                raise colander.Invalid(node, u'用户类型%r不正确' % appstruct)
            return appstruct.name
        def deserialize(self, node, cstruct):  # 表单反序列化给后台
            if cstruct is colander.null:
                return colander.null
            if not isinstance(cstruct, basestring):
                raise colander.Invalid(node, u'用户%r格式不正确' % cstruct)
    
            user_info = user.get_user_by_name(name=cstruct)
            if not user_info:
                raise colander.Invalid(node, u'用户%s不存在' % cstruct)
            return user_info

    这样appstruct['username']就是user_info数据了

    validators.py中密码验证要改动

    def password_validator(form, value):
        user_info = value['username']
        password = value['password']
        # user_info = user.get_user_by_name(name=username)  # 如果自定义TypeUser的话 不需要多次查询数据库
        if user_info.password != password:
            raise colander.Invalid(form, u'用户名密码不正确')

    同理,login.py中查询user数据也可以删掉了

     @view_config(match_param=('ctrl=%s' % ctrl, 'action=view'),
                     renderer="login.html")
                     # renderer="string")
        def view(self):
            deforms.deform_static.need()  # 使用deform必须步骤
            schema = deforms.LoginFormSchema(validator=validators.password_validator)  # 声明一个schema   # validator指定表单级别验证
            # 声明一个表单
            form = deforms.deform.Form(schema,
                                       buttons=('submit',),  # 表单上需要哪些按钮
                                       )
    
            if 'submit' in self.request.POST:
                try:
                    appstruct = form.validate(self.request.POST.items())  # 对用户提交的内容进行有效性验证
                except deforms.deform.ValidationFailure, e:
                    return {
                        'title':'login',
                        'form':e.render()  # 如果校验失败会提示错误信息
                    }
                # user_info = user.get_user_by_name(name=appstruct['username'])
                user_info = appstruct['username']  # 直接把user数据赋值给user_info
                headers = remember(self.request, user_info.id)
                return HTTPFound(location='/', headers=headers)

     OK 跟之前一样登录

  • 相关阅读:
    [Python] 登录人人网2011版
    [WPF] 自定义窗体样式
    [Python] 控制台输入密码的方法
    [Python] 字符串加密解密
    [WPF] 模仿AMD LIVE! EXPLORER界面
    [Python] Visual Studio 2008 集成 IronPython 开发环境
    mysql表类型(存储引擎)
    logstash收集nginx访问日志
    linux设置开机启动脚本
    logstash安装log4j插件
  • 原文地址:https://www.cnblogs.com/yifengs/p/12274788.html
Copyright © 2011-2022 走看看