博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
web.py开发web 第七章 Formalchemy + Jinja2
阅读量:7053 次
发布时间:2019-06-28

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

hot3.png

    formalchemy是一个强大的表单表格生成框架,几乎所有的动态web开发里都需要处理form表单,而form表单要处理的几个方面包括:表单展现,表单服务端验证,表单前端验证(既js验证),表单数据插入数据库。formalchemy在这几方面都做的非常好,特别是对掌控欲特别强又很懒的人来说:)。由于formalchemy是跟sqlalchemy是配套的(两者名字是如此相似),所以我们可以很好的与前面所创建的User表关联起来。

    这一章我们要解决的是关于form的展现,formalchemy自身支持三种template engine,分别是:mokogenshitempita,除了mako我没用过,另外两个我都用过了,老实说,不怎么样,但是formalchemy为我们这种有需求的人提供了解决方案,customize templates,这里我要介绍的就是用jinja2定制一个让我们随便玩的template engine,上代码。
customEngine.py

#-*- coding:utf-8 -*-from formalchemy import templatesfrom jinja2 import Environment,FileSystemLoader#定义一个方法用来获取formalchemy输出input的name属性def field_label(field):    return field.parent._format % dict([('model',field.model.__class__.__name__), ('pk',field.parent.model.id or ''), ('name',field.name)])#定义一个方法用来获取formalchemy中定义字段的labeldef field_name(field):    return field.label_text or field.nameclass Jinja2Engine(templates.TemplateEngine):    extension = 'jinja2'    def get_template(self, name, **kw):        self._lookup = Environment(loader=FileSystemLoader(self.directories, **kw))        self._lookup.filters.update(            #如果你想要在模板里添加filter,可以在这里添加            field_label = field_label,            field_name = field_name,        )        #增加这个扩展可以让我们在模板的循环块里使用break,continue        self._lookup.add_extension('jinja2.ext.loopcontrols')        #增加这个扩展可以让我们在模板里使用do关键字,用来进行一些python语句操作        self._lookup.add_extension('jinja2.ext.do')        return self._lookup.get_template("%s.%s" % (name, self.extension))    def render(self, template_name, **kwargs):        template = self._lookup.get_template("%s.%s" % (template_name, self.extension))        return template.render(**kwargs)

     以上代码是通过重载formalchemy的TemplateEngine来实现一个定制的Engine,下面是如何调用这个Engine,代码中结合上一章的User表为例。

forms.py

#-*- coding:utf-8 -*-from formalchemy import config, validators, Field, FieldSetfrom customEngine import Jinja2Enginefrom models 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()        self.email = self.email.required().email().validate(validators.email)        self.password = self.password.required().password()        self.confirm_password = self.confirm_password.required().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,                self.email,                self.password,                self.confirm_password            ]        )        return self.fs
    ok,接下来我们要制作一个模板用来展现表单,只要没啥特殊改变,整个项目都可以使用这个模板,这里我们还是使用bootstrap来渲染页面,首先我们在templates目录下创建form目录,form目录中创建一个fieldset.jinja2,fieldset_readonly.jinja2,grid.jinja2,grid_readonly.jinja2,fieldset.jinja2为表单模板,这一章我们只讲fieldset.jinja2,下面是fieldset.jinja2代码。
fieldset.jinja2
{%- if fieldset.errors %}    
{% for field in fieldset.errors %}

{ field|field_name }}:

{% for e in field.errors %}

{

{ e }}

{% endfor %}

{% endfor %}
{% endif -%}{% for field in fieldset.render_fields.itervalues() %} {% if field.requires_label %}
{% if field.is_required() %} {
{ field.with_html(required_='required').render() }} {% else %} {
{ field.render() }} {% endif %} {% if 'instructions' in field.metadata %} {% if field.metadata["instructions"] is iterable %} {% for i in field.metadata["instructions"] %}

{

{ i }}

{% endfor %} {% else %}

{

{ field.metadata["instructions"] }}

{% endif %} {% endif %}
{% else %} {
{ field.render() }} {% endif %}{% endfor %}
main.py
#-*- coding:utf-8 -*-import web, middlewarefrom web.contrib.template import render_jinjafrom models import *from forms import *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 GET(self):        form = UserForm()        fs = form.write_render(self)        return render.form(form=fs)if __name__ == "__main__":    app.run()

    最后在templates目录中添加form.html

form.html

        
{
{ form.render() }}

    运行main.py,然后访问/form/页面,看看是不是出来了一个整齐的表单:)

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

你可能感兴趣的文章
ubuntu快捷键
查看>>
IOS——生成智能调试输出
查看>>
杀毒软件Avast被曝严重的0day漏洞
查看>>
NDK Caused by: java.lang.UnsatisfiedLinkError:
查看>>
oracle timestamp相减
查看>>
【swing】 BoxLayout布局
查看>>
Android 属性动画(Property Animation)完全解析 (下)
查看>>
GC overhead limit exceeded
查看>>
JDBC学习之三
查看>>
CSS3 渐变(Gradients)
查看>>
Windows7关机、重启、待机、休眠命令
查看>>
如何在Xcode8上安装插件
查看>>
Java Base
查看>>
mysql优化sql语句查询的方法(一)
查看>>
既然存在,就是合理的
查看>>
【GIT-1】GIT 的基础教程 创建,添加,更替,追溯版本库
查看>>
【原创】公司自研缓存系统UPU的总结
查看>>
一个JavaScript的简单通用验证
查看>>
phpstorm 安装 及 使用 去掉名称类型提示
查看>>
Xp sp3 创建进程的堆栈
查看>>