Python项目WebApp实战之六——前端框架及API

二叶草 2020年3月9日21:30:45前端框架评论阅读模式

前端页面

针对繁杂的前端开发网页页面而言,最好是应用一套CSS架构来进行基础的合理布局和款式。新项目中应用uikit架构。全部的静态数据資源文档统一放进static文件目录下,并依照类型分类。因为网页页面将会存有许多 同样的一部分,例如页眉和页脚。常见的模板引擎已经考虑到了页面上重复的HTML部分复用问题。

一般有两种实现方式,一种是include。比如:

  1. <html>
  2.    <% include file="inc_header.html" %>
  3.    <% include file="index_body.html" %>
  4.    <% include file="inc_footer.html" %>
  5. </html>

这样,相同的部分incheader.html和incfooter.html就可以共享。但是include方法不利于页面整体结构的维护。

还有另一种是通过“继承”的方式,编写一个父模板,定义一些可替换的块。然后编写多个子模板,替换父模板中的block。

  1. <!-- base.html -->
  2. <html>
  3.    <head>
  4.        <title>{% block title%} 这里定义了一个名为title的block {% endblock %}</title>
  5.    </head>
  6.    <body>
  7.        {% block content %} 这里定义了一个名为content的block {% endblock %}
  8.    </body>
  9. </html>
  10. <!-- a.html -->
  11. {% extends 'base.html' %}
  12. {% block title %} A {% endblock %}
  13. {% block content %}
  14.    <h1>Chapter A</h1>
  15.    <p>blablabla...</p>
  16. {% endblock %}
  17. <!-- b.html -->
  18. {% extends 'base.html' %}
  19. {% block title %} B {% endblock %}
  20. {% block content %}
  21.    <h1>Chapter B</h1>
  22.    <ul>
  23.       <li>list 1</li>
  24.       <li>list 2</li>
  25.    </ul>
  26. {% endblock %}

一旦编写好了父模板,编写子模板非常容易。

编写首页

首先是编写一个父模板, __base__.html。包含一些block,比如meta块,标题块, <head>标签中插入的JavaScript代码,引入的文件块等。最重要的就是content,页面内容块。

然后就可以编写一个blog.html页面,显示门户文章的列表。

  1. {% extends '__base__.html' %}
  2. {% block title %}日志{% endblock %}
  3. {% block content %}
  4.    <div class="uk-width-medium-3-4">
  5.        {% for blog in blogs %}
  6.            <article class="uk-article">
  7.                <h2><a href="/blog/{{ blog.id }}">{{ blog.name }}</a></h2>
  8.                <p class="uk-article-meta">发表于{{ blog.created_at}}</p>
  9.                <p>{{ blog.summary }}</p>
  10.                <p><a href="/blog/{{ blog.id }}">继续阅读 <i class="uk-icon-angle-double-right"></i></a></p>
  11.            </article>
  12.            <hr class="uk-article-divider">
  13.        {% endfor %}
  14.    </div>
  15. {% endblock %}

相应的URL的处理函数需要修改为:

  1. @get('/')
  2. def index(request):
  3.    summary = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.'
  4.    blogs = [
  5.        Blog(id='1', name='Test Blog', summary=summary, created_at=time.time()-120),
  6.        Blog(id='2', name='Something New', summary=summary, created_at=time.time()-3600),
  7.        Blog(id='3', name='Learn Swift', summary=summary, created_at=time.time()-7200)
  8.    ]
  9.    return {
  10.        '__template__': 'blogs.html',
  11.        'blogs': blogs
  12.    }

Blog的创建日期显示的是一个浮点数,因为它是由这段模板渲染出来的:

  1. <p class="uk-article-meta">发表于{{ blog.created_at }}</p>

解决方法是通过jinja2的filter(过滤器),把一个浮点数转换成日期字符串。编写一个datetime的filter,用法如下:

  1. <p class="uk-article-meta">发表于{{ blog.created_at|datetime }}</p>

filter需要在初始化jinja2时设置。相关代码如下:

  1. def datetime_filter(t):
  2.    delta = int(time.time() - t)
  3.    if delta < 60:
  4.        return '1分钟前'
  5.    if delta < 3600:
  6.        return '%s分钟前' % (delta // 60)
  7.    if delta < 86400:
  8.        return '%s小时前' % (delta // 3600)
  9.    if delta < 604800:
  10.        return '%s天前' % (delta // 86400)
  11.    dt = datetime.fromtimestamp(t)
  12.    return '%s年%s月%s日' % (dt.year, dt.month, dt.day)
  13. ...
  14. init_jinja2(app, filters=dict(datetime=datetime_filter))

为移动应用开发api

REST就是一种设计API的模式。最常用的数据格式是JSON。

一个API也是一个URL的处理函数,我们希望能直接通过一个@api来把函数变成JSON格式的REST API,这样,获取注册用户可以用一个API实现如下:

  1. @get('/api/users')
  2. def api_get_users(*, page='1'):
  3.    page_index = get_page_index(page)
  4.    num = yield from User.findNumber('count(id)')
  5.    p = Page(num, page_index)
  6.    if num == 0:
  7.        return dict(page=p, users=())
  8.    users = yield from User.findAll(orderBy='created_at desc', limit=(p.offset, p.limit))
  9.    for u in users:
  10.        u.passwd = '******'
  11.    return dict(page=p, users=users)

只要返回一个dict,后续的response这个middleware就可以把结果序列化为JSON并返回。

我们需要对Error进行处理,因此定义一个APIError,这种Error是指API调用时发生了逻辑错误(比如用户不存在),其他的Error视为Bug,返回的错误代码为internalerror。

客户端调用API时,必须通过错误代码来区分API调用是否成功。错误代码是用来告诉调用者出错的原因。很多API用一个整数表示错误码,这种方式很难维护错误码,客户端拿到错误码还需要查表得知错误信息。更好的方式是用字符串表示错误代码,不需要看文档也能猜到错误原因。

本文来源于:Python项目WebApp实战之六——前端框架及API-变化吧门户
特别声明:以上文章内容仅代表作者本人观点,不代表变化吧门户观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。

  • 赞助本站
  • 微信扫一扫
  • weinxin
  • 加入Q群
  • QQ扫一扫
  • weinxin
二叶草
Go语言接口规则 前端框架

Go语言接口规则

Go语言接口规则 接口是一个或多个方法签名的集合。任何类型的方法集中只要拥有该接口对应的全部方法签名。就表示它 "实现" 了该接口,无须在该类型上显式声明实现了哪个接口。对应方法,是指有相同名称、参数...
Go语言中处理 HTTP 服务器 前端框架

Go语言中处理 HTTP 服务器

1 概述 包 net/http 提供了HTTP服务器端和客户端的实现。本文说明关于服务器端的部分。 快速开始: package main import (   "log"   "net/http" )...

发表评论