Flask 和 Django 是两个领先的 Python Web 框架,虽然它们都可以帮助开发人员快速构建网站,但它们的方法却截然不同。在本文中,我们将了解每个框架的用途、工作原理以及开发人员选择其中一个框架的原因。为了展示这些差异,我们将从头开始构建三个不同的项目 - Hello World 应用程序、个人网站和待办事项项目 - 这样您就可以亲眼目睹它们如何工作并根据您的需求做出最佳决策。
数据库驱动的网站具有非常相似的需求:URL 路由、逻辑、连接到数据库、呈现 HTML 模板、用户身份验证等。在万维网的早期,开发人员必须自己构建所有这些部分,然后才能开始开发网站本身。
开源 Web 框架很快出现,允许开发人员小组协作应对这一挑战,分享最佳实践,审查代码,并且通常不会在每次有人想要构建新网站时重新发明轮子。每种主要编程语言都有 Web 框架,其中著名的示例包括用 Ruby 编写的 Ruby on Rails、用 PHP 编写的 Laravel、用 Java 编写的 Spring,以及我们在 Python 中介绍的两个框架:Flask 和 Django。
如果您是编程新手,听到 Python“框架”与“库”一词可能会感到困惑。两者都指的是软件,但区别在于复杂性:库专注于特定问题,而框架则解决更大的挑战,并且通常会合并许多较小的库来实现这一目标。正如我们将看到的,Flask 和 Django 都依赖相当多的 Python 库。
如果我们看一下 GitHub 的 star 数,Flask 和 Django 相对并驾齐驱,但我们可以看到 FastAPI 的爆炸性增长,它现在已经明确跻身 Python Web 框架前 3 名。
2023 年 Python 开发者调查显示 Django 在 2023 年仅领先于 Flask,但 FastAPI 也势头强劲。
Stack Overflow 对所有编程语言的开发人员进行的 2023 年调查 Flask 稍稍领先,但紧随其后的是 Django,FastAPI 稍稍落后。
这些比较对于查看趋势很有趣,但并不能解释很多事情。例如,一个Web框架很流行,是否意味着真正的公司和专业开发人员正在使用它,或者它只是初学者喜欢玩的东西?
无论比较指标如何,很明显 Flask 和 Django 是目前排名前两位的 Python Web 框架。
如果您正在寻找 Python Web 开发人员的工作,Django 是更好的选择。在 Indeed.com 等主要招聘网站上,Django 开发人员的列表数量几乎是 Flask 的两倍。
然而,这种差异可能是因为 Django 是一个比 Flask 更具体的选择。初创公司或公司可以仅在 Django 上运行几乎所有的服务,而 Flask 由于其轻量级的占用空间而经常与其他技术一起使用。
最实用的方法是首先真正掌握 Python,然后使用 Django 或 Flask(最好两者都有!)添加 Web 开发知识。
Django 拥有两者中规模更大、更有组织的社区。 Django 代码库有超过 1,800 名提交者,而 Flask 的提交者约为 550 名。 StackOverflow 上有大约 212,500 个 Django 问题,而 Flask 问题有大约 31,500 个。
Django还在美国、欧洲和澳大利亚举办年会。尽管 PyCon 活动中对这两个框架都有积极的讨论,但 Flask 没有类似级别的会议。
Flask 是一个微框架,其设计有意做到最小化和灵活,这显然并没有限制它的实用性。正如我们将看到的,这个设计决策既有优点也有缺点。
Flask 最初是 Armin Ronacher 于 2010 年开的一个愚人节玩笑,其灵感来自于 Sinatra Ruby 框架。 FLask 的设计初衷是足够简单,适合单个 Python 文件,尽管它的起源很幽默,但 Flask 由于其简单性和灵活性很快就受到了欢迎。
Flask 本身的代码库相当小,并且严重依赖两个主要依赖项:Werkzeug 和 Jinja,这两个依赖项最初都是由 Armin Ronacher 创建的。
Werkzeug 是一个 WSGI(Web 服务器网关接口)工具包,为 Flask 提供核心功能。它处理 HTTP 请求和响应、URL 路由系统、内置开发服务器、交互式调试器、测试客户端和中间件。 Jinja 是一个模板引擎,用于生成动态 HTML 文档,它具有自己的基本逻辑、变量、if/else 循环、模板继承等语法。
虽然 Flask 没有指定特定的结构,但它经常用于其他 Web 框架(例如 Ruby on Rails)常见的模型-视图-控制器 (MVC) 模式。
Flask 的微框架架构意味着它可以非常好地执行一些任务,并依赖第三方库(和开发人员)来实现其余任务。这种方法非常适合不需要 Django 内置的所有功能的小型 Web 应用程序。在另一个极端,需要完全控制应用程序的经验丰富的程序员通常更喜欢 Flask,尽管这意味着比使用 Django 这样的完整框架要做出更多的设计决策。
Django 是一个高级 Python Web 框架,鼓励快速开发和简洁、务实的设计。它由《劳伦斯世界日报》创建,并于 2005 年公开发布。“高级”意味着 Django 旨在通过为大多数用例提供内置“电池”来最大限度地减少 Web 应用程序过程中所需的实际编码,包括 ORM(对象关系映射器)、URL 路由、模板引擎、表单处理、身份验证系统、管理界面和强大的安全功能。在 Flask 中,开发人员必须选择并实现这些不同的功能,但在 Django 中,它们是开箱即用的。
Django 由非营利性 Django 软件基金会管理,背后有一个庞大而专注的社区,致力于新版本、广泛的文档、活跃的在线社区和定期的社区运行会议。
Django 遵循 MVC 架构的一种变体,称为模型-视图-模板 (MVT) 模式,强调关注点分离:
还包含第四个组件 URLs,用于处理 URL 路由,将用户请求与特定视图匹配,然后生成响应。
Python 应该已经安装在你的计算机上,所以我们需要做的就是创建一个虚拟环境并安装 Flask。
# Windows $ python -m venv .venv $ .venv\Scripts\Activate.ps1 (.venv) $ python -m pip install flask # macOS/Linux $ python3 -m venv .venv $ source .venv/bin/activate (.venv) $ python -m pip install flask
使用文本编辑器创建一个名为 hello.py 的新文件。 Flask 众所周知,Hello World 网页只需要五行。
# app.py from flask import Flask app = Flask(__name__) @app.route("/") def hello_world(): return "<p>Hello, World!</p>"
此代码在顶部导入 Flask 类,并在下一行创建一个名为 app 的实例。 Route() 装饰器告诉 Flask 哪个 URL 应该触发该函数;此处设置为主页 /。然后函数 hello_world 返回段落
和段落之间的 HTML 字符串。带有我们的消息的标签。
要运行代码,请使用flask run 命令。
(.venv) $ flask run * Debug mode: off WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Running on http://127.0.0.1:5000 Press CTRL+C to quit
如果您在网络浏览器中导航至 127.0.0.1:5000,则该消息可见。 Flask 默认使用端口 5000。
这几乎是最简单的,并且说明了 Flask 的根源是尝试用单文件方式创建 Web 应用程序,也是其固有灵活性的一个示例。
Django 文档没有提供类似的快速入门指南,但我们只需多写几行代码就可以完成类似的任务。事实上,这样做已经成为经验丰富的 Django 开发人员之间的一种游戏,并且有一个完整的存储库 django-microframework 致力于这些工作。我们会选择选项2,它不是最简洁的,但比其他一些方法更容易理解。
Navigate to a new directory, perhaps called django on your Desktop, and create a virtual environment containing Django.
# Windows > cd onedrive\desktop\code > mkdir django > cd django > python -m venv .venv > .venv\Scripts\Activate.ps1 (.venv) > python -m pip install django # macOS % cd ~/desktop/code % mkdir django % cd django % python3 -m venv .venv % source .venv/bin/activate (.venv) % python3 -m pip install django
In your text editor create a hello_django.py file with the following code:
# hello_django.py from django.conf import settings from django.core.handlers.wsgi import WSGIHandler from django.core.management import execute_from_command_line from django.http import HttpResponse from django.urls import path settings.configure( ROOT_URLCONF=__name__, DEBUG=True, ) def hello_world(request): return HttpResponse("Hello, Django!") urlpatterns = [path("", hello_world)] application = WSGIHandler() if __name__ == "__main__": execute_from_command_line()
Django is designed for larger web application and typically relies on a global settings.py file for many configurations, however we can import what we need in a single file. The key points of reference are the hello_world function that returns the string, "Hello, Django!" and the urlpatterns defining our URL routes, namely at "", meaning the empty string, so the homepage.
Start up Django's built-in server using the runserver command
(.venv) > python hello_django.py runserver Watching for file changes with StatReloader Performing system checks... System check identified no issues (0 silenced). July 17, 2024 - 13:48:54 Django version 5.0, using settings None Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C.
Navigate to Django's standard port of 8000, http://127.0.0.1:8000/, to see the "Hello, Django!" message.
Django required tweleve lines of code rather than Flask's five, but both these examples are intended as quickstart guides; they are not how you structure a real-world Flask or Django app.
Now let's build a Personal Website with a home page and an about page. This will give a chance to introduce templates and repeat some of the patterns we saw around how routes are defined in Flask.
Update the app.py file as follows:
from flask import Flask, render_template app = Flask(__name__) @app.route('/') def home(): return render_template('home.html') @app.route('/about') def about(): return render_template('about.html') if __name__ == '__main__': app.run(debug=True)
Both the home and about View functions now return a template. We're also using the route() decorator again to define the URL path for each. We've also added debug=True at the bottom so that the development server runs now in debug mode.
The next step is creating our two templates. Flask will look for template files in a templates directory so create that now.
(.venv) $ mkdir templates
Within it add the two files with the following code:
<!-- templates/home.html --> <!DOCTYPE html> <html> <head> <title>Personal Website</title> </head> <body> <h1>Welcome to My Website</h1> <a href="{{ url_for('about') }}">About Me</a> </body> </html>
<!-- templates/about.html --> <!DOCTYPE html> <html> <head> <title>About Me</title> </head> <body> <h1>About Me</h1> <p>This is my personal website.</p> <a href="{{ url_for('home') }}">Home</a> </body> </html>
Each file use the method url_for to define links based on the view function name.
Run the server again with flask run and navigate to the homepage:
Then click the "About Me" link.
This is a rudimentary example but you can start to see how templates and views interact in Flask. We still have only one main Python file powering the whole thing, but once we have many more pages and start to introduce logic, the single-file approach stops making sense and it's time to start organizing the Flask app in different ways. There are some common patterns used in the Flask community, however, it is ultimately up to the developer.
Django is designed for full-bodied web applications so building a Personal Website is a chance to see this in action. We'll start by creating a project, which is the central hub for our website, using the startproject command.
(.venv) $ django-admin startproject django_project .
We've named the project django_project here. Adding the period, ., means the new folder and files are installed in the current directory. If you don't have the period Django creates a new directory and then adds the project folder and files there.
This is what your directory should look like now. The hello_django.py file remains and can either be left there or removed entirely: we will no longer use it. There is an entirely new django_project folder containing several files and a manage.py file used for running Django commands.
├── django_project │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── hello_django.py └── manage.py
We want to create an app now using thes startapp command which will be called pages. A single Django project typically has multiple apps for different functionality. If we added user registration that code should be in its own app, same for payments, and so on. This is a way to help developers reason better about their code.
(.venv) $ python manage.py startapp pages.
This command creates a pages directory with the following files:
└── pages ├── __init__.py ├── admin.py ├── apps.py ├── migrations │ └── __init__.py ├── models.py ├── tests.py └── views.py
Our first step is updating the django_project/settings.py file to tell Django about our new app. This is a global settings file for the entire project.
# django_project/settings.py INSTALLED_APPS = [ "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", "pages", # new ]
Second, update the django_project/urls.py file. When a URL request comes in it will hit this file first and then be either processed or redirected to a specific app. In this case, we want to send requests to the pages app. To do this we'll import include and set a new path at "", meaning the homepage. Django defaults to including the URL configuration for the built-in admin, a powerful visual way to interact with your database.
# django_project/urls.py from django.contrib import admin from django.urls import path, include # new urlpatterns = [ path("admin/", admin.site.urls), path("", include("pages.urls")), # new ]
Within the pages app we need a view and a URLs file. Let's start with the view at pages/views.py.
# pages/views.py from django.shortcuts import render def home(request): return render(request, "home.html") def about(request): return render(request, "about.html")
In Django, views receive web requests and return web responses. The request parameter is an object containing metadata about the request from the user. We'll define two function-based views here, home and about, that use the shortcut function render to combine a template with an HttpResponse object sent back to the user. The two templates are home.html and about.html.
For the templates, we can create a templates directory within pages, then another directory with the app name, and finally our template files. This approach removes any concerns about confusing the Django template loader in larger projects.
(.venv) $ mkdir pages/templates (.venv) $ mkdir pages/templates/pages
Then in your text editor add two new files: pages/templates/pages/home.html and pages/templates/pages/about.html.
<!-- pages/templates/pages/home.html --> <!DOCTYPE html> <html> <head> <title>Personal Website</title> </head> <body> <h1>Welcome to My Website</h1> <a href="{% url 'about' %}">About Me</a> </body> </html>
<!-- pages/templates/pages/about.html --> <!DOCTYPE html> <html> <head> <title>About Me</title> </head> <body> <h1>About Me</h1> <p>This is my personal website.</p> <a href="{% url 'home' %}">Home</a> </body> </html>
The final step is configuring the URLs for these two pages. To do this, create a urls.py file within the pages app with the following code.
# pages/urls.py from django.urls import path from . import views urlpatterns = [ path("", views.home, name="home"), path("about/", views.about, name="about"), ]
At the top we import our views and then set a URL path for each. The syntax is defining the URL path, the view name, and optionally adding a URL name that allows us to link to each path in our templates.
Start up the Django local server with the runserver command.
(.venv) $ python manage.py runserver
You can see the homepage:
Click the "About Me" to be redirected to the about page:
As you can see Django required more scaffolding than Flask, however this approach provides a consistent structure that is quite scaleable.
The true comparison of these web frameworks depends on your project's needs. Are you building a traditional web application that connects to a database, requires CRUD (Create-Read-Update-Delete) functionality, and user authentication? If yes, Django has built-in solutions for all of these needs. By comparison, Flask requires installing multiple third-party libraries: Flask-SQLAlchemy to connect to the database, Flask-Migrate to manage database migrations, Flask-WTF and WTForms for forms, Flask-Login for user authentication, FLask-Mail for email support, Flask-Security for security features, Flask-Admin for an admin interface to manage application data, Flask-Caching for caching support, Flask-BCrypt for password hashing and so on.
The power of Django is that you don't have to worry about any of these things. They are included, tested, and supported by the community. For Flask, the third-party libraries are not as tightly integrated and require more manual installation by the developer. This affords greater flexibility but also requires more programmer expertise.
Ultimately, you can't go wrong choosing Flask or Django for your web application needs. They both are mature, scaleable, and well-documented. This difference is in approach and the best way to determine what you prefer is to try each out by building more complex projects.
If you're interested in learning more about Django, check out Django for Beginners for a guide to building six progressively more complex web applications including testing and deployment. For Flask, the Flask Mega-Tutorial has a free online version. There are also two courses over at TestDriven.io worth recommending: TDD with Python, Flask and Docker and Authentication with Flask, React, and Docker. If you prefer video, there are many Flask courses on Udemy but the best video course I've seen is Build a SaaS App with Flask and Docker.
以上是Python Web 框架综合比较 Flask vs Django的详细内容。更多信息请关注PHP中文网其他相关文章!