• 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 跟之前一样登录

  • 相关阅读:
    中国历史朝代公元对照简表
    [Solved] DashBoard – Excel Service: The data sources may be unreachable, may not be responding, or may have denied you access.
    Delete/Remove Project from TFS 2010
    Sharepoint site showing system account instead of my username on the top right corner.
    你的成功在于你每天养成的习惯
    Internet Information Services is running in 32bit emulation mode. Correct the issue listed above and rerun setup.
    Prepare to back up and restore a farm (Office SharePoint Server 2007)
    Word中字号与磅值的对应关系
    How to: Change the Frequency for Refreshing the Data Warehouse for Team System
    UI Automation in WPF/Silverlight
  • 原文地址:https://www.cnblogs.com/yifengs/p/12274788.html
Copyright © 2020-2023  润新知