前军教程网

中小站长与DIV+CSS网页布局开发技术人员的首选CSS学习平台

python散装笔记——126: Flask

Flask 是一个 Python 微型 Web 框架,用于运行包括 Pinterest、Twilio 和 LinkedIn 在内的主要网站。本章将解释并展示 Flask 为前后端 Web 开发提供的各种功能。

1: 文件和模板

与其在返回语句中输入 HTML 标记,不如使用 render_template() 函数:

 from flask import Flask
 from flask import render_template
 app = Flask(__name__)
 
 @app.route("/about")
 def about():
   return render_template("about-us.html")
 
 if __name__ == "__main__":
   app.run(host="0.0.0.0", port=80, debug=True)

这将使用我们的模板文件 about-us.html。为了确保应用程序能够找到该文件,我们必须按照以下格式组织目录结构:

 - application.py
 /templates
     - about-us.html
     - login-form.html
 /static
     /styles
         - about-style.css
         - login-style.css
     /scripts
         - about-script.js
         - login-script.js

最重要的是,HTML 中对这些文件的引用必须如下所示:

 

这将指示应用程序在 static 文件夹下的 styles 文件夹中查找 about-style.css。所有对图像、样式、脚本或文件的引用都适用相同的路径格式。

2: 基础

以下是一个基本服务器的示例:

 # 导入 Flask 类
 from flask import Flask
 # 创建一个应用并检查是否为主程序或导入
 app = Flask(__name__)
 
 # 指定触发 hello_world() 的 URL
 @app.route('/')
 # 在索引路由上运行的函数
 def hello_world():
     # 返回要显示的文本
     return "Hello World!"
 
 # 如果此脚本不是导入的
 if __name__ == "__main__":
     # 运行应用直到停止
     app.run()

运行此脚本(安装了所有正确依赖项的情况下)将启动一个本地服务器。主机是 127.0.0.1,通常称为本地主机。此服务器默认运行在端口 5000 上。要访问你的 Web 服务器,请打开一个 Web 浏览器并输入 URL localhost:5000127.0.0.1:5000(两者没有区别)。目前,只有你的计算机可以访问 Web 服务器。

app.run() 有三个参数:hostportdebug。主机默认为 127.0.0.1,但将其设置为 0.0.0.0 将使你的 Web 服务器可以通过网络中的任何设备使用你的私有 IP 地址访问。端口默认为 5000,但如果将参数设置为端口 80,用户将不需要指定端口号,因为浏览器默认使用端口 80。至于调试选项,在开发过程中(永远不要在生产环境中)将此参数设置为 True 是有帮助的,因为当对 Flask 项目进行更改时,服务器将重新启动。

 if __name__ == "__main__":
   app.run(host="0.0.0.0", port=80, debug=True)

3: 路由 URL

在 Flask 中,URL 路由通常使用装饰器完成。这些装饰器可用于静态路由,以及带参数的 URL 路由。在以下示例中,假设此 Flask 脚本正在运行网站 www.example.com

 @app.route("/")
 def index():
   return "You went to www.example.com"
 
 @app.route("/about")
 def about():
   return "You went to www.example.com/about"
 
 @app.route("/users/guido-van-rossum")
 def user():
   return "You went to www.example.com/guido-van-rossum"

在最后一个路由中,你可以看到,给定一个带有 /users/ 和个人资料名称的 URL,我们可以返回一个个人资料。由于为每个用户包含一个 @app.route() 将极其低效且混乱,Flask 提供了从 URL 中获取参数的功能:

 @app.route("/users/")
 def profile(username):
   return "Welcome to the profile of " + username
 
 cities = ["OMAHA", "MELBOURNE", "NEPAL", "STUTTGART", "LIMA", "CAIRO", "SHANGHAI"]
 
 @app.route("/stores/locations/")
 def storefronts(city):
   if city in cities:
     return "Yes! We are located in " + city
   else:
     return "No. We are not located in " + city

4: HTTP 方法

最常见的两种 HTTP 方法是 GET 和 POST。Flask 可以根据使用的 HTTP 方法从同一个 URL 运行不同的代码。例如,在一个带有账户的 Web 服务中,将登录页面和登录过程通过同一个 URL 路由是最方便的。GET 请求(当你在浏览器中打开一个 URL 时执行的相同请求)应该显示登录表单,而 POST 请求(携带登录数据)应该单独处理。还创建了一个路由来处理 DELETE 和 PUT HTTP 方法。

 @app.route("/login", methods=["GET"])
 def login_form():
   return "This is the login form"
 
 @app.route("/login", methods=["POST"])
 def login_auth():
   return "Processing your data"
 
 @app.route("/login", methods=["DELETE", "PUT"])
 def deny():
   return "This method is not allowed"

为了简化代码,我们可以从 Flask 导入 request 包。

 from flask import request
 
 @app.route("/login", methods=["GET", "POST", "DELETE", "PUT"])
 def login():
   if request.method == "DELETE" or request.method == "PUT":
     return "This method is not allowed"
   elif request.method == "GET":
     return "This is the login forum"
   elif request.method == "POST":
     return "Processing your data"

要从 POST 请求中检索数据,我们必须使用 request 包:

 from flask import request
 
 @app.route("/login", methods=["GET", "POST", "DELETE", "PUT"])
 def login():
   if request.method == "DELETE" or request.method == "PUT":
     return "This method is not allowed"
   elif request.method == "GET":
     return "This is the login forum"
   elif request.method == "POST":
     return "Username was " + request.form["username"] + " and password was " + request.form["password"]

Section 126.5: Jinja 模板

与 Meteor.js 类似,Flask 与前端模板服务集成得很好。Flask 默认使用 Jinja 模板。模板允许在 HTML 文件中使用小代码片段,例如条件语句或循环。

当我们渲染一个模板时,除了模板文件名之外的任何参数都将传递到 HTML 模板服务中。以下路由将用户名和加入日期(来自其他地方的函数)传递到 HTML 中。

 @app.route("/users/")
 def profile(username):
     joinedDate = get_joined_date(username)  # 此函数的代码无关紧要
     awards = get_awards(username)  # 此函数的代码无关紧要
     # joinDate 是一个字符串,awards 是一个字符串数组
     return render_template("profile.html", username=username, joinDate=joinedDate, awards=awards)

当此模板被渲染时,它可以使用从 render_template() 函数传递给它的变量。以下是 profile.html 的内容:

 
 
   
     # if username
       Profile of {{ username }}
     # else
       No User Found
     # endif
   
   
     {% if username %}
       

{{ username }} joined on the date {{ date }}

{% if len(awards) > 0 %}

{{ username }} has the following awards:

    {% for award in awards %}
  • {{award}}
  • {% endfor %}
{% else %}

{{ username }} has no awards

{% endif %} {% else %}

No user was found under that username

{% endif %} {# This is a comment and doesn't affect the output #}

以下分隔符用于不同的解释:

  • {% ... %} 表示一个语句
  • {{ ... }} 表示一个表达式,其中模板被输出
  • {# ... #} 表示一个注释(不包括在模板输出中)
  • {# ... ## 表示该行的其余部分应被解释为一个语句

Section 126.6: 请求对象

请求对象提供了有关向路由发出的请求的信息。要使用此对象,必须从 Flask 模块导入它:

 from flask import request

URL 参数

在前面的示例中使用了 request.methodrequest.form,然而我们还可以使用 request.args 属性来检索 URL 参数中的键/值字典。

 @app.route("/api/users/")
 def user_api(username):
   try:
     token = request.args.get("key")
     if key == "pA55w0Rd":
       if isUser(username): # 此方法的代码无关紧要
         joined = joinDate(username) # 此方法的代码无关紧要
         return "User " + username + " joined on " + joined
       else:
         return "User not found"
     else:
       return "Incorrect key"
   # 如果没有关键参数
   except KeyError:
     return "No key provided"

为了在此上下文中正确进行身份验证,需要以下 URL(将用户名替换为任何用户名):

 www.example.com/api/users/guido-van-rossum?key=pa55w0Rd

文件上传

如果 POST 请求中提交的表单中包含文件上传,则可以使用请求对象处理文件:

 @app.route("/upload", methods=["POST"])
 def upload_file():
   f = request.files["wordlist-upload"]
   f.save("/var/www/uploads/" + f.filename) # 使用原始文件名存储

Cookie

请求还可以在与 URL 参数类似的字典中包含 Cookie。

 @app.route("/home")
 def home():
   try:
     username = request.cookies.get("username")
     return "Your stored username is " + username
   except KeyError:
     return "No username cookies was found")

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言