前端页面
针对繁杂的前端开发网页页面而言,最好是应用一套CSS架构来进行基础的合理布局和款式。新项目中应用uikit架构。全部的静态数据資源文档统一放进static文件目录下,并依照类型分类。因为网页页面将会存有许多 同样的一部分,例如页眉和页脚。常见的模板引擎已经考虑到了页面上重复的HTML部分复用问题。
一般有两种实现方式,一种是include。比如:
- <html>
- <% include file="inc_header.html" %>
- <% include file="index_body.html" %>
- <% include file="inc_footer.html" %>
- </html>
这样,相同的部分incheader.html和incfooter.html就可以共享。但是include方法不利于页面整体结构的维护。
还有另一种是通过“继承”的方式,编写一个父模板,定义一些可替换的块。然后编写多个子模板,替换父模板中的block。
- <!-- base.html -->
- <html>
- <head>
- <title>{% block title%} 这里定义了一个名为title的block {% endblock %}</title>
- </head>
- <body>
- {% block content %} 这里定义了一个名为content的block {% endblock %}
- </body>
- </html>
- <!-- a.html -->
- {% extends 'base.html' %}
- {% block title %} A {% endblock %}
- {% block content %}
- <h1>Chapter A</h1>
- <p>blablabla...</p>
- {% endblock %}
- <!-- b.html -->
- {% extends 'base.html' %}
- {% block title %} B {% endblock %}
- {% block content %}
- <h1>Chapter B</h1>
- <ul>
- <li>list 1</li>
- <li>list 2</li>
- </ul>
- {% endblock %}
一旦编写好了父模板,编写子模板非常容易。
编写首页
首先是编写一个父模板, __base__.html。包含一些block,比如meta块,标题块, <head>标签中插入的JavaScript代码,引入的文件块等。最重要的就是content,页面内容块。
然后就可以编写一个blog.html页面,显示门户文章的列表。
- {% extends '__base__.html' %}
- {% block title %}日志{% endblock %}
- {% block content %}
- <div class="uk-width-medium-3-4">
- {% for blog in blogs %}
- <article class="uk-article">
- <h2><a href="/blog/{{ blog.id }}">{{ blog.name }}</a></h2>
- <p class="uk-article-meta">发表于{{ blog.created_at}}</p>
- <p>{{ blog.summary }}</p>
- <p><a href="/blog/{{ blog.id }}">继续阅读 <i class="uk-icon-angle-double-right"></i></a></p>
- </article>
- <hr class="uk-article-divider">
- {% endfor %}
- </div>
- {% endblock %}
相应的URL的处理函数需要修改为:
- @get('/')
- def index(request):
- summary = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
- blogs = [
- Blog(id='1', name='Test Blog', summary=summary, created_at=time.time()-120),
- Blog(id='2', name='Something New', summary=summary, created_at=time.time()-3600),
- Blog(id='3', name='Learn Swift', summary=summary, created_at=time.time()-7200)
- ]
- return {
- '__template__': 'blogs.html',
- 'blogs': blogs
- }
Blog的创建日期显示的是一个浮点数,因为它是由这段模板渲染出来的:
- <p class="uk-article-meta">发表于{{ blog.created_at }}</p>
解决方法是通过jinja2的filter(过滤器),把一个浮点数转换成日期字符串。编写一个datetime的filter,用法如下:
- <p class="uk-article-meta">发表于{{ blog.created_at|datetime }}</p>
filter需要在初始化jinja2时设置。相关代码如下:
- def datetime_filter(t):
- delta = int(time.time() - t)
- if delta < 60:
- return '1分钟前'
- if delta < 3600:
- return '%s分钟前' % (delta // 60)
- if delta < 86400:
- return '%s小时前' % (delta // 3600)
- if delta < 604800:
- return '%s天前' % (delta // 86400)
- dt = datetime.fromtimestamp(t)
- return '%s年%s月%s日' % (dt.year, dt.month, dt.day)
- ...
- init_jinja2(app, filters=dict(datetime=datetime_filter))
为移动应用开发api
REST就是一种设计API的模式。最常用的数据格式是JSON。
一个API也是一个URL的处理函数,我们希望能直接通过一个@api来把函数变成JSON格式的REST API,这样,获取注册用户可以用一个API实现如下:
- @get('/api/users')
- def api_get_users(*, page='1'):
- page_index = get_page_index(page)
- num = yield from User.findNumber('count(id)')
- p = Page(num, page_index)
- if num == 0:
- return dict(page=p, users=())
- users = yield from User.findAll(orderBy='created_at desc', limit=(p.offset, p.limit))
- for u in users:
- u.passwd = '******'
- return dict(page=p, users=users)
只要返回一个dict,后续的response这个middleware就可以把结果序列化为JSON并返回。
我们需要对Error进行处理,因此定义一个APIError,这种Error是指API调用时发生了逻辑错误(比如用户不存在),其他的Error视为Bug,返回的错误代码为internalerror。
客户端调用API时,必须通过错误代码来区分API调用是否成功。错误代码是用来告诉调用者出错的原因。很多API用一个整数表示错误码,这种方式很难维护错误码,客户端拿到错误码还需要查表得知错误信息。更好的方式是用字符串表示错误代码,不需要看文档也能猜到错误原因。
本文来源于:Python项目WebApp实战之六——前端框架及API-变化吧门户
特别声明:以上文章内容仅代表作者本人观点,不代表变化吧门户观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。
- 赞助本站
- 微信扫一扫
-
- 加入Q群
- QQ扫一扫
-
评论