Your SlideShare is downloading. ×
Uliweb比较与实践 2013
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×

Saving this for later?

Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime - even offline.

Text the download link to your phone

Standard text messaging rates apply

Uliweb比较与实践 2013

1,680
views

Published on

在 pycon china beijing 大会上的演讲,关于uliweb和其它框架的一些比较,以及uliweb的一些特色功能介绍

在 pycon china beijing 大会上的演讲,关于uliweb和其它框架的一些比较,以及uliweb的一些特色功能介绍

Published in: Education

1 Comment
0 Likes
Statistics
Notes
  • 支持!可惜没有看到和 Pyramid 的比较~是时间不够来不及吗?一个非常好的消息是现在这些常用框架的文档都是很详尽和更新及时的~
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
  • Be the first to like this

No Downloads
Views
Total Views
1,680
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
5
Comments
1
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide
  • 2013年小结:介绍2013年uliweb的发展及去我做过的一些事情
    uliweb与其它框架比较:了解uliweb与常见其它框架之间的差异,为了更好的理解它们的设计与进行选择。选择了几个有代表性的框架
    特殊功能主要是介绍:uliweb一些有代表性的功能设计
  • 我们常说的框架,其实是软件框架,所以它首先是软件。
    框架里面有什么?
    框架和库的区别?
    为什么要有框架?
  • 我个人的答案是需要,但是如果没有合适的框架,那我们就创建一个出来
  • 这里我们主要比较:设计,常见功能
    不同的框架产生的时间,背景,思念都不相同
    比较可以了解框架间的差异,从而体会不同的设计思想,重点强调Uliweb的设计细节
    单纯的对比可能比较生硬,因此也有类似的代码间的比较
    FramewoksShow是比较早期,参与人很少
    TODO比较是自发的,可以大概了解不同的语言实现TODO的过程
  • APP的组织方式表示按模块来组织程序结构。自由并不表示不是模块化的,只不过可能会缺省一些针对APP的支持。同时,APP方式一般结构是固定的,如:static, templates目录的约定。django, uliweb都是配置化的,而Flask, Tornado都是要在程序中写的。
  • Uliweb是ini方式的,所以有section将配置信息分组。其它的不分组。
  • 分散定义的好处是为了方便复用
  • 分散定义的好处是为了方便复用
  • 这里方法是指当view是类时的情况。类则作为模板子目录。
  • 自动注入是指view函数。导入是一般函数。uliweb还提供了如json, redirect等的注入。
  • Form是指类似于django.Form, WTForms这样的库
  • django的模板中使用i18n是使用 trans 标签,其它的都支持 _() 函数
  • 通过functions实现定义与使用相分离
  • 统一函数提供了使用和定义相分离
  • 绿色:调用的参数
    红色:调者文件位置及函数
    紫色:explain输出
    记录了执行时间大于0.001秒及自动显示explain语句
    蓝色:记录了最终花费的时间
  • 黄色:执行总条数
    红色:URL紫色:explain输出
    记录了执行总行数,URL,以及按SQL划分的,每条不同的SQL执行的次数及花费时间
  • 实际的处理是:先编译成.py文件,use, link都将转为对应的函数,然后进行模板的渲染,在最后和动态插入到</head>之前。因此use, link可以在渲染前来保证调用的顺序。
  • find template会按照查找的顺序来显示。这里是有重名的模板,会使用最前一个。
  • tree可以查看include, extend的结构,箭头所指是当前模板的位置
  • Transcript

    • 1. Uliweb 比较与实践 -2013 李迎辉 (limodou@gmail.com) 2013/11/25
    • 2. 2013 年个人小结 Uliweb 与其它框架比较 Uliweb 的特殊功能介绍
    • 3. 2013 年个人小结 Uliweb 与其它框架比较 Uliweb 的特殊功能介绍
    • 4. • • • • • • • • • Uliweb 发布到 0.2.2 par 发布到 0.9.3 , parm 发布到 0.6 Win32-Process-Watcher 发布 定制 alembic 并与 Uliweb 集成 chatroom 实验使用 Uliweb+gevnet-socketio 写 的 websocket 的聊天程序 , wshell-web shell desktopnotify js 库,可以调浏览器 notification API 对 mmGrid 添加树,优化多行表头,无限翻页等 功能 尝试 python3 ,创建 2to6 项目 参加何家胜组织的 codepark 编程公园活动,组 织了 3 次全天的编程活动
    • 5. 2013 年个人小结 Uliweb 与其它框架比较 Uliweb 的特殊功能介绍
    • 6. 怎么理解框架?我们需要框架吗?
    • 7. ( 软件 ) 框架是经验的总结 框架是把设计思想 ( 模式 ) 、开发习 惯、常见功能组织在一起的一种 ** 软件 ** 使用框架要按框架的要求来组织代码 ,让框架来调 使用库则是由你来组织如何使用 使用框架表示你可能认同它的设计思 想
    • 8. 我们需要框架吗?
    • 9. http://wiki.woodpecker.org.cn/moin/FrameworksShow http://simple-is-better.com/news/309
    • 10. 第一个版本发布时间 第一个版本发布时间 8 2011.1 (1.0) 3 2008.12 (0.31) 6 2010.4 (0.1) 4 2009.10 (0.0.1) 时间 1 2005.11 (0.90) 2 2007.10 (1.8) 4 2009.10 (0.5.3) 7 2010.07 (1.0.0)
    • 11. V S
    • 12. 组织方式 组织方式 APP 自由,通过 Blueprint 来实现 APP 类似的功能 自由 APP 时间 - 组织
    • 13. 配置文件 配置文件 settings.py 自由 , 多种格式 支持,要先定义, py 文件 settings.ini, local_setings.ini, app 级别 settings.ini 时间 - 组织 - 配置文件
    • 14. 配置文件语法 配置文件语法 变量大写, Python 语法 变量大写, Python 语法,支持 类的写法 Python 语法 大小写都可以, Python 语法 时间 - 组织 - 配置文件
    • 15. 程序结构的创建 程序结构的创建 makeproject 手工 手工 makeproject, makeapp 时间 - 组织 - 配置文件 - 项 目
    • 16. URL 的定义 URL 的定义 集中式, urls.py ,可以 include ,正则式 在程序中分散定义,使用 decorator ,非正则 主程序中集中定义,正则式 在 views.py 中分散定义,使用 decorator ,同 flask 时间 - 组织 - 配置文件 - 项 目 -URL
    • 17. URL 的反向获取 URL 的反向获取 提供 url_for ,按名字获取 url_for, 按名字获取 reverse_url ,按名字 提供 url_for , url_for_static , 按名字获取 时间 - 组织 - 配置文件 - 项 目 -URL
    • 18. 模板 模板 支持 block ,代码受限,可以定 义 filter, tag jinjia2 ,类 django 模块,代码 限制较小 类 django ,但是可以嵌入 python 表达式,导入等 从 web2py 改造而来,支持 block ,可以直接嵌入 python , pass 表示缩近结束 时间 - 组织 - 配置文件 - 项 目 -URL- 模板
    • 19. 模板文件关联 模板文件关联 在 render_to_template 中指定 在 render_template 中指定 render 中指定 自动套用函数,返回值为 dict 时或方法名或 response.template 中指定或 expose 中 template 时间 - 组织 - 配置文件 - 项 目 -URL- 模板
    • 20. View 方法 View 方法 函数和类,一个类只处理一个 URL ,需要从基类继承 函数 , 类 ( 需要从基类继承 ), 没 有对类的 decorator 的修饰函数 ,一个类只处理一个 URL 类,一个类只处理一个 URL , 需要从基类继承 函数和类,一个类可以处理多 个 URL 。可以在类方法上加 expose, 不需要特殊基类 时间 - 组织 - 配置文件 - 项 目 -URL- 模板 -View
    • 21. 常用对象的引用 常用对象的引用 request 是作为第一个参数 导入 绑定在类上 自动注入和导入 时间 - 组织 - 配置文件 - 项 目 -URL- 模板 -View- 常用对 象
    • 22. Form 处理 Form 处理 内置 不提供,需要使用 WTForms 不提供 内置 时间 - 组织 - 配置文件 - 项 目 -URL- 模板 -View- 常用对 象 -Form
    • 23. ORM ORM 内置,自已实现 不直接提供,通过 FlaskSQLAlchemy 不提供 内置,基于 SQLAlchemy 实现 时间 - 组织 - 配置文件 - 项 目 -URL- 模板 -View- 常用对 象 -Form-ORM
    • 24. 数据库迁移 数据库迁移 间接通过 south 不提供 不提供 间接,集成了 alembic 时间 - 组织 - 配置文件 - 项 目 -URL- 模板 -View- 常用对 象 -Form-ORM
    • 25. i18n i18n 支持,通过 xgettext 提取 支持,通过 babel 处理 支持,通过 xgettext 提取 支持,通过修改 pygettext.py 时间 - 组织 - 配置文件 - 项 目 -URL- 模板 -View- 常用对 象 -Form-i18n
    • 26. 命令行工具 命令行工具 提供,可以按 app 来自定义 第三方 无 提供,可以按 app 来自定义 时间 - 组织 - 配置文件 - 项 目 -URL- 模板 -View- 常用对 象 -Form-i18n-CMD
    • 27. 异步处理支持 异步处理支持 第三方 第三方 内置 第三方 时间 - 组织 - 配置文件 - 项 目 -URL- 模板 -View- 常用对 象 -Form-i18n-CMD- 异步
    • 28. websocket websocket 第三方 第三方 内置 第三方 时间 - 组织 - 配置文件 - 项 目 -URL- 模板 -View- 常用对 象 -Form-i18n-CMD- 异步
    • 29. 比较总结(一) 比较总结(一) 比较 内容 APP Flask Free/Blueprint Tornado Uliweb 配置文件 py 多种 py ini 配置文件语法 py py py py 程序结构创建 cmd 集中 分散 集中 cmd 分散 √ 继承,受限 √ 继承,自由 √ 继承,自由 手动 手动 组织方式 URL 定义 URL 反向获取 模板 模板调用 View Url/View-Class request 等对象 Django √ 继承 , 受限 手动 函数 / 类 函数 / 类 1:1 参数 1:1 导入 类 1:1 绑定类 APP 套用 / 手动 函数 / 类 n:1 注入 / 导入 Form √ √ ORM √ √
    • 30. 比较总结(二) 比较总结(二) 比较 内容 数据库迁移 i18n 命令行工具 Django Flask Tornado -/south √ Uliweb -/Alembic √ √ √ √ √ 异步处理 √ websocket √
    • 31. 2013 年个人小结 Uliweb 与其它框架比较 Uliweb 的特殊功能介绍
    • 32. API API • 如何简单提供统一的 API 的 定义和使用方式?
    • 33. functions [FUNCTIONS] get_model = 'uliweb.orm.get_model' get_object = 'uliweb.orm.get_object' set_echo = 'uliweb.orm.set_echo' from uliweb import functions User = functions.get_model(‘user’)
    • 34. Model Model • Model 能替換吗? • Model 变了怎么方便处理? • 如何方便调试?
    • 35. 配置化 [MODELS] wikipage = 'wiki.models.WikiPage' wikichangeset = 'wiki.models.WikiChangeSet'
    • 36. get_model() from uliweb import functions User = functions.get_model(‘user’)
    • 37. 命令行 uliweb syncdb -v [default] [default] [default] [default] [default] [default] Creating Creating Creating Creating Creating Creating [1/40, [2/40, [3/40, [4/40, [5/40, [6/40, blog] blog_category...EXISTED blog] blog...EXISTED blog] blog_blog_tag_tags...EXISTED blog] blog_tag...EXISTED classes] class_teacher...EXISTED classes] class_info...EXISTED
    • 38. 命令行 uliweb dump [appname,…] uliweb dumptable tablename[, tablename] uliweb reset [appname,…] uliewb resettable tablename[, tablename] uliweb load [appname,…] uliewb loadtable tablename[, tablename]
    • 39. 命令行 uliweb sql uliweb sqltable CREATE TABLE forumcategory ( name VARCHAR(100), description TEXT, ordering INTEGER, created_on DATETIME, updated_on DATETIME, id INTEGER NOT NULL AUTO_INCREMENT, PRIMARY KEY (id) )CHARSET=utf8;
    • 40. 命令行 uliweb sqlhtml
    • 41. 命令行 uliweb sqldot
    • 42. Alembic 集成 uliweb alembic init uliweb alembic diff uliweb alembic upgrade
    • 43. 调试 set_echo functions.set_echo(True, time=0.001, explain=True) ===>>> (d:/project/mywork/uliweb-git/uliweb/utils/generic:1916:objects) SELECT tutorials.title, tutorials.creator, tutorials.create_date, ..., tutorials.comments_count, tutorials.id FROM tutorials WHERE tutorials.deleted = false ORDER BY tutorials.modified_date DESC LIMIT 0, 10 ---Explain: id=1L, select_type=u'SIMPLE', table=u'tutorials', type=u'ALL', possible_keys=None, key=None, key_len=None, ref=None, rows=8L, Extra=u'Using where; Using filesort', ===<<< time used 0.024000s
    • 44. 调试 SQLMonitorMiddle [MIDDLEWARES] sqlmonitor = 'uliweb.contrib.orm.middle_sqlmonitor.SQLMonitorMiddle‘ [ORM] SQL_MONITOR = True ====== SELECT t... SELECT tu... SELECT use... sql execution count 10 </tutorial> ======= tutorials.title, tutorials.creator, tutorials.create_date, 1 0.100 count(tutorials.id) AS tbl_row_count FROM tutorials WHERE 2 0.002 user.username, user.nickname, user.email, user.password, 7 0.012
    • 45. 模板 模板 • 如何方便引用外部资源,不 想写 <script> 或 <link> • 在模板继承时,如何处理新 増资源 • 模板如何调试?继承,查找 ?
    • 46. 定义 1 app/template_plugins/xxxx.py def call(app, var, env, version=None): from uliweb import settings a = [] version = version or settings.UI_CONFIG.angularjs_version a.append('angularjs/%s/angular-%s.min.js' % (version, version)) a.append('jsutils/json2.js') return {'toplinks':a}
    • 47. 定义 2 settings.ini [TEMPLATE_USE] avalon = {'toplinks':['avalon/avalon.js', 'avalon/avalon_init.js']}
    • 48. 使用 use, link ‘uliweb.contrib.template’ {{use “avalon”}} {{link “test.js”}} <script type="text/javascript" src="/static/avalon/avalon.js?ver=18"></script> <script type="text/javascript" src="/static/avalon/avalon_init.js?ver=18"></script>
    • 49. 模板继承的处理 #layout.html <html> <head> {{use "bootstrap"}} </head> <body>{{block content}}{{end}}</body> </html> #layout.html {{extend “layout.html”}} {{block content}} {{use “avalon”}} {{end}}
    • 50. 处理结果 #layout.html <html> <head> {{use "bootstrap"}} {{use “avalon”}} </head> <body>{{block content}}{{end}}</body> </html>
    • 51. 命令行调式 uliweb find –t template D:projectccctasks-master>uliweb find -t index.html apps/newportal/templates/index.html apps/myportal/templates/index.html apps/Portal/templates/index.html
    • 52. 命令行调式 uliweb find –t template --tree D:projectccctasks-master>uliweb find -t index.html --tree apps/newportal/templates/index.html -------------- Tree -------------apps/theme/templates/theme/skeleton.html (extend)apps/theme/templates/theme/zebra.html -----------> (extend)apps/newportal/templates/index.html (include)apps/theme/templates/include/inc_userinfo.html (include)apps/theme/templates/include/inc_checklogin.html (include)apps/theme/templates/theme/utils.html (include)d:/project/mywork/plugsgit/plugs/ui/jquery/pnotify/templates/ inc_show_flashes.html
    • 53. 命令行调式 uliweb find –t template–block –with-filename -------------- Blocks -------------title (apps/theme/templates/theme/zebra.html) meta (apps/theme/templates/theme/skeleton.html) _css (apps/newportal/templates/index.html) body_class (apps/newportal/templates/index.html) before_header (apps/theme/templates/theme/skeleton.html) header (apps/theme/templates/theme/zebra.html) header_extra_class (apps/theme/templates/theme/zebra.html)
    • 54. CSS, JS 合并 初始 <link href="/static/bootstrap/2.2.0/bootstrap.min.css?ver=18"/> <script src="/static/bootstrap/2.2.0/js/bootstrap.min.js?ver=18"></script> <link href="/static/jquery/ui/css/redmond/jquery-ui-1.8.16.custom.css? ver=18"/> <script src="/static/jquery/ui/js/jquery-ui-1.8.16.custom.min.js? ver=18"></script> <script src="/static/jquery/ui/js/jquery.ui.datepicker.zh.js?ver=18"></script> <link href="/static/theme/blove/index.css?ver=18"/> <script src="/static/jqutils/jquery.cookie.js?ver=18"></script> <link href="/static/poshytip/tip-twitter/tip-twitter.css?ver=18"/>
    • 55. CSS, JS 合并 配置 [STATIC_COMBINE] 1 = ['jquery/jquery-1.7.2.min.js', 'jsutils/json2.js'] #jquitls 2 = ['jquery/ui/js/jquery-ui-1.8.16.custom.min.js', 'jquery/ui/js/jquery.ui.datepicker.zh.js', 'jsmenu/menu.js', 'poshytip/jquery.poshytip.js', 'jqutils/jqrselect.js', 'jqutils/jqutils.js', 'jqutils/jquery.hotkeys.js', 'jqutils/jquery.form.js', 'pnotify/1.2.0/jquery.pnotify.min.js', ]
    • 56. CSS, JS 合并 uliweb exportstatic –auto static <link href="/static/_cmb_3ab42e4ed430d339f6390330aa3e77b7.css?ver=15"/> <script src="/static/_cmb_9ed3a8d3597e13abdd529ea9d4e6270f.js? ver=15"></script> <link href="/static/_cmb_88466a4a9313f6857d61aa632abf5054.css?ver=15"/> <script src="/static/_cmb_c8a04bdfa7d2195d5f05c76a87a8767a.js? ver=15"></script>
    • 57. Generic Generic • 如何快速处理 CRUD
    • 58. 操作流程定义为类 AddView EditView DetailView DeleteView ListView …
    • 59. 操作流程定义为类 AddView @expose(‘/blog’) class BlogAdd(object): def add(self): Blog = functions.get_model(‘blog’) def get_url(id): return url_for(self.__class__.list) view = functions.AddView(Blog, ok_url=get_url) return view.run()
    • 60. 操作流程定义为类 form = make_form(Model) # 根据 Model 自动生成 Form if method == ‘GET’: return {‘form’:form}# 显示页面 else: #POST if form.validate(request.values): # 表单校验 # 成功 save() # 保存数据 return redirect(ok_url) # 成功后跳转 else: return {‘form’:form} # 带有出错信息返回 显示 校验 成功 出错
    • 61. 通过参数与回调来进行控制 class AddView(object): def __init__(self, model, ok_url=None, ok_template=None, form=None, success_msg=None, fail_msg=None, use_flash=True, data=None, default_data=None, fields=None, form_cls=None, form_args=None, static_fields=None, hidden_fields=None, pre_save=None, post_save=None, post_created_form=None, layout=None, file_replace=True, template_data=None, success_data=None, fail_data=None, meta='AddForm', get_form_field=None, post_fail=None, types_convert_map=None, fields_convert_map=None, json_func=None, file_convert=True, upload_to=None, upload_to_sub=None, fileserving_config='UPLOAD', protect=False, protect_field_name=None):
    • 62. 自动生成代码框架 generic_app_blog>uliweb generic Appname:blog Table Name:blog Creation Theme([a]ngularjs, [h]tml), [e]sayui)[a]:h View Class Name [BlogView]: Save views to [views_blog.py]: Class View URL prefix [/blog]: Enable pagination(Y/n/q)[Y]: Enable query(Y/n/q)[Y]:n Enable download(Y/n/q)[Y]:n Add View using popup(Y/n/q)[Y]:n Add View using ajax(Y/n/q)[Y]:n Edit View using popup(Y/n/q)[Y]:n Edit View using ajax(Y/n/q)[Y]:n Delete View using ajax(Y/n/q)[Y]:
    • 63. 生成的目录及文件 ├─apps │ ├─blog │ │ ├─static │ │ └─templates │ │ │ └─BlogView │ │ │ ├─add.html │ │ │ ├─edit.html │ │ │ ├─list.html │ │ │ └─view.html │ │ └─views_blog.py
    • 64. 欢迎使用 Uliweb 欢迎使用 Uliweb
    • 65. 谢谢 邮件列表  https://groups.google.com/forum/#!forum/uliweb 论 坛  http://uliweb.clkg.org 文 档 http://limodou.github.io/uliweb-doc/ QQ 群 162487035 邮箱: limodou@gmail.com 微博: http://weibo.com/u/1689940061