选择一个 Python Web 框架:Django vs Flask vs Pyramid(Django vs Flask vs Pyramid: Choosing a Python Web Framework)

编程语言 William 305浏览 0评论

TL;DR: Pyramid, Django, and Flask are all excellent frameworks, and choosing just one for a project is hard. We’ll see working apps with identical functionality in all three frameworks to make comparing the three easier. Skip to Frameworks in Action for the code.

1 Introduction

The world of Python web frameworks is full of choices. Django, Flask, Pyramid, Tornado, Bottle, Diesel, Pecan, Falcon, and many more are competing for developer mindshare. As a developer you want to cut the legions of options down to the one that will help you finish your project and get on to the Next Big Thing ™. We’ll focus on Flask, Pyramid, and Django. Their ideal cases span from micro-project to enterprise-size web service.

Pyramid, Django, 和 Flask都是优秀的框架,为项目选择其中的哪一个都是伤脑筋的事。我们将会用三种框架实现相同功能的应用来更容易的对比三者。也可以直接跳到框架实战(Frameworks in Action)章节查看代码(code)。

1 简介

世界上可选的基于Python的web框架有很多。Django, Flask, Pyramid, Tornado, Bottle, Diesel, Pecan, Falcon等等,都在争取开发者支持。作为一开发者从一堆选择中筛选出一个来完成项目将会成为下一个大工程。我们今天专注于Flask, Pyramid, 和 Django。它们涵盖了从小微项目到企业级的web服务。

To help make the choice between the three easier (or at least more informed), we’ll build the same application in each framework and compare the code, highlighting the strengths and weaknesses of each approach. If you just want the code, skip straight to Frameworks in Action or view the code onGithub.

Flask is a “microframework” primarily aimed at small applications with simpler requirements. Pyramid and Django are both aimed at larger applications, but take different approaches to extensibility and flexibility. Pyramid targets flexibility and lets the developer use the right tools for their project. This means the developer can choose the database, URL structure, templating style, and more. Django aims to include all the batteries a web application will need so developers need only open the box and start working, pulling in Django’s many modules as they go.

为了更容易在三者中作出选择(至少更了解它们),我们将用每一个框架构建同样的应用并比较它们的代码,对于每一个方法我们会高亮显示它的优点和缺点。如果你只想要代码,直接跳到框架实战章节(Frameworks in Action),或者查看其在Github上的代码。

Flask是一个面向简单需求小型应用的“微框架(microframework)”。Pyramid和Django都是面向大型应用的,但是有不同的拓展性和灵活性。Pyramid的目的是更灵活,能够让开发者为项目选择合适的工具。这意味着开发者能够选择数据库、URL结构、模板类型等等。Django目的是囊括web应用的所有内容,所以开发者只需要打开箱子开始工作,将Django的模块拉进箱子中。

Django includes an ORM out of the box, while Pyramid and Flask leave it to the developer to choose how (or if) they want their data stored. The most popular ORM for non-Django web applications is SQLAlchemy by far, but there are plenty of other options from DynamoDB andMongoDB to simple local persistence like LevelDB or plainSQLite. Pyramid is designed to use any persistence layer, even yet-to-be-invented ones.

2 About the Frameworks

Django’s “batteries included” approach makes it easy for developers who know Python already to dive in to web applications quickly without needing to make a lot of decisions about their application’s infrastructure ahead of time. Django has for templating, forms, routing, authentication, basic database administration, and more built in. In contrast, Pyramid includes routing and authentication, but templating and database administration require external libraries.

前面为 Flask和Pyramid apps选择组件的额外工作给那些使用案例不适用标准ORM的开发者提供了更多的灵活性,同样也给使用不同工作流和模版化系统的开发者们带来了灵活性。

Flask,作为三个框架里面最稚气的一个,开始于2010年年中。Pyramid框架是从Pylons项目开始的,在2010年底获得 Pyramid这个名字,虽然在2005年就已经发布了第一个版本。Django 2006年发布了第一个版本,就在Pylons项目(最后叫Pyramid)开始之后。Pyramid和Django都是非常成熟的框架,积累了众多插件和扩展以满足难以置信的巨大需求。

虽然Flask历史相对更短,但它能够学习之前出现的框架并且把注意力放在了微小项目上。它大多数情况被使用在一些只有一两个功能的小型项目上。例如 httpbin一个简单的(但很强大的)调试和测试HTTP库的项目。

3 Community

The prize for most active community goes to Django with 80,000 StackOverflow questions and a healthy set of blogs from developers and power users. The Flask and Pyramid communities aren’t as large, but their communities are quite active on their mailing lists and on IRC. With only 5,000 StackOverflow questions tagged, Flask is 15x smaller than Django. On Github, they have a nearly identical number of stars with 11,300 for Django, and 10,900 for Flask.

All three frameworks are available under BSD-derived permissive licenses. BothFlask’s and Django’s licenses are 3-clause BSD, while Pyramid’s Repoze Public License RPL is a derivative of the 4-clause BSD license.

3. 社区

最具活力的社区当属Django,其有80,000个StackOverflow问题和一系列来自开发者和优秀用户的良好的博客。Flask和Pyramid社区并没有那么大,但它们的社区在邮件列表和IRC上相当活跃。StackOverflow上仅有5,000个相关的标签,Flask比Django小了15倍。在Github上,它们的star近乎相当,Django有11,300个,Flask有10,900个。

三个框架都使用的是BSD衍生的协议。FlaskDjango的协议是BSD 3条款,Pyramid的Repoze Public License RPL是BSD协议 4条款的衍生。

4 Bootstrapping

Django and Pyramid both come with bootstrapping tools built in. Flask includes nothing of the sort because Flask’s target audience isn’t trying to build large MVC applications.

4.1 Flask

Flask’s Hello World app has to be the simplest out there, clocking in at a puny 7 lines of code in a single Python file.

# from http://flask.pocoo.org/ tutorial
from flask import Flask
app = Flask(__name__)

@app.route("/") # take note of this decorator syntax, it's a common pattern
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run()

This is why there aren’t bootstrapping tools for Flask: there isn’t a demand for them. From the above Hello World featured on Flask’s homepage, a developer with no experience building Python web applications can get hacking immediately.

For projects that need more separation between components, Flask hasblueprints. For example, you could structure your Flask app with all user-related functions in users.py and your sales-related functions inecommerce.py, then import them and add them to your app in site.py. We won’t go over this functionality, as it’s beyond the needs of our demo app.

4. Bootstrapping

Django和Pyramid都内建bootstrapping工具。Flask没有包含类似的工具,因为Flask的目标用户不是那种试图构建大型MVC应用的人。

4.1 Flask

Flask的hello world应用非常的简单,仅仅单个Python文件的7行代码就够了。

# from http://flask.pocoo.org/ tutorial
from flask import Flask
app = Flask(__name__)

@app.route("/") # take note of this decorator syntax, it's a common pattern
def hello():
    return "Hello World!"

if __name__ == "__main__":
    app.run()

这是Flask没有bootstrapping工具的原因:没有它们的需求。从Flask主页上的Hello World特性看,没有构建Python web应用经验的开发者可以立即开始hacking。

对于各部分需要更多分离的项目,Flask有blueprints。例如,你可以将所有用户相关的函数放在users.py中,将销售相关的函数放在ecommerce.py中,然后在site.py中添加引用它们来结构化你的Flask应用。我们不会深入这个功能,因为它超出了我们展示demo应用的需求。

4.2 Pyramid

Pyramid’s bootstrapping tool is called pcreate which is part of Pyramid. Previously the Paste suite of tools provided bootstrapping for but has since been replaced with a Pyramid-specific toolchain.

$ pcreate -s starter hello_pyramid # Just make a Pyramid project

Pyramid is intended for bigger and more complex applications than Flask. Because of this, its bootstrapping tool creates a bigger skeleton project. It also throws in basic configuration files, an example template, and the files to package your application for uploading to the Python Package Index.

hello_pyramid
├── CHANGES.txt
├── development.ini
├── MANIFEST.in
├── production.ini
├── hello_pyramid
│   ├── __init__.py
│   ├── static
│   │   ├── pyramid-16x16.png
│   │   ├── pyramid.png
│   │   ├── theme.css
│   │   └── theme.min.css
│   ├── templates
│   │   └── mytemplate.pt
│   ├── tests.py
│   └── views.py
├── README.txt
└── setup.py

As in the rest of the framework, Pyramid’s bootstrapper is incredibly flexible. It’s not limited to one default application; pcreate can use any number of project templates. Included in pcreate there is the “starter” template we used above, along with SQLAlchemy- and ZODB-backed scaffold projects. On PyPi it’s possible to find ready-made scaffolds forGoogle App Engine, jQuery Mobile, Jinja2 templating, modern frontend frameworks, and many more.

5 模板

一个Python应用能够响应HTTP请求将是一个伟大的开端,但是有可能你的大多数用户是没有兴趣使用curl与你的web应用交互的。幸运的是,这三个竞争者提供了使用自定义信息填充HTML的方法,以便让大伙们能够享受时髦的Bootstrap 前端。

模板让你能够直接向页面注入动态信息,而不是采用AJAX。你只需要一次请求就可以获取整个页面以及所有的动态数据,这对用户体验来说是很好的。这对于手机网站来说尤其重要,因为一次请求花费的时间会更长。

所有的模板选项依赖于“上下文环境(context)”,其为模板转换为HTML提供了动态信息。模板的最简单的例子是填充已登录用户的名字以正确的迎接他们。也可以用AJAX获取这种动态信息,但是用一整个调用来填写用户的名字有点过头了,而同时模板又是这么的简单。

5.1 Django

Our example use case is about as easy as it gets, assuming that we have auser object that has a fullname property containing a user’s name. In Python we’d pass the current user to the template like so:

def a_view(request):
    # get the logged in user
    # ... do more things
    return render_to_response(
        "view.html",
        {"user": cur_user}
    )

Populating the template context is as simple as passing a dictionary of the Python objects and data structures the template should use. Now we need to render their name to the page, just in case they forget who they are.

<!-- view.html -->
<div >
  <div >
  <!-- more top bar things go here -->
  </div>
  {% if user %}
  <div >
    You are logged in as {{ user.fullname }}
  </div>
  {% endif %}
</div>

First, you’ll notice the {% if user %} construct. In Django templates {%is used for control statements like loops and conditionals. The if userstatement is there to guard against cases where there is not a user. Anonymous users shouldn’t see “you are logged in as” in the site header.

Inside the if block, you can see that including the name is as simple as wrapping the property we want to insert in {{ }}. The {{ is used to insert actual values into the template, such as {{ user.fullname }}.

Another common use for templates is displaying groups of things, like the inventory page for an ecommerce site.

def browse_shop(request):
    # get items
    return render_to_response(
        "browse.html",
        {"inventory": all_items}
    )

In the template we can use the same {% to loop over all the items in the inventory, and to fill in the URL to their individual page.

{% for widget in inventory %}
    <li><a href="/widget/{{ widget.slug }}/">{{ widget.displayname }}</a></li>
{% endfor %}

To do most common templating tasks, Django can accomplish the goal with just a few constructs, making it easy to get started.

5.1 Django

我们使用的例子正如写的那么简单,假设我们有一个包含了用户名的funllname属性的user对象。在Python中我们这样向模板中传递当前用户:

def a_view(request):
    # get the logged in user
    # ... do more things
    return render_to_response(
        "view.html",
        {"user": cur_user}
    )

拥有这个模板的上下文很简单,传入一个Python对象的字典和模板使用的数据结构。现在我们需要在页面上渲染他们的名字,以防页面忘了他们是谁。

<!-- view.html -->
<div >
  <div >
  <!-- more top bar things go here -->
  </div>
  {% if user %}
  <div >
    You are logged in as {{ user.fullname }}
  </div>
  {% endif %}
</div>

首先,你会注意到这个  {% if user %} 概念。在Django模板中, {% 用来控制循环和条件的声明。这里的if user声明是为了防止那些不是用户的情况。匿名用户不应该在页面头部看到“你已经登录”的字样。

在if块内,你可以看到,包含名字非常的简单,只要用{{}}包含着我们要插入的属性就可以了。{{是用来向模板插入真实值的,如{{ user.fullname }}。

模板的另一个常用情况是展示一组物品,如一个电子商务网站的存货清单页面。

def browse_shop(request):
    # get items
    return render_to_response(
        "browse.html",
        {"inventory": all_items}
    )

在模板中,我们使用同样的{%来循环清单中的所有条目,并填入它们各自的页面地址。

{% for widget in inventory %}
    <li><a href="/widget/{{ widget.slug }}/">{{ widget.displayname }}</a></li>
{% endfor %}

为了做大部分常见的模板任务,Django可以仅仅使用很少的结构来完成目标,因此很容易上手。


via:oschina

转载请注明:AspxHtml学习分享网 » 选择一个 Python Web 框架:Django vs Flask vs Pyramid(Django vs Flask vs Pyramid: Choosing a Python Web Framework)

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址