当前位置: 首页 > news >正文

城市联盟网站怎么做在线ui设计软件

城市联盟网站怎么做,在线ui设计软件,平面广告设计软件有哪些,企业网站cms系统论文文章目录2.1 Flask介绍及其安装2.2 Virtualenv3.1 一个最小的应用3.2 外部课件服务器3.3 调试模式4.1 路由介绍4.2 变量规则4.3 构建URL4.4 HTTP 方法4 总结5.1 静态文件5.2 渲染模板5.3 练习66.1 接收请求数据6.2 请求对象6.3 文件上传6.4 Cookies6 总结77.1 重定向和错误7.2 … 文章目录2.1 Flask介绍及其安装2.2 Virtualenv3.1 一个最小的应用3.2 外部课件服务器3.3 调试模式4.1 路由介绍4.2 变量规则4.3 构建URL4.4 HTTP 方法4 总结5.1 静态文件5.2 渲染模板5.3 练习66.1 接收请求数据6.2 请求对象6.3 文件上传6.4 Cookies6 总结77.1 重定向和错误7.2 关于响应7.3 会话7.4 消息闪烁7.5 日志和整合 WSGI 中间件7 总结7 练习参考 https://www.shiyanlou.com/courses/29/learning/?id2632.1 Flask介绍及其安装 Flask 是一个轻量级的 Web 应用框架, 使用 Python 编写。 基于 WerkzeugWSGI 工具箱和 Jinja2 模板引擎。使用 BSD 授权。 Flask 也被称为 microframework 因为它使用简单的核心用 extension 增加其它功能。 Flask 没有默认使用的数据库、窗体验证工具。 然而Flask 保留了扩增的弹性可以用 Flask-extension 加入这些功能ORM、窗体验证工具、文件上传、各种开放式身份验证技术。 当安装 Flask 时以下组件也会自动安装 Werkzeug: WSGIweb 服务器网关接口工具是介于应用和服务器之间标准的接口工具。Jinja: web 前端页面中使用的模板语言。MarkupSafe: 与 Jinja 配合使用当表单页面跳转时会进行验证从而避免遭遇不信任的输入带来的攻击。ItsDangerous: 安全地注入数据以确保数据的完整性通常用于保护 Flask 的 session cookie。Click: 一个解析命令行的应用它支持在 Flask 中自定义管理命令。 2.2 Virtualenv 也许 Virtualenv 是你在开发中最愿意使用的如果你在生产机器上有 shell 权限的时候也会愿意用上 Virtualenv。 virtualenv 解决了什么问题如果你像我一样喜欢 Python 的话有很多机会在基于 Flask 的 web 应用外的其它项目上使用 Python。 然而项目越多越有可能在不同版本的 python或者至少在不同 python 库的版本上工作。我们需要面对这样的事实库破坏向后兼容性的情况相当常见而且零依赖的正式应用也不大可能存在。如此当你的项目中的两个或更多出现依赖性冲突你会怎么做 Virtualenv 的出现解决这一切Virtualenv 能够允许多个不同版本的 Python 安装每一个服务于各自的项目。它实际上并没有安装独立的 Python 副本只是提供了一种方式使得环境保持独立。让我们见识下 virtualenv 怎么工作的。 如果你在 Mac OS X 或 Windows 下下面两条命令可能会适用: sudo easy_install virtualenv# 或者是 sudo pip3 install virtualenv上述的命令会在你的系统中安装 virtualenv。它甚至可能会出现在包管理器中。 如果是在 Windows 下并且没有安装 easy_install 命令你首先必须安装 easy_install 。要想获取更多的安装信息请查看 Windows 下的 pip 和 distribute 。一旦安装好 easy_install 运行上述的命令但是要去掉 sudo 前缀。 如果你使用 Ubuntu 请尝试: sudo apt-get install python-virtualenv一旦成功安装 virtualenv运行 shell 创建自己的环境。通常会创建一个项目文件夹 myproject其下创建 venv 文件夹该文件夹就是一个虚拟的 Python 环境同样的我们可以使用 -p 参数来改变 python 的版本默认情况下virtualenv 会优先选取系统默认的 python 环境。本实验中我们使用 python3 。 $ cd /home/shiyanlou/Code $ mkdir myproject cd myproject $ virtualenv -p /usr/bin/python3 venv New python executable in venv/bin/python Installing distribute............done.现在只要你想要在某个项目上在本课程中我们建议你在新建的 myproject 目录下这样 python 运行环境之间不存在冲突工作只要激活相应的环境。在 Mac OS X 和 Linux 下执行如下命令: . venv/bin/activate如果你是 Windows 用户下面的命令行是为你而准备: venv\scripts\activate无论哪种方式现在都能够使用你的 virtualenv (注意你的 shell 提示符显示的是活动的环境)。 接下来只需要输入以下的命令在 virtualenv 中安装 flask在本课程中统一使用 Flask 1.0.2 版本: pip3 install flask1.0.2几秒后一切就为你准备就绪。 检查是否成功安装 Flask: $ python3import flask2.2.2 全局安装 以下命令安装 Flask 也是可行的这样就是把 Flask 全局安装在操作环境中。只需要以 root 权限运行 pip: sudo apt-get update sudo pip3 install flask1.0.2 (在 Windows 系统上在管理员权限的命令提示符中运行这条命令不需要 sudo。)2.2.3 体验最新的 Flask (Living on the Edge) 如果你想要使用最新版的 Flask 可以直接在终端执行如下命令 sudo pip3 install -U https://github.com/pallets/flask/archive/master.tar.gz 3.1 一个最小的应用 一个最小的应用看起来像这样在 /home/shiyanlou/Code 目录下新建 hello.py 文件并向其中写入如下代码 from flask import Flask app Flask(__name__)app.route(/) def hello_world():return Hello, World! 那么这段代码做了什么首先我们导入了类 Flask。这个类的实例化将会是我们的 WSGI 应用。 接着我们创建一个该类的实例。第一个参数是应用模块或包的名称这样 Flask 才会知道去哪里寻找模板、静态文件等等。如果你使用的是单一的模块就如本例第一个参数应该使用 name。 我们使用装饰器route()告诉 Flask 哪个URL才能触发我们的函数。 定义一个函数该函数名也是用来给特定函数生成 URLs并且返回我们想要显示在用户浏览器上的信息。 使用 Python 解释器运行这个文件注意这个文件不能取名为flask.py因为这会与 Flask 本身冲突。 运行这个应用既可以使用 flask 命令行也可以使用 Python 的 -m 调用 flask在运行之前你需要设置 FLASK_APP 的环境变量来告诉终端需要运行哪个应用在终端执行如下命令 大家请注意记得要切回 Code 目录,才能调用在后续课程实例代码中将不会再提醒 $ cd /home/shiyanlou/Code $ export FLASK_APPhello.py $ flask run* Serving Flask app hello.py* Environment: productionWARNING: Do not use the development server in a production environment.Use a production WSGI server instead.* Debug mode: off* Running on http://127.0.0.1:5000/ (Press CTRLC to quit)也可以使用如下命令启动应用 $ export FLASK_APPhello.py$ python3 -m flask run* Serving Flask app hello.py* Environment: productionWARNING: Do not use the development server in a production environment.Use a production WSGI server instead.* Debug mode: off* Running on http://127.0.0.1:5000/ (Press CTRLC to quit)以上的命令启动了一个非常简单的 flask 内置服务器用于测试已经足够了但可能你并不想用于生产环境。更多配置可以参考开发者选项。 现在使用浏览器浏览http://127.0.0.1:5000/将会看到页面上的 Hello, World!。 请按Ctrlc来停止服务器。 3.2 外部课件服务器 一个最小的应用看起来像这样在 /home/shiyanlou/Code 目录下新建 hello.py 文件并向其中写入如下代码 from flask import Flask app Flask(name) app.route(’/’) def hello_world(): return ‘Hello, World!’ 那么这段代码做了什么 首先我们导入了类 Flask。这个类的实例化将会是我们的 WSGI 应用。 接着我们创建一个该类的实例。第一个参数是应用模块或包的名称这样 Flask 才会知道去哪里寻找模板、静态文件等等。如果你使用的是单一的模块就如本例第一个参数应该使用 name。 我们使用装饰器route()告诉 Flask 哪个URL才能触发我们的函数。 定义一个函数该函数名也是用来给特定函数生成 URLs并且返回我们想要显示在用户浏览器上的信息。 使用 Python 解释器运行这个文件注意这个文件不能取名为flask.py因为这会与 Flask 本身冲突。 运行这个应用既可以使用 flask 命令行也可以使用 Python 的 -m 调用 flask在运行之前你需要设置 FLASK_APP 的环境变量来告诉终端需要运行哪个应用在终端执行如下命令 大家请注意记得要切回 Code 目录,才能调用在后续课程实例代码中将不会再提醒 $ cd /home/shiyanlou/Code $ export FLASK_APPhello.py $ flask run* Serving Flask app hello.py* Environment: productionWARNING: Do not use the development server in a production environment.Use a production WSGI server instead.* Debug mode: off* Running on http://127.0.0.1:5000/ (Press CTRLC to quit)也可以使用如下命令启动应用 $ export FLASK_APPhello.py$ python3 -m flask run* Serving Flask app hello.py* Environment: productionWARNING: Do not use the development server in a production environment.Use a production WSGI server instead.* Debug mode: off* Running on http://127.0.0.1:5000/ (Press CTRLC to quit)以上的命令启动了一个非常简单的 flask 内置服务器用于测试已经足够了但可能你并不想用于生产环境。更多配置可以参考开发者选项。 现在使用浏览器浏览http://127.0.0.1:5000/将会看到页面上的 Hello, World!。 请按Ctrlc来停止服务器。 3.3 调试模式 使用 flask 命令行可以非常方便的启动一个本地开发服务器但是每次修改代码后你都需要手动重启服务器。通过前面的启动后输出显示可以发现 Environment 为 production同时调试模式未开启 Debug mode: off。 这样做并不好Flask 能做得更好。如果启用了调试支持在代码修改后服务器能够自动重载并且如果发生错误它会提供一个有用的调试器。 为了让所有的开发者特征可用包括调试模式在运行服务器之前可以设置 FLASK_ENV 环境变量为 development $ export FLASK_ENVdevelopment $ export FLASK_DEBUG1 $ flask run Serving Flask app “hello.py” (lazy loading)Environment: developmentDebug mode: onRunning on http://127.0.0.1:5000/ (Press CTRLC to quit)Restarting with statDebugger is active!Debugger PIN: 219-973-102 上述命令做了以下几件事 使调试器debugger可用 启动了代码改变自动的热加载 在 flask 应用中开启了 debug 模式 注意 尽管交互式调试器(debugger)不能在分叉(forking)环境下工作(这使得它几乎不可能在生产服务器上使用)它依然允许执行任意代码。这使它成为一个巨大的安全风险因此它绝对不能用于生产环境。 运行中的调试器的截图从截图可以看出在页面上有终端可以执行交互式命令: 本节讲解了一个 Flask 的小例子以及在命令行中通过设置环境变量来开启调试模式。 参考链接 WSGI 简介(https://blog.csdn.net/on_1y/article/details/18803563) 4.1 路由介绍 现代 Web 应用程序使用有意义的 URLs 去帮助用户。如果一个网站使用有意义的 URL 能够让用户记住并且直接访问这个页面那么用户会更有可能再一次访问该网站。 正如上面所说route 装饰器是用于把一个函数绑定到一个 URL 上。修改 /home/shiyanlou/Code/hello.py 文件的代码如下所示 from flask import Flask app Flask(__name__)# 如果访问 /,返回 Index Page app.route(/) def index():return Index Page# 如果访问 /hello返回 Hello, World! app.route(/hello) def hello():return Hello, World!然后在终端执行如下命令启动服务 export FLASK_APPhello.py export FLASK_ENVdevelopment flask run访问地址 http://127.0.0.1:5000浏览器页面会显示 Index Page如果访问地址 http://127.0.0.1:5000/hello浏览器页面会显示 Hello, World!。这样就实现了通过访问不同的 URL 地址从而响应不同的页面。 不仅如此你可以动态地构造 URL 的特定部分也可以在一个函数上绑定多个不同的规则。 4.2 变量规则 为了给 URL 增加变量的部分你需要把一些特定的字段标记成variable_name。这些特定的字段将作为参数传入到你的函数中。当然也可以指定一个可选的转换器通过规则converter:variable_name将变量值转换为特定的数据类型。 在 /home/shiyanlou/Code/hello.py 文件中添加如下的代码 app.route(/user/username) def show_user_profile(username):# 显示用户名return User {}.format(username)app.route(/post/int:post_id) def show_post(post_id):# 显示提交整型的用户id的结果注意int是将输入的字符串形式转换为整型数据return Post {}.format(post_id)app.route(/path/path:subpath) def show_subpath(subpath):# 显示 /path/ 之后的路径名return Subpath {}.format(subpath)按照前面的方式启动应用逐个访问地址 当访问 http://127.0.0.1:5000/user/shiyanlou 时页面显示为 User shiyanlou。 当访问 http://127.0.0.1:5000/post/3 时页面显示为 Post 3。用户在浏览器地址栏上输入的都是字符串但是在传递给 show_post 函数处理时已经被转换为了整型。 当访问 http://127.0.0.1:5000/path/file/A/a.txt 时页面显示为 Subpath file/A/a.txt。 转换器的主要类型如下 类型 含义 string 默认的数据类型接受没有任何斜杠“/”的字符串 int 接受整型 float 接受浮点类型 path 和 string 类似但是接受斜杠“/” uuid 只接受 uuid 字符串 唯一 URLs / 重定向行为 Flask 的 URL 规则是基于 Werkzeug 的 routing 模块。该模块背后的思路是基于 Apache 和早期的 HTTP 服务器定下先例确保优雅和唯一的 URL。 以这两个规则为例在 /home/shiyanlou/Code/hello.py 文件中添加如下的代码 app.route(/projects/) def projects():return The project pageapp.route(/about) def about():return The about page虽然它们看起来确实相似但它们结尾斜线的使用在 URL 定义中不同。 第一种情况中规范的 URL 指向 projects 尾端有一个斜线/。这种感觉很像在文件系统中的文件夹。访问一个结尾不带斜线的 URL 会被 Flask 重定向到带斜线的规范 URL 去。当访问 http://127.0.0.1:5000/projects/ 时页面会显示 The project page。 然而第二种情况的 URL 结尾不带斜线类似 UNIX-like 系统下的文件的路径名。此时如果访问结尾带斜线的 URL 会产生一个404 “Not Found”错误。当访问 http://127.0.0.1:5000/about 时页面会显示 The about page但是当访问 http://127.0.0.1:5000/about/ 时页面就会报错 Not Found。 当用户访问页面忘记结尾斜线时这个行为允许关联的 URL 继续工作并且与 Apache 和其它的服务器的行为一致反之则不行因此在代码的 URL 设置时斜线只可多写不可少写另外URL 会保持唯一有助于避免搜索引擎索引同一个页面两次。 4.3 构建URL 去构建一个 URL 来匹配一个特定的函数可以使用 url_for() 方法。它接受函数名作为第一个参数以及一些关键字参数每一个关键字参数对应于 URL 规则的变量部分。未知变量部分被插入到 URL 中作为查询参数。 为什么你要构建 URLs 而不是在模版中硬编码呢这里有几个理由 反向构建通常比硬编码更具备描述性。 它允许你一次性修改 URL而不是到处找 URL 修改。 构建 URL 能够显式地处理特殊字符和Unicode转义因此你不必去处理这些。 如果你的应用不在 URL 根目录下(比如在 /myapplication 而不在 /)url_for()将会适当地替你处理好。 在 Python shell 交互式命令行下运行如下代码 记得切回myproject对应目录 $ python3from flask import Flask, url_forapp Flask(__name__)app.route(/) ... def index(): ... return index ...app.route(/login) ... def login(): ... return login ...app.route(/user/username) ... def profile(username): ... return {}\s profile.format(username) ...with app.test_request_context(): ... print(url_for(index)) ... print(url_for(login)) ... print(url_for(login, next/)) ... print(url_for(profile, usernameJohn Doe)) ... / /login /login?next%2F # 对字符串进行了转义未知变量部分被当做查询参数 /user/John%20Doetest_request_context() 方法告诉 Flask 表现得像是在处理一个请求即使我们正在通过 Python shell 交互。大家可以仔细分析一下该函数的打印结果。 4.4 HTTP 方法 HTTP (也就是 Web 应用协议) 有不同的方法来访问 URLs 。默认情况下路由只会响应 GET 请求但是能够通过给 route() 装饰器提供 methods 参数来改变。这里是一个例子: app.route(/login, methods[GET, POST]) def login():if request.method POST:do_the_login() # 如果是 POST 方法就执行登录操作else:show_the_login_form() # 如果是 GET 方法就展示登录表单如果使用 GET 方法HEAD 方法将会自动添加进来。你不必处理它们。也能确保 HEAD 请求会按照 HTTP RFC (文档在 HTTP 协议里面描述) 要求来处理因此你完全可以忽略这部分 HTTP 规范。同样地自从 Flask 0.6 后OPTIONS 方法也能自动为你处理。 也许你并不清楚 HTTP 方法是什么别担心这里有一个 HTTP 方法的快速入门以及为什么它们重要 HTTP方法通常也称为“谓词”告诉服务器客户端想要对请求的页面做什么。 下面这些方法是比较常见的 GET浏览器通知服务器只获取页面上的信息并且发送回来。这可能是最常用的方法。 HEAD浏览器告诉服务器获取信息但是只对头信息感兴趣不需要整个页面的内容。应用应该处理起来像接收到一个 GET 请求但是不传递实际内容。在 Flask 中你完全不需要处理它底层的 Werkzeug 库会为你处理的。 POST浏览器通知服务器它要在 URL 上提交一些信息服务器必须保证数据被存储且只存储一次。这是 HTML 表单通常发送数据到服务器的方法。 PUT同 POST 类似但是服务器可能触发了多次存储过程多次覆盖掉旧值。现在你就会问这有什么用有许多理由需要如此去做。考虑下在传输过程中连接丢失在这种情况下浏览器和服务器之间的系统可能安全地第二次接收请求而不破坏其它东西。该过程操作 POST 方法是不可能实现的因为它只会被触发一次。 DELETE移除给定位置的信息。 OPTIONS给客户端提供一个快速的途径来指出这个 URL 支持哪些 HTTP 方法。从 Flask 0.6 开始自动实现了该功能。 现在在 HTML4 和 XHTML1 中表单只能以 GET 和 POST 方法来提交到服务器。在 JavaScript 和以后的 HTML 标准中也能使用其它的方法。同时HTTP 最近变得十分流行浏览器不再是唯一使用 HTTP 的客户端。比如许多版本控制系统使用 HTTP。 4 总结 本节讲解了 Flask 的路由我们可以给 URL 添加规则也可以动态地构建 URL 。 5.1 静态文件 动态的 web 应用同样需要静态文件。CSS 和 JavaScript 文件通常来源于此。理想情况下你的 web 服务器已经配置好为它们服务然而在开发过程中 Flask 就能够做到。只要在你的包中或模块旁边创建一个名为static 的文件夹在应用中使用 /static 即可访问。 给静态文件生成 URL 使用特殊的 static 端点名: url_for(static, filenamestyle.css)这个文件是应该存储在文件系统上的static/style.css。 5.2 渲染模板 在 Python 中生成 HTML 并不好玩实际上是相当繁琐的因为你必须自行做好 HTML 转义以保持应用程序的安全。由于这个原因Flask 自动为你配置好 Jinja2 模板。 你可以使用方法 render_template() 来渲染模板。所有你需要做的就是提供模板的名称以及你想要作为关键字参数传入模板的变量。 这里有个渲染模板的简单例子在 /home/shiyanlou/Code 目录下新建 hello.py 文件并向其中添加如下代码: from flask import Flask, render_template app Flask(__name__)app.route(/hello/) app.route(/hello/name) def hello(nameNone): # 默认 name 为 Nonereturn render_template(hello.html, namename) # 将 name 参数传递到模板变量中Flask 将会在 templates 文件夹中寻找模板。因此如果你的应用是个模块这个文件夹在模块的旁边如果它是一个包那么这个文件夹在你的包里面: 比如应用是模块本系列实验的应用结构都是模块型: /application.py /templates/hello.html比如应用是包: /application/__init__.py/templates/hello.html对于模板你可以使用 Jinja2 模板的全部能力。详细信息查看官方的 Jinja2 Template Documentation 。 在 /home/shiyanlou/Code 目录下新建 templates 文件夹并在其中新建 hello.html 文件 cd /home/shiyanlou/Code mkdir templates cd templates touch hello.html然后向 hello.html 模板文件中添加如下代码 !doctype html titleHello from Flask/title {% if name %} !-- 如果 name 不为空则将 name 渲染出来 --h1Hello {{ name }}!/h1 {% else %} !-- 如果 name 为空则打印 Hello World! --h1Hello World!/h1 {% endif %}按照前面的方法运行应用程序当访问 http://127.0.0.1:5000/hello/ 时页面显示 Hello World!当访问 http://127.0.0.1:5000/hello/shiyanlou 时页面显示 Hello shiyanlou!。 在模板中你也可以使用requestsession和g对象也能使用函数get_flashed_messages() 。 模板继承是十分有用的。如果想要知道模板继承如何工作的话请阅读文档模板继承。基本的模板继承使得某些特定元素如标题、导航和页脚在每一页成为可能。 自动转义默认是开启的因此如name包含 HTML它将会自动转义。如果你信任一个变量并且你知道它是安全的例如一个模块把 wiki 标记转换到 HTML 你可以用Markup类或|safe过滤器在模板中标记它是安全的。 在 Jinja 2 文档中你会见到更多例子。 下面有一个Markup类如何工作的基本介绍在 Python3 交互式命令行中执行如下命令 $ python3from flask import MarkupMarkup(strongHello %s!/strong) % blinkhacker/blink Markup(strongHello lt;blinkgt;hackerlt;/blinkgt;!/strong)Markup.escape(blinkhacker/blink) Markup(lt;blinkgt;hackerlt;/blinkgt;)Markup(emMarked up/em raquo; HTML).striptags() Marked up » HTML注意在后面的0.5版本以上: 自动转义不再在所有模板中启用。模板中下列后缀的文件会触发自动转义.html, .htm, .xml,.xhtml。从字符串加载的模板会禁用自动转义。 5.3 练习 请创建一个模板和CSS文件并在模板引入CSS文件当访问网站首页时显示一个绿色的Hello ShiYanLou字样。 6 对于 Web 应用来说对客户端发送给服务器的数据做出反应至关重要本实验将介绍 Flask 是怎样提供这些信息的。 6.1 接收请求数据 在 Flask 中由全局对象 request 来提供这些信息。如果你有一定的 Python 经验你会好奇这个对象怎么可能是全局的并且 Flask 是怎么还能保证线程安全。答案是上下文作用域。 局部上下文 注意如果你想要了解上下文作用域是如何工作的以及如何使用它进行测试就可以读这一部分如果暂时不需要的话可以直接跳过这部分。 Flask 中的某些对象是全局对象但不是通常的类型。这些对象实际上是给定上下文的局部对象的代理。虽然很拗口但实际上很容易理解。 想象下线程处理的上下文。一个请求传入web 服务器决定产生一个新线程(或者其它东西底层对象比线程更有能力处理并发系统)。当 Flask 开始它内部请求处理时它认定当前线程是活动的上下文并绑定当前的应用和 WSGI 环境到那个上下文线程。它以一种智能的方法来实现以致一个应用可以调用另一个应用而不会中断。 所以这对你意味着什么呢除非你是在做一些类似单元测试的事情否则基本上你可以完全忽略这种情况。你会发现依赖于请求对象的代码会突然中断因为没有请求对象。解决方案就是自己创建一个请求并把它跟上下文绑定。 针对单元测试最早的解决方案是使用test_request_context()上下文管理器。结合with声明它将绑定一个测试请求来进行交互。这里是一个例子: from flask import requestwith app.test_request_context(/hello, methodPOST):# 现在你可以做出请求比如基本的断言assert request.path /helloassert request.method POST另一个可能性就是传入整个 WSGI 环境到request_context()方法: from flask import requestwith app.request_context(environ):assert request.method POST参考链接 Flask 上下文理解 https://jin-yang.github.io/post/flask-context.html Flask 的 Context 机制https://blog.tonyseek.com/post/the-context-mechanism-of-flask/ 6.2 请求对象 首先你需要从 flask 模块中导入request: from flask import request当前请求的方法可以用method属性来访问。你可以用form属性来访问表单数据 (数据在 POST 或者PUT中传输)。这里是上面提及到的两种属性的完整的例子: app.route(/login, methods[POST, GET]) def login():error Noneif request.method POST:if valid_login(request.form[username],request.form[password]):return log_the_user_in(request.form[username])else:error Invalid username/password# 当请求形式为“GET”或者认证失败则执行以下代码return render_template(login.html, errorerror)如果在form属性中不存在上述键值会发生些什么在这种情况下会触发一个特别的 KeyError。你可以像捕获标准的KeyError一样来捕获它如果你不这样去做会显示一个HTTP 400 Bad Request错误页面。所以很多情况下你不需要处理这个问题。 你可以用args属性来接收在URL ( ?keyvalue )中提交的参数: searchword request.args.get(key, )我们推荐使用get来访问 URL 参数或捕获KeyError因为用户可能会修改 URL向他们显示一个400 bad request页面不是用户友好的。 6.3 文件上传 你能够很容易地用 Flask 处理文件上传。只要确保在你的 HTML 表单中不要忘记设置属性enctype“multipart/form-data”否则浏览器将不会传送文件。 上传的文件是存储在内存或者文件系统上一个临时位置。你可以通过请求对象中files属性访问这些文件。每个上传的文件都会存储在这个属性字典里。它表现得像一个标准的 Python file对象但是它同样具有save()方法该方法允许你存储文件在服务器的文件系统上。 下面是一个简单的例子用来演示提交文件到服务器上: from flask import requestapp.route(/upload, methods[GET, POST]) def upload_file():if request.method POST:f request.files[the_file]f.save(/var/www/uploads/uploaded_file.txt)...如果你想要知道在上传到你的应用之前在客户端的文件名称你可以访问filename属性。但请记住永远不要信任这个值因为这个值可以伪造。如果你想要使用客户端的文件名来在服务器上存储文件把它传递到Werkzeug提供给你的secure_filename()函数: from flask import request from werkzeug import secure_filenameapp.route(/upload, methods[GET, POST]) def upload_file():if request.method POST:f request.files[the_file]f.save(/var/www/uploads/ secure_filename(f.filename))...6.4 Cookies 你可以用 cookies 属性来访问 Cookies 。你能够用响应对象的 set_cookie 来设置 cookies。请求对象中的 cookies 属性是一个客户端发送所有的 cookies 的字典。 如果你要使用会话(sessions)请不要直接使用 cookies相反请用 Flask 中的会话Flask 已经在cookies 上增加了一些安全细节关于更多 seesions 和 cookies 的区别与联系请参见施杨出品的博客。 读取 cookies: from flask import requestapp.route(/) def index():username request.cookies.get(username)# 注意这里引用cookies字典的键值对是使用cookies.get(key)# 而不是cookies[key]这是防止该字典不存在时报错keyerror 存储 cookies:from flask import make_responseapp.route(/) def index():resp make_response(render_template(...))resp.set_cookie(username, the username)return resp注意cookies是在响应对象中被设置。由于通常只是从视图函数返回字符串Flask 会将其转换为响应对象。如果你要显式地这么做可以使用 make_response() 函数接着修改它。 有时候你可能要在响应对象不存在的地方设置cookie。利用延迟请求回调模式使得这种情况成为可能。 6 总结 本节讲解了 flask 的请求如果想在没有请求的情况下获取上下文可以使用test_request_context()或者request_context()从request对象的form中可以获取表单的数据args中可以获取 URL 中的参数files可以获取上传的文件cookies可以操作cookie。 7 7.1 重定向和错误 你能够用redirect()函数重定向用户到其它地方。能够用abort()函数提前中断一个请求并带有一个错误代码。 下面是一个演示它们如何工作的例子在 /home/shiyanlou/Code/ 目录下新建 hello.py 文件并向其中写入如下代码 from flask import Flask from flask import abort, redirect, url_forapp Flask(__name__)app.route(/) def index():return redirect(url_for(login))app.route(/login) def login():abort(401)this_is_never_executed()按照之前的方式运行应用这是一个相当无意义的例子因为用户会从主页/重定向到一个不能访问的页面/login 401 意味着禁止访问但是它说明了重定向如何工作。 默认情况下每个错误代码会显示一个黑白错误页面。比如上面的页面会显示 401 Unauthorized。如果你想定制错误页面可以使用errorhandler()装饰器向 /home/shiyanlou/Code/hello.py 文件中添加如下代码: from flask import render_templateapp.errorhandler(401) def page_not_found(error):return render_template(page_not_found.html), 404注意到 404 是在render_template()调用之后。告诉 Flask 该页的错误代码应是 404 即没有找到。默认的 200 被假定为一切正常。 在 /home/shiyanlou/Code 目录下新建 templates 文件夹并在其中新建 page_not_found.html 文件。 cd /home/shiyanlou/Code mkdir templates cd templates touch page_not_found.html向 page_not_found.html 文件中添加如下代码 h1page not found, this is an error page./h1等代码重新热加载后访问首页就可以看到 page not found, this is an error page.。 7.2 关于响应 一个视图函数的返回值会被自动转换为一个响应对象。如果返回值是一个字符串它被转换成一个响应主体是该字符串错误代码为 200 OK 媒体类型为text/html的响应对象。Flask 把返回值转换成响应对象的逻辑如下 如果返回的是一个合法的响应对象它会直接从视图返回。 如果返回的是一个字符串响应对象会用字符串数据和默认参数创建。 如果返回的是一个元组而且元组中元素能够提供额外的信息。这样的元组必须是(response, status, headers) 形式且至少含有其中的一个元素。status值将会覆盖状态代码headers可以是一个列表或额外的消息头值字典。 如果上述条件均不满足Flask 会假设返回值是一个合法的 WSGI 应用程序并转换为一个请求对象。 如果你想要获取在视图中得到的响应对象你可以用函数make_response()。 想象你有这样一个视图: app.errorhandler(404) def not_found(error):return render_template(error.html), 404 你只需要用make_response()封装返回表达式获取结果对象并修改然后返回它app.errorhandler(404) def not_found(error):resp make_response(render_template(error.html), 404)resp.headers[X-Something] A valuereturn resp7.3 会话 除了请求对象还有第二个称为session对象允许你在不同请求间存储特定用户的信息。这是在 cookies 的基础上实现的并且在 cookies 中使用加密的签名。这意味着用户可以查看 cookie 的内容但是不能修改它除非知道签名的密钥。 要使用会话你需要设置一个密钥。这里介绍会话如何工作在 /home/shiyanlou/Code 目录下新建 test.py 文件并写入如下代码 from flask import Flask, session, redirect, url_for, escape, requestapp Flask(__name__)# 设置密钥保证会话安全 app.secret_key _5#y2LF4Q8z\n\xec]/app.route(/) def index():if username in session:return Logged in as %s % escape(session[username])return You are not logged inapp.route(/login, methods[GET, POST]) def login():if request.method POST:session[username] request.form[username]return redirect(url_for(index))return form methodpostpinput typetext nameusernamepinput typesubmit valueLogin/formapp.route(/logout) def logout():# 如果用户名存在则从会话中移除该用户名session.pop(username, None)return redirect(url_for(index))这里提到的escape()可以在你不使用模板引擎的时候做转义如同本例。其中login函数中返回的网页源代码可以单独存储在templates文件夹中作为模板文件html然后使用return render_template()更方便。 按照前面的方式运行程序 当访问首页 http://127.0.0.1:5000/ 时会显示 You are not logged in 当访问登录页面 http://127.0.0.1:5000/login 时会出现一个输入框在输入框中输入用户名 shiyanlou然后点击 Login 按钮这时 URL 会重定向到首页上首页显示 Logged in as shiyanlou 最后再访问登出页面 http://127.0.0.1:5000/logout这时从 session 中移除了用户名URL 重定向到首页显示 You are not logged in 怎样产生一个好的密钥 随机的问题在于很难判断什么是真随机。一个密钥应该足够随机。你的操作系统可以基于一个密码随机生成器来生成漂亮的随机值这个值可以用来做密钥: $ python3 -c import os; print(os.urandom(16)) bm \xf8]?\x86\xcf/y\x0e\xc5\xc7j\xc5/把这个值复制粘贴到你的代码你就搞定了密钥。 使用基于 cookie 的会话需注意: Flask 会将你放进会话session对象的值序列化到 cookie 。如果你试图寻找一个跨请求不能存留的值cookies 确实是启用的并且你不会获得明确的错误信息检查你页面请求中 cookie 的大小并与 web 浏览器所支持的大小对比。 7.4 消息闪烁 好的应用和用户界面全部是关于反馈。如果用户得不到足够的反馈他们可能会变得讨厌这个应用。Flask 提供了一个真正的简单的方式来通过消息闪现系统给用户反馈。消息闪现系统基本上使得在请求结束时记录信息并在下一个 且仅在下一个请求中访问。通常结合模板布局来显示消息。 使用flash()方法来闪现一个消息使用get_flashed_messages()能够获取消息get_flashed_messages()也能用于模板中。 下面来看一个简单的例子在 /home/shiyanlou/Code 目录下新建 flashTest.py 文件并向其中写入如下代码 from flask import Flask, flash, redirect, render_template, \request, url_forapp Flask(__name__) app.secret_key b_5#y2LF4Q8z\n\xec]/app.route(/) def index():return render_template(index.html)app.route(/login, methods[GET, POST]) def login():error Noneif request.method POST:if request.form[username] ! admin or \request.form[password] ! secret:error Invalid credentialselse:flash(You were successfully logged in)return redirect(url_for(index))return render_template(login.html, errorerror)然后在 /home/shiyanlou/Code/templates 目录下新建 base.html 页面其中写入基本的模板代码代码主要是从后端获取 flash 消息以及错误信息。 !doctype html titleMy Application/title {% with messages get_flashed_messages() %}{% if messages %}ul classflashes{% for message in messages %}li{{ message }}/li{% endfor %}/ul{% endif %} {% endwith %} {% block body %}{% endblock %} 在该目录下新建 index.html 页面这个页面继承于 base.html 页面{% extends base.html %} {% block body %}h1Overview/h1pDo you want to a href{{ url_for(login) }}log in?/a {% endblock %}在该目录下新建 login.html 页面这个页面也继承于 base.html 页面 {% extends base.html %} {% block body %}h1Login/h1{% if error %}p classerrorstrongError:/strong {{ error }}{% endif %}form methodpostdldtUsername:ddinput typetext nameusername value{{request.form.username }}dtPassword:ddinput typepassword namepassword/dlpinput typesubmit valueLogin/form {% endblock %}按照前面的方式运行程序 当访问首页 http://127.0.0.1:5000会提示 Do you want to log in?点击链接跳转到登录页面。 在登录页面 http://127.0.0.1:5000/login输入用户名和密码如果输入错误的信息比如两个都为 shiyanlou点击 Login就会出现错误提示 Error: Invalid credentials。如果用户名输入 admin、密码输入 secret点击 Login就会跳转到首页同时在首页会显示 flash 消息 You were successfully logged in。 7.5 日志和整合 WSGI 中间件 日志 有时候你会遇到一种情况理论上来说你处理的数据应该是正确的然而实际上并不正确的状况。比如你可能有一些客户端代码代码向服务器发送一个 HTTP 请求但是显然它是错误的。这可能是由于用户篡改数据或客户端代码失败。大部分时候针对这一情况返回400 Bad Request就可以了但是有时候不能这样做代码必须继续工作。 你也有可能想要记录一些发生的不正常事情。这时候日志就派上用处。从 Flask 0.3 开始日志记录是预先配置好的。 这里有一些日志调用的例子: app.logger.debug(A value for debugging) app.logger.warning(A warning occurred (%d apples), 42) app.logger.error(An error occurred)附带的 logger 是一个标准的日志类 Logger 因此更多的信息请查阅官方文档 logging documentation。 整合 WSGI 中间件 如果你想给你的应用添加 WSGI 中间件你可以封装内部 WSGI 应用。例如如果你想使用 Werkzeug 包中的某个中间件来应付 lighttpd 中的 bugs你可以这样做: from werkzeug.contrib.fixers import LighttpdCGIRootFix app.wsgi_app LighttpdCGIRootFix(app.wsgi_app)7 总结 本节讲了 flask 的重定向、响应、会话和扩展重定向可以使用redirect()错误处理可以使用errorhander装饰器session对象保存会话信息要使用会话需要设置secret_key可以用make_response函数生成响应flash可以用于消息闪现flask 也能够整合 WSGI 中间件。 7 练习 请实现一个完整的用户登录功能: 当访问地址 http://127.0.0.1:5000/login 出现登录页面可以使用用户名和密码填写登录表单。 如果用户名和密码都为shiyanlou那么就把用户名数据放到session中把地址重定向到首页显示Hello shiyanlou同时闪现消息 you were logged in。 如果用户名和密码不对依然把地址重定向到首页显示hello world同时闪现消息 username or password invalid。 参考 https://www.shiyanlou.com/courses/29/learning/?id263
http://www.yutouwan.com/news/206972/

相关文章:

  • 杭州建设企业网站的网站建设规划设计公司
  • 上海缪斯设计公司地址seo优化厂家
  • 设计网站开发沈阳市网站建设企业
  • 巩义网站推广优化shein跨境电商官网
  • 培训校园网站建设简报东营城乡规划网
  • 网站快速收录工具网上商城建设方案
  • 电商网站前端模板那些知名网站是外包做的
  • 做网站背景图的科技图片宝山区建设用地事务所网站
  • h5自适应网站模板中国电子科技集团有限公司
  • 黄冈网站推广代运营内蒙古建设项目环保备案网站
  • 校园局域网站建设费用学什么可以先做网站
  • 企业网站建设的材料模板建网站费用
  • 微信导航网站有用吗东莞智通人才网登录
  • 商务网站建设的主流程快速网站建设多少钱
  • 买了空间和域名 就有网站后台了吗小程序注册登录
  • 广州住建官方网站广东网站设计服务商
  • 极速建站系统wordpress 中文连接
  • 免费网站app哪个最好一个网站里有两个网页怎么做
  • 哪个网站的域名便宜公司如何做网站不发钱
  • 个人网站要买多大的空间左旗网站建设公司
  • 房产网站建设什么类型医院网站建设熊掌号
  • 自己的网站怎么做网盘如何用手机制作网页链接
  • 自建网站编程天津做网站价格
  • 广州新际网站建设seo流量排名门户
  • 清远建设网站制作申请注册公司需要什么资料
  • 淄博网站排名seo高级服装定制网站
  • 2017年做那个网站致富专业网站设计工作室
  • 网站建设管理考核办法南江红鱼洞水库建设管理局网站
  • 12306网站开发wordpress随机文章
  • 网页设计与网站建设在线考试石油大学门店管理系统软件免费