做门户网站找哪家公司宣武网站建设

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

做门户网站找哪家公司,宣武网站建设,网站建设与制,邢台多地划为高风险区Flask是一个轻量级的基于Python的web框架。 我们建议使用最新版本的 Python。Flask 支持 Python 3.8 及更高版本。 官网#xff1a;欢迎使用 Flask — Flask 文档 #xff08;3.0.x#xff09; (palletsprojects.com) RESTFul API#xff1a;Python Flask高级编程之REST…Flask是一个轻量级的基于Python的web框架。 我们建议使用最新版本的 Python。Flask 支持 Python 3.8 及更高版本。 官网欢迎使用 Flask — Flask 文档 3.0.x (palletsprojects.com) RESTFul APIPython Flask高级编程之RESTFul API前后端分离学习笔记 完整项目Python Flask Web PyQt 前后端分离的项目—学习成绩可视化分析系统附源码 1.简介 Flask 是一个轻量级的 Python Web 应用框架它由 Armin Ronacher 开发并由社区维护。Flask 的设计理念是简单、灵活它提供了构建 Web 应用所需的基本组件同时也允许开发者根据自己的需求灵活地扩展功能。 2.安装 通过pip安装Flask即可 \( pip install Flask安装 Flask 时将自动安装这些发行版。 Werkzeug 实现了 WSGI这是 应用程序和服务器。 Jinja 是一种模板语言用于呈现应用程序的页面 服务。 MarkupSafe 随 Jinja 一起提供。它在渲染时转义不受信任的输入 模板来避免注入攻击。 ItsDangerous 安全地对数据进行签名以确保其完整性。这是用的 以保护 Flask 的会话 cookie。 Click 是用于编写命令行应用程序的框架。它提供 命令并允许添加自定义管理命令。flask Blinker 提供对 Signals 的支持。 3. 快速入门从 Hello World 开始 本节主要内容使用Flask写一个显示”Hello World!”的web程序如何配置、调试Flask。 3.1 Hello World 按照以下命令建立Flask项目HelloWorld: mkdir HelloWorld mkdir HelloWorld/static mkdir HelloWorld/templates touch HelloWorld/server.pystatic和templates目录是默认配置其中static用来存放静态资源例如图片、js、css文件等。templates存放模板文件。 我们的网站逻辑基本在server.py文件中当然也可以给这个文件起其他的名字。 在server.py中加入以下内容 from flask import Flaskapp Flask(__name__)app.route(/) def hello_world():return Hello World!if __name__ __main__:app.run()运行server.py \) python3 server.py * Running on http://127.0.0.1:5000/打开浏览器访问http://127.0.0.1:5000/浏览页面上将出现Hello World!。 终端里会显示下面的信息 127.0.0.1 - - [16/May/2014 10:29:08] GET / HTTP/1.1 200 -变量app是一个Flask实例通过下面的方式 app.route(/) def hello_world():return Hello World!当客户端访问/时将响应hello_world()函数返回的内容。注意这不是返回Hello World!这么简单Hello World!只是HTTP响应报文的实体部分状态码等信息既可以由Flask自动处理也可以通过编程来制定。 3.2 修改Flask的配置 app Flask(name)上面的代码中python内置变量name的值是字符串main 。Flask类将这个参数作为程序名称。当然这个是可以自定义的比如app  Flask(my-app)。 Flask默认使用static目录存放静态资源templates目录存放模板这是可以通过设置参数更改的 app Flask(my-app, static_folderpath1, template_folderpath2)更多参数请参考doc from flask import Flask print(Flask.doc)3.3 调试模式 上面的server.py中以app.run()方式运行这种方式下如果服务器端出现错误是不会在客户端显示的。但是在开发环境中显示错误信息是很有必要的要显示错误信息应该以下面的方式运行Flask app.run(debugTrue)将debug设置为True的另一个好处是程序启动后会自动检测源码是否发生变化若有变化则自动重启程序。这可以帮我们省下很多时间。 3.4 绑定IP和端口 默认情况下Flask绑定IP为127.0.0.1端口为5000。我们也可以通过下面的方式自定义 app.run(host0.0.0.0, port80, debugTrue)0.0.0.0代表电脑所有的IP。80是HTTP网站服务的默认端口。什么是默认比如我们访问网站http://www.example.com其实是访问的http://www.example.com:80只不过:80可以省略不写。 由于绑定了80端口需要使用root权限运行server.py。也就是 \( python3 server.py4. 获取 URL 参数 URL参数是出现在url中的键值对例如http://127.0.0.1:5000/?disp3中的url参数是{disp:3}。 4.1 建立Flask项目 按照以下命令建立Flask项目HelloWorld: mkdir HelloWorld mkdir HelloWorld/static mkdir HelloWorld/templates touch HelloWorld/server.py4.2 列出所有的url参数 在server.py中添加以下内容 from flask import Flask, requestapp Flask(__name__)app.route(/) def hello_world():return request.args.__str__()if __name__ __main__:app.run(port5000, debugTrue)在浏览器中访问http://127.0.0.1:5000/?userFlasktimep7p8将显示 ImmutableMultiDict([(user, Flask), (time, ), (p, 7), (p, 8)])在浏览器中访问http://127.0.0.1:5000/?info这是爱将显示 ImmutableMultiDict([(info, 这是爱)])浏览器传给我们的Flask服务的数据长什么样子呢可以通过request.full_path和request.path来看一下 from flask import Flask, requestapp Flask(__name__)app.route(/) def hello_world():print(request.path)print(request.full_path)return request.args.__str__()if __name__ __main__:app.run(port5000, debugTrue)浏览器访问http://127.0.0.1:5000/?info这是爱运行server.py的终端会输出 / /?info%E8%BF%99%E6%98%AF%E7%88%B1%EF%BC%8C4.3 获取某个指定的参数 例如要获取键info对应的值如下修改server.py from flask import Flask, requestapp Flask(__name__)app.route(/) def hello_world():return request.args.get(info)if __name__ __main__:app.run(port5000)运行server.py在浏览器中访问http://127.0.0.1:5000/?infohello浏览器将显示 hello不过当我们访问http://127.0.0.1:5000/时候却出现了500错误浏览器显示 为什么为这样 这是因为没有在URL参数中找到info。所以request.args.get(info)返回Python内置的None而Flask不允许返回None。 解决方法很简单我们先判断下它是不是None from flask import Flask, requestapp Flask(__name__)app.route(/) def hello_world():r request.args.get(info)if rNone:# do somethingreturn return rif __name__ __main__:app.run(port5000, debugTrue) 另外一个方法是设置默认值也就是取不到数据时用这个值 from flask import Flask, requestapp Flask(__name__)app.route(/) def hello_world():r request.args.get(info, hi)return rif __name__ __main__:app.run(port5000, debugTrue)函数request.args.get的第二个参数用来设置默认值。此时在浏览器访问http://127.0.0.1:5000/将显示 hi4.4 如何处理多值 还记得上面有一次请求是这样的吗 http://127.0.0.1:5000/?userFlasktimep7p8仔细看下p有两个值。 如果我们的代码是 from flask import Flask, requestapp Flask(__name__)app.route(/) def hello_world():r request.args.get(p)return rif __name__ __main__:app.run(port5000, debugTrue)在浏览器中请求时我们只会看到7。如果我们需要把p的所有值都获取到该怎么办 不用get用getlist from flask import Flask, requestapp Flask(__name__)app.route(/) def hello_world():r request.args.getlist(p) # 返回一个listreturn str(r)if __name__ __main__:app.run(port5000, debugTrue)浏览器输入 http://127.0.0.1:5000/?userFlasktimep7p8我们会看到[7, 8]。 5. 获取POST方法传送的数据 作为一种HTTP请求方法POST用于向指定的资源提交要被处理的数据。我们在某网站注册用户、写文章等时候需要将数据传递到网站服务器中。并不适合将数据放到URL参数中密码放到URL参数中容易被看到文章数据又太多浏览器不一定支持太长长度的URL。这时一般使用POST方法。 本文使用python的requests库模拟浏览器。 安装方法 \) pip install requests5.1 建立Flask项目 按照以下命令建立Flask项目HelloWorld: mkdir HelloWorld mkdir HelloWorld/static mkdir HelloWorld/templates touch HelloWorld/server.py5.2 查看POST数据内容 以用户注册为例子我们需要向服务器/register传送用户名name和密码password。如下编写HelloWorld/server.py。 from flask import Flask, requestapp Flask(name)app.route(/) def hello_world():return hello worldapp.route(/register, methods[POST]) def register():print(request.headers)print(request.stream.read())return welcomeif name main:app.run(port5000, debugTrue)app.route(‘/register’, methods[‘POST’])是指url/register只接受POST方法。可以根据需要修改methods参数例如如果想要让它同时支持GET和POST这样写 app.route(/register, methods[GET, POST]) 浏览器模拟工具client.py内容如下 import requestsuser_info {name: admin, password: 123} r requests.post(http://127.0.0.1:5000/register, datauser_info)print(r.text)运行HelloWorld/server.py然后运行client.py。client.py将输出 welcome而HelloWorld/server.py在终端中输出以下调试信息通过print输出 Host: 127.0.0.1:5000 User-Agent: python-requests/2.28.2 Accept-Encoding: gzip, deflate
Accept: / Connection: keep-alive Content-Length: 24 Content-Type: application/x-www-form-urlencodedbnameadminpassword123 前6行是client.py生成的HTTP请求头由print(request.headers)输出。 请求体的数据我们通过print(request.stream.read())输出结果是 bnameadminpassword1235.3 解析POST数据 上面我们看到post的数据内容是 bnameadminpassword123我们要想办法把我们要的name、password提取出来怎么做呢自己写不用Flask已经内置了解析器request.form。 我们将服务代码改成 from flask import Flask, requestapp Flask(name)app.route(/) def hello_world():return hello worldapp.route(/register, methods[POST]) def register():print(request.headers)# print(request.stream.read()) # 不要用否则下面的form取不到数据print(request.form)print(request.form[name])print(request.form.get(name))print(request.form.getlist(name))print(request.form.get(nickname, defaultlittle apple))return welcomeif name main:app.run(port5000, debugTrue)执行client.py请求数据服务器代码会在终端输出 Host: 127.0.0.1:5000 User-Agent: python-requests/2.28.2 Accept-Encoding: gzip, deflate Accept: / Connection: keep-alive Content-Length: 24 Content-Type: application/x-www-form-urlencodedImmutableMultiDict([(name, admin), (password, 123)]) admin admin [admin] little applerequest.form会自动解析数据。 request.form[name]和request.form.get(name)都可以获取name对应的值。对于request.form.get()可以为参数default指定值以作为默认值。所以 print(request.form.get(nickname, defaultlittle apple))输出的是默认值 little apple如果name有多个值可以使用request.form.getlist(name)该方法将返回一个列表。我们将client.py改一下 import requestsuser_info {name: [admin, admin2], password: 123} r requests.post(http://127.0.0.1:5000/register, datauser_info)print(r.text)此时运行client.pyprint(request.form.getlist(name))将输出 [uadmin, uadmin2]6. 处理和响应JSON数据 使用 HTTP POST 方法传到网站服务器的数据格式可以有很多种比如「5. 获取POST方法传送的数据」讲到的nameletianpassword123这种用过符号分割的key-value键值对格式。我们也可以用JSON格式、XML格式。相比XML的重量、规范繁琐JSON显得非常小巧和易用。 6.1 建立Flask项目 按照以下命令建立Flask项目HelloWorld: mkdir HelloWorld mkdir HelloWorld/static mkdir HelloWorld/templates touch HelloWorld/server.py6.2 处理JSON格式的请求数据 如果POST的数据是JSON格式request.json会自动将json数据转换成Python类型字典或者列表。 编写server.py: from flask import Flask, requestapp Flask(my-app)app.route(/) def hello_world():return Hello World!app.route(/add, methods[POST]) def add():print(request.headers)print(type(request.json))print(request.json)result request.json[a] request.json[b]return str(result)if name main:app.run(host127.0.0.1, port5000, debugTrue)编写client.py模拟浏览器请求 import requestsjson_data {a: 1, b: 2}r requests.post(http://127.0.0.1:5000/add, jsonjson_data)print(r.text)运行server.py然后运行client.pyclient.py 会在终端输出 3server.py 会在终端输出 Host: 127.0.0.1:5000 User-Agent: python-requests/2.19.1 Accept-Encoding: gzip, deflate Accept: / Connection: keep-alive Content-Length: 16 Content-Type: application/jsonclass dict {a: 1, b: 2}注意请求头中Content-Type的值是application/json。 6.3 响应JSON-方案1 响应JSON时除了要把响应体改成JSON格式响应头的Content-Type也要设置为application/json。 编写server2.py from flask import Flask, request, Response import jsonapp Flask(my-app)app.route(/) def hello_world():return Hello World!app.route(/add, methods[POST]) def add():result {sum: request.json[a] request.json[b]}return Response(json.dumps(result), mimetypeapplication/json)if name main:app.run(host127.0.0.1, port5000, debugTrue)修改后运行。 编写client2.py import requestsjson_data {a: 1, b: 2}r requests.post(http://127.0.0.1:5000/add, jsonjson_data)print(r.headers) print(r.text)运行client.py将显示 {Content-Type: application/json, Content-Length: 10, Server: Werkzeug/0.14.1 Python/3.6.4, Date: Sat, 07 Jul 2018 05:23:00 GMT} {sum: 3}上面第一段内容是服务器的响应头第二段内容是响应体也就是服务器返回的JSON格式数据。 另外如果需要服务器的HTTP响应头具有更好的可定制性比如自定义Server可以如下修改add()函数 app.route(/add, methods[POST]) def add():result {sum: request.json[a] request.json[b]}resp Response(json.dumps(result), mimetypeapplication/json)resp.headers.add(Server, python flask)return respclient2.py运行后会输出 {Content-Type: application/json, Content-Length: 10, Server: python flask, Date: Sat, 07 Jul 2018 05:26:40 GMT} {sum: 3}6.4 响应JSON-方案2 使用 jsonify 工具函数即可。 from flask import Flask, request, jsonifyapp Flask(my-app)app.route(/) def hello_world():return Hello World!app.route(/add, methods[POST]) def add():result {sum: request.json[a] request.json[b]}return jsonify(result)if name main:app.run(host127.0.0.1, port5000, debugTrue)7. 上传文件 上传文件一般也是用POST方法。 7.1 建立Flask项目 按照以下命令建立Flask项目HelloWorld: mkdir HelloWorld mkdir HelloWorld/static mkdir HelloWorld/templates touch HelloWorld/server.py7.2 上传文件 我们以上传图片为例 假设将上传的图片只允许’png’、’jpg’、’jpeg’、’gif’这四种格式通过url/upload使用POST上传上传的图片存放在服务器端的static/uploads目录下。 首先在项目HelloWorld中创建目录static/uploads mkdir HelloWorld/static/uploadswerkzeug库可以判断文件名是否安全例如防止文件名是../../../a.png安装这个库 $ pip install werkzeugserver.py代码 from flask import Flask, requestfrom werkzeug.utils import secure_filename import osapp Flask(name)# 文件上传目录 app.config[UPLOAD_FOLDER] static/uploads/

支持的文件格式

app.config[ALLOWED_EXTENSIONS] {png, jpg, jpeg, gif} # 集合类型# 判断文件名是否是我们支持的格式 def allowed_file(filename):return . in filename and \filename.rsplit(., 1)[1] in app.config[ALLOWED_EXTENSIONS]app.route(/) def hello_world():return hello worldapp.route(/upload, methods[POST]) def upload():upload_file request.files[image]if upload_file and allowed_file(upload_file.filename):filename secure_filename(upload_file.filename)# 将文件保存到 static/uploads 目录文件名同上传时使用的文件名upload_file.save(os.path.join(app.root_path, app.config[UPLOAD_FOLDER], filename))return info is request.form.get(info, ). successelse:return failedif name main:app.run(port5000, debugTrue)app.config中的config是字典的子类可以用来设置自有的配置信息也可以设置自己的配置信息。函数allowed_file(filename)用来判断filename是否有后缀以及后缀是否在app.config[ALLOWED_EXTENSIONS]中。 客户端上传的图片必须以image01标识。upload_file是上传文件对应的对象。app.root_path获取server.py所在目录在文件系统中的绝对路径。upload_file.save(path)用来将upload_file保存在服务器的文件系统中参数最好是绝对路径否则会报错网上很多代码都是使用相对路径但是笔者在使用相对路径时总是报错说找不到路径。函数os.path.join()用来将使用合适的路径分隔符将路径组合起来。 好了定制客户端client.py import requestsfile_data {image: open(Lenna.jpg, rb)}user_info {info: Lenna}r requests.post(http://127.0.0.1:5000/upload, datauser_info, filesfile_data)print(r.text)运行client.py当前目录下的Lenna.jpg将上传到服务器。 然后我们可以在static/uploads中看到文件Lenna.jpg。 要控制上产文件的大小可以设置请求实体的大小例如 app.config[MAX_CONTENT_LENGTH] 16 * 1024 * 1024 #16MB不过在处理上传文件时候需要使用try:…except:…。 如果要获取上传文件的内容可以 file_content request.files[image].stream.read()8. Restful URL 简单来说Restful URL可以看做是对 URL 参数的替代。 8.1 建立Flask项目 按照以下命令建立Flask项目HelloWorld: mkdir HelloWorld mkdir HelloWorld/static mkdir HelloWorld/templates touch HelloWorld/server.py8.2 编写代码 编辑server.py from flask import Flaskapp Flask(name)app.route(/) def hello_world():return hello worldapp.route(/user/username) def user(username):print(username)print(type(username))return hello usernameapp.route(/user/username/friends) def user_friends(username):print(username)print(type(username))return hello usernameif name main:app.run(port5000, debugTrue)运行HelloWorld/server.py。使用浏览器访问http://127.0.0.1:5000/user/adminHelloWorld/server.py将输出 admin class str而访问http://127.0.0.1:5000/user/admin/响应为404 Not Found。 浏览器访问http://127.0.0.1:5000/user/admin/friends可以看到 Hello admin.
HelloWorld/server.py输出 admin class str8.3 转换类型 由上面的示例可以看出使用 Restful URL 得到的变量默认为str对象。如果我们需要通过分页显示查询结果那么需要在url中有数字来指定页数。按照上面方法可以在获取str类型页数变量后将其转换为int类型。不过还有更方便的方法就是用flask内置的转换机制即在route中指定该如何转换。 新的服务器代码 from flask import Flaskapp Flask(name)app.route(/) def hello_world():return hello worldapp.route(/page/int:num) def page(num):print(num)print(type(num))return hello worldif name main:app.run(port5000, debugTrue)app.route(‘/page/int:num‘)会将num变量自动转换成int类型。 运行上面的程序在浏览器中访问http://127.0.0.1:5000/page/1HelloWorld/server.py将输出如下内容 1 class int如果访问的是http://127.0.0.1:5000/page/asd我们会得到404响应。 在官方资料中说是有3个默认的转换器 int accepts integers float like int but for floating point values path like the default but also accepts slashes8.4 一个有趣的用法 如下编写服务器代码 from flask import Flaskapp Flask(name)app.route(/) def hello_world():return hello worldapp.route(/page/int:num1-int:num2) def page(num1, num2):print(num1)print(num2)return hello worldif name main:app.run(port5000, debugTrue)在浏览器中访问http://127.0.0.1:5000/page/11-22HelloWorld/server.py会输出 11 228.5 编写转换器 自定义的转换器是一个继承werkzeug.routing.BaseConverter的类修改to_python和to_url方法即可。to_python方法用于将url中的变量转换后供被app.route包装的函数使用to_url方法用于flask.url_for中的参数转换。 下面是一个示例将HelloWorld/server.py修改如下 from flask import Flask, url_forfrom werkzeug.routing import BaseConverterclass MyIntConverter(BaseConverter):def init(self, url_map):super(MyIntConverter, self).init(url_map)def to_python(self, value):return int(value)def to_url(self, value):return value * 2app Flask(name) app.url_map.converters[my_int] MyIntConverterapp.route(/) def hello_world():return hello worldapp.route(/page/my_int:num) def page(num):print(num)print(url_for(page, numstr(123))) # page 对应的是 page函数 num 对应对应/page/my_int:num中的num必须是strreturn hello worldif name main:app.run(port5000, debugTrue) 浏览器访问http://127.0.0.1:5000/page/123后HelloWorld/server.py的输出信息是 123 /page/1231238.7 值得读 理解RESTful架构。 9. 使用url_for生成链接 工具函数url_for可以让你以软编码的形式生成url提供开发效率。 9.1 建立Flask项目 按照以下命令建立Flask项目HelloWorld: mkdir HelloWorld mkdir HelloWorld/static mkdir HelloWorld/templates touch HelloWorld/server.py9.2 编写代码 编辑HelloWorld/server.py from flask import Flask, url_forapp Flask(name)app.route(/) def hello_world():passapp.route(/user/name) def user(name):passapp.route(/page/int:num) def page(num):passapp.route(/test) def test():print(url_for(hello_world))print(url_for(user, nameadmin))print(url_for(page, num1, qhadoop mapreduce 10%3))print(url_for(static, filenameuploads/01.jpg))return Helloif name main:app.run(debugTrue)运行HelloWorld/server.py。然后在浏览器中访问http://127.0.0.1:5000/testHelloWorld/server.py将输出以下信息 / /user/admin /page/1?qhadoopmapreduce10%253 /static/uploads/01.jpg10. 使用redirect重定向网址 redirect函数用于重定向实现机制很简单就是向客户端浏览器发送一个重定向的HTTP报文浏览器会去访问报文中指定的url。 10.1 建立Flask项目 按照以下命令建立Flask项目HelloWorld: mkdir HelloWorld mkdir HelloWorld/static mkdir HelloWorld/templates touch HelloWorld/server.py10.2 编写代码 使用redirect时给它一个字符串类型的参数就行了。 编辑HelloWorld/server.py from flask import Flask, url_for, redirectapp Flask(name)app.route(/) def hello_world():return hello worldapp.route(/test1) def test1():print(this is test1)return redirect(url_for(test2))app.route(/test2) def test2():print(this is test2)return this is test2if name main:app.run(debugTrue)运行HelloWorld/server.py在浏览器中访问http://127.0.0.1:5000/test1浏览器的url会变成http://127.0.0.1:5000/test2并显示 this is test211. 使用Jinja2模板引擎 模板引擎负责MVC中的Vview视图这一部分。Flask默认使用Jinja2模板引擎。 Flask与模板相关的函数有 flask.render_template(template_name_or_list, **context) Renders a template from the template folder with the given context.flask.render_template_string(source, **context) Renders a template from the given template source string with the given context.flask.get_template_attribute(template_name, attribute) Loads a macro (or variable) a template exports. This can be used to invoke a macro from within Python code. 这其中常用的就是前两个函数。 这个实例中使用了模板继承、if判断、for循环。 11.1 建立Flask项目 按照以下命令建立Flask项目HelloWorld: mkdir HelloWorld mkdir HelloWorld/static mkdir HelloWorld/templates touch HelloWorld/server.py11.2 创建并编辑HelloWorld/templates/default.html 内容如下 html headtitle{% if page_title %}{{ page_title }}{% endif %}/title /headbody{% block body %}{% endblock %}可以看到在标签中使用了if判断如果给模板传递了page_title变量显示之否则不显示。标签中定义了一个名为body的block用来被其他模板文件继承。### 11.3 创建并编辑HelloWorld/templates/user_info.html 内容如下 {% extends default.html %}{% block body %}{% for key in user_info %}{{ key }}: {{ user_info[key] }} {% endfor %} {% endblock %}变量user_info应该是一个字典for循环用来循环输出键值对。 11.4 编辑HelloWorld/server.py 内容如下 from flask import Flask, render_templateapp Flask(name)app.route(/) def hello_world():return hello worldapp.route(/user) def user():user_info {name: admin,email: 123aa.com,age:0,github: https://github.com/admin}return render_template(user_info.html, page_titleadmin\s info, user_infouser_info)if name main:app.run(port5000, debugTrue)render_template()函数的第一个参数指定模板文件后面的参数是要传递的数据。 11.5 运行与测试 运行HelloWorld/server.py \( python3 HelloWorld/server.py在浏览器中访问http://127.0.0.1:5000/user效果图如下 查看网页源码 html headtitleletian#39;s info/title /head bodyname: letian br/email: 123aa.com br/age: 0 br/github: https://github.com/letiantian br/ /body /html12. 自定义404等错误的响应 要处理HTTP错误可以使用flask.abort函数。 12.1 示例1简单入门 建立Flask项目 按照以下命令建立Flask项目HelloWorld: mkdir HelloWorld mkdir HelloWorld/static mkdir HelloWorld/templates touch HelloWorld/server.py代码 编辑HelloWorld/server.py from flask import Flask, render_template_string, abortapp Flask(__name__)app.route(/) def hello_world():return hello worldapp.route(/user) def user():abort(401) # Unauthorized 未授权print(Unauthorized, 请先登录)if __name__ __main__:app.run(port5000, debugTrue)效果 运行HelloWorld/server.py浏览器访问http://127.0.0.1:5000/user效果如下 要注意的是HelloWorld/server.py中abort(401)后的print并没有执行。 12.2 示例2自定义错误页面 代码 将服务器代码改为 from flask import Flask, render_template_string, abortapp Flask(__name__)app.route(/) def hello_world():return hello worldapp.route(/user) def user():abort(401) # Unauthorizedapp.errorhandler(401) def page_unauthorized(error):return render_template_string(h1 Unauthorized /h1h2{{ error_info }}/h2, error_infoerror), 401if __name__ __main__:app.run(port5000, debugTrue)page_unauthorized函数返回的是一个元组401 代表HTTP 响应状态码。如果省略401则响应状态码会变成默认的 200。 效果 运行HelloWorld/server.py浏览器访问http://127.0.0.1:5000/user效果如下 13. 用户会话 session用来记录用户的登录状态一般基于cookie实现。 下面是一个简单的示例。 13.1 建立Flask项目 按照以下命令建立Flask项目HelloWorld: mkdir HelloWorld mkdir HelloWorld/static mkdir HelloWorld/templates touch HelloWorld/server.py13.2 编辑HelloWorld/server.py 内容如下 from flask import Flask, render_template_string, \session, request, redirect, url_forapp Flask(__name__)app.secret_key F12Zr47j\3yX R~XH!jLwf/Tapp.route(/) def hello_world():return hello worldapp.route(/login) def login():page form action{{ url_for(do_login) }} methodpostpname: input typetext nameuser_name //pinput typesubmit valueSubmit //formreturn render_template_string(page)app.route(/do_login, methods[POST]) def do_login():name request.form.get(user_name)session[user_name] namereturn successapp.route(/show) def show():return session[user_name]app.route(/logout) def logout():session.pop(user_name, None)return redirect(url_for(login))if __name__ __main__:app.run(port5000, debugTrue)13.3 代码的含义 app.secret_key用于给session加密。 在/login中将向用户展示一个表单要求输入一个名字submit后将数据以post的方式传递给/do_login/do_login将名字存放在session中。 如果用户成功登录访问/show时会显示用户的名字。此时打开firebug等调试工具选择session面板会看到有一个cookie的名称为session。 /logout用于登出通过将session中的user_name字段pop即可。Flask中的session基于字典类型实现调用pop方法时会返回pop的键对应的值如果要pop的键并不存在那么返回值是pop()的第二个参数。 另外使用redirect()重定向时一定要在前面加上return。 13.4 效果 进入http://127.0.0.1:5000/login输入name点击submit 进入http://127.0.0.1:5000/show查看session中存储的name   13.5 设置sessin的有效时间 下面这段代码来自Is there an easy way to make sessions timeout in flask? from datetime import timedelta from flask import session, appsession.permanent True app.permanent_session_lifetime timedelta(minutes5)这段代码将session的有效时间设置为5分钟。 14. 使用Cookie Cookie是存储在客户端的记录访问者状态的数据。具体原理请见 http://zh.wikipedia.org/wiki/Cookie 。 常用的用于记录用户登录状态的session大多是基于cookie实现的。 cookie可以借助flask.Response来实现。下面是一个示例。 14.1 建立Flask项目 按照以下命令建立Flask项目HelloWorld: mkdir HelloWorld mkdir HelloWorld/static mkdir HelloWorld/templates touch HelloWorld/server.py14.2 代码 修改HelloWorld/server.py from flask import Flask, request, Response, make_response import timeapp Flask(__name__)app.route(/) def hello_world():return hello worldapp.route(/add) def login():res Response(add cookies)res.set_cookie(keyname, valueadmin, expirestime.time()6*60)return resapp.route(/show) def show():return request.cookies.__str__()app.route(/del) def del_cookie():res Response(delete cookies)res.set_cookie(name, , expires0)return resif __name__ __main__:app.run(port5000, debugTrue)由上可以看到可以使用Response.set_cookie添加和删除cookie。expires参数用来设置cookie有效时间它的值可以是datetime对象或者unix时间戳笔者使用的是unix时间戳。 res.set_cookie(keyname, valueadmin, expirestime.time()6*60)上面的expire参数的值表示cookie在从现在开始的6分钟内都是有效的。 要删除cookie将expire参数的值设为0即可 res.set_cookie(name, , expires0)set_cookie()函数的原型如下 set_cookie(key, value’’, max_ageNone, expiresNone, path’/‘, domainNone, secureNone, httponlyFalse) Sets a cookie. The parameters are the same as in the cookie Morsel object in the  Python standard library but it accepts unicode data, too. Parameters: key – the key (name) of the cookie to be set.      value – the value of the cookie.      max_age – should be a number of seconds, or None (default) if the cookie should last only as long as the client’s browser session. expires – should be a datetime object or UNIX timestamp. domain – if you want to set a cross-domain cookie. For example, domain”.example.com” will set a cookie that is readable by the domain  www.example.com, foo.example.com etc. Otherwise, a cookie will only be readable by the domain that set it. path – limits the cookie to a given path, per default it will span the whole domain. 14.3 运行与测试 运行HelloWorld/server.py \) python3 HelloWorld/server.py使用浏览器打开http://127.0.0.1:5000/add浏览器界面会显示 add cookies下面查看一下cookie如果使用firefox浏览器可以用firebug插件查看。打开firebug选择Cookies选项刷新页面可以看到名为name的cookie其值为admin。 在“网络”选项中可以查看响应头中类似下面内容的设置cookie的HTTP「指令」 Set-Cookie: nameadmin; ExpiresTue, 13 Feb 2024 08:48:03 GMT; Path/在cookie有效期间使用浏览器访问http://127.0.0.1:5000/show可以看到 {name: letian}15. 闪存系统 flashing system Flask的闪存系统flashing system用于向用户提供反馈信息这些反馈信息一般是对用户上一次操作的反馈。反馈信息是存储在服务器端的当服务器向客户端返回反馈信息后这些反馈信息会被服务器端删除。 下面是一个示例。 15.1 建立Flask项目 按照以下命令建立Flask项目HelloWorld: mkdir HelloWorld mkdir HelloWorld/static mkdir HelloWorld/templates touch HelloWorld/server.py15.2 编写HelloWorld/server.py 内容如下 from flask import Flask, flash, get_flashed_messages import timeapp Flask(name) app.secret_key some_secretapp.route(/) def index():return hiapp.route(/gen) def gen():info access at time.time().str()flash(info)return infoapp.route(/show1) def show1():return get_flashed_messages().str()app.route(/show2) def show2():return get_flashed_messages().str()if name main:app.run(port5000, debugTrue)15.3 效果 运行服务器 $ python3 HelloWorld/server.py打开浏览器访问http://127.0.0.1:5000/gen浏览器界面显示注意时间戳是动态生成的每次都会不一样除非并行访问 access at 1707813833.4530551查看浏览器的cookie可以看到session其对应的内容是 .eyJfZmxhc2hlcyI6W3siIHQiOlsibWVzc2FnZSIsImFjY2VzcyBhdCAxNzA3ODEzODMzLjQ1MzA1NTEiXX1dfQ.ZcsryQ.0GhWgm18aTL1_8C6wd2p-qdPq74再一次访问http://127.0.0.1:5000/gen浏览器界面显示 access at 1707813887.7479208cookie中session发生了变化新的内容是 ..eJyrVopPy0kszkgtVrKKrlZSKAFSSrmpxcWJ6alKOkqJyclAtkJiiYKhuYG5haGxhbGxnompsYGpqaFSbK0OMToszPXMTcwtjQwsgDpiawGmVCC3.Zcsr_w.qJk-PEYwOflqDoXEh6ScwUG9c3Q然后使用浏览器访问http://127.0.0.1:5000/show1浏览器界面显示 [access at 1707813833.4530551, access at 1707813887.7479208]这个列表中的内容也就是上面的两次访问http://127.0.0.1:5000/gen得到的内容。此时cookie中已经没有session了。 如果使用浏览器访问http://127.0.0.1:5000/show1或者http://127.0.0.1:5000/show2只会得到 []15.4 高级用法 flash系统也支持对flash的内容进行分类。修改HelloWorld/server.py内容 from flask import Flask, flash, get_flashed_messages import timeapp Flask(name) app.secret_key some_secretapp.route(/) def index():return hiapp.route(/gen) def gen():info access at time.time().str()flash(show1 info, categoryshow1)flash(show2 info, categoryshow2)return infoapp.route(/show1) def show1():return get_flashed_messages(category_filtershow1).str()app.route(/show2) def show2():return get_flashed_messages(category_filtershow2).str()if name main:app.run(port5000, debugTrue)某一时刻浏览器访问http://127.0.0.1:5000/gen浏览器界面显示 access at 1707814052.5459604不过由上面的代码可以知道此时生成了两个flash信息但分类(category)不同。 使用浏览器访问http://127.0.0.1:5000/show1得到如下内容 [show1 access at 1707814052.5459604]而继续访问http://127.0.0.1:5000/show2得到的内容为空 []15.5 在模板文件中获取flash的内容 在Flask中get_flashed_messages()默认已经集成到Jinja2模板引擎中易用性很强。 参考文献Python Flask Web 框架入门