文章目录
Flask 依赖两个外部库:WerkZeug 和 Jinja2。WerkZeug 是一个WSGI(在web应用和多种服务器之间的标准Python 接口)工具集。Jinja2负责渲染模板。所以在安装Flask之前,需要安装这两个外部库,而最简单的方法就是使用 Virtualenv 创建虚拟环境
pip install virtualenv
检验
virtualenv --version
下一步就是使用Virtualenv 命令在当前文件夹创建Python虚拟环境。创建虚拟环境之后当前文件夹会出现一个子文件夹,名字就是下述命令中指定的参数
virtualenv venv


venv\Scripts\activate
pip install flask
安装校验
pip list --format columns

from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run(debug=True)

(1)首先我们导入了Flask类。这个类的实例将会是我们的WSGI应用程序
(2)接下来,我们创建了一个该类的实例,第一个参数是应用模块或者包名的名称。如果你还用单一的模块,比如本例,你应该使用__name__,因为模块的名称将会因其作为一个单独的应用模块启动还是作为模块导入而有不同(也是__main_或者实际的导入名)。这是必须得,这样Flask才知道到哪儿去模板,静态文件等。详情见Flask的文档。
(3)然后,我们使用route()装饰器告诉Flask什么样的URL能触发我们的函数
(4)这个函数的名字也在生成URL时被特定的函数采用,这个函数返回我们想要显示在用户浏览器中的信息
(5)最后我们使用run()函数来让应用运行在本地的服务器上面。其中if__name __=='__main__':确保服务器只会在该脚本被Python解释器直接执行的时候才会运行,而不是作为模板导入的时候
虽然run()方法使用与启动本地的开发服务,但是用户没每次修改代码后需要手动的重启服务,这样并不优雅,而Flask可以做到更好。如果你启用了调试支持,服务器会在代码修改后自动重新载入,并且在发生错误的时候提供一个相当可用的调试器 相当于Java的热部署
使用方法,直接在代码中添加
app.run(debug=True)
或者
app.debug=True
app.run()
处理URL和函数之间的关系的程序称之为路由
@app.route('/')
def hello_world():
return '<h1>Hello World!</h1>'

修饰器是Python语言的标准特性,可以使用不同的方法修改函数的行为。惯常用法是使用修饰器把函数注册为事件的处理程序
要给URL添加变量部分,你可以把这些特殊的字段编辑为<variable_name>,这个部分将会作为命名参数传递到你的函数。规格可以使用converter:variable_name指定一个可选的转化器
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
@app.route('/user/<username>')
def show_user_profile(username):
# 显示该用户名的用户信息
return 'User %s' % username
@app.route('/post/<int:post_id>')
def show_post(post_id):
# 根据ID显示文章,ID是整型数据
return 'Post %d' % post_id
if __name__ == '__main__':
app.run(debug=True)



Flask能够匹配URL,而且还可以用url_for()来给指定的函数构造URL。它接收函数名作为第一个参数,也接受对应URL规则的变量部分的命名参数。未知变量部分会添加到URL末尾作为查询条件
from flask import Flask , url_for
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello World!'
@app.route('/user/<username>')
def show_user_profile(username):
# 显示该用户名的用户信息
return 'User %s' % username
@app.route('/post/<int:post_id>')
def show_post(post_id):
# 根据ID显示文章,ID是整型数据
return 'Post %d' % post_id
@app.route('/url/')
def get_url():
# 根据ID显示文章,ID是整型数据
return url_for('show_post',post_id=2)
if __name__ == '__main__':
app.run(debug=True)

HTTP(与web应用会话的协议)有许多的不同的构造方法访问URL方法。默认情况下,路由只回应GET请求,当时通过route()装饰器传递methods 参数可以改变这个行为。
@app.route('/', methods=['GET', 'POST'])
def index():
if request.methods=='POST':
pass
else:
pass

url_for('static',filename='style.css'),
# 这个文件应该存储在文件系统上的static/style.css
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def hello_world():
return render_template('index.html')
@app.route('/user/<username>')
def show_user_profile(username):
# 显示该用户名的用户信息
return render_template('user.html', name=username)
if __name__ == '__main__':
app.run(debug=True)


模板是一个包含响应文本的额文件,其中包含用占位变量表示的动态部分,其具体值只在请求的上下文中才能知道。使用真实值替代变量,再返回最终得到的响应字符串,这一过程称为渲染。为了渲染模板,Flask使用了一个名为Jinja2的强大模板引擎
默认情况下,Flask在程序文件夹中的templates 子文件夹中寻找模板。
比如:



我们可以在模板中使用变量{{name}},这表示一个占位符,而name是变量名称;
模板学习
<p>从一个字典中获取一个值:{{mydict['key']}}.</p>
<p>从一个列表中获取一个值:{{mylist[3]}}.</p>
<p>从一个列表中获取一个带索引的值:{{mylist[myintvar]}}.</p>
<p>从一个对象的方法中获取一个值:{{myobj.somemethod()}}.</p>
可以使用过滤器修改变量,过滤器添加变量名之后,中间使用竖线分隔。
Hello,{{name|capitalize}}
Jinja2提供了许多内置过滤器,常用的过滤器如下:


if…else…endif
{% if user %}
Hello,{{user}}
{% else %}
Hello Stranger
{% endif %}
{% for comment in comments %}
{{comment}}
{% endfor %}
宏类似于Python代码中的函数
{% macro render_comment(comment) %}
{{comment}}
{% endmacro %}
{% for comment in comments %}
{{render_comment(comment)}}
{% endfor %}
需要在多处重复使用的模板代码片段可以写在独立的文件,在包含在所有的模板中,以免重复
方法一:全部包含
{% include 'common.html' %}
方法二:继承包含
base.html
<html>
<head>
{%block head%}
<title>{%block title%}{%endblock%}-My Application</title>
<%endblock%>
</head>
<title>
<body>
{%bolck body%}
{%endbody%}
</body>
</html>
bolck标签定义的元素可在衍生模板中修改。在本例中,我们定义了名为head、title、body的块。注意。title包含在head中。
举例衍生模板
{% extends "base.html"}
{%block title%}Index{%endhead%}
{%block head%}
{{supper()}}
<style>
</style>
{% endblock %}
{%bolck body%}
<h1>Hello</h1>
{%endbody%}
extends 指令声明这个模板衍生于base,html,在extends指令之后,基模板的三个块被重新定义,模板引擎将会在其插入适当的位置,注意新定义的head块,在基模板中其内容不是空的,所以用supper()获取原来的内容
pip install flask-wtf
安装成功显示如下:

CSRF跨站请求伪造,源于WEB的隐式身份验证机制。WEB的身份验证机制虽然可以抱着一个请求时来自于某个用户的浏览器,但却无法保证该请求是用户批准发送的。
例如,用户登录受信任的网址A,在本地生成了Cookie,在Cookie没有失效的情况下去访问了危险网站B。B可能会盗用你的身份,以你的名义去发送恶意请求,邮件,盗取你的账号,设置购买商品,造成你个人隐私泄露,已经财产安全。
实际上,WTForms在渲染没一个表单都会生成一个独一无二的token,这个token将在POST请求的时候随着表单一起提交进行验证。默认情况下Flask-WTF能保护所有表单免受跨域请求伪造的攻击,恶意网站把请求发送到被攻击者已经登陆的网站就会引发CSRF攻击。为了实现CSRF保护,Flask-WTF需要程序设置加密令牌,再用加密令牌来验证表单数据的真伪。
使用方法
app = Flask(__name__)
app.config['SECRET_KEY'] = 'abcd123'
使用Flask-WTF时,每个表单都由一个继承自Form的类表示,这个类定义表单中的一组字段。
每个字段有用对象表示,并且字段可以附属一个或者多个校验用来验证用户输入的数据是否符合要求。
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import Required
class NameForm():
name = StringField('请输入姓名', validators=[Required()])
password = PasswordField('请输入密码', validators=[Required()])
submit = SubmitField('Submit')
这个表单中所有字段都定义为类变量,类变量的值是相应字段类型的对象

在上述代码中我们使用了三个HTML标准字段,更多参考如下:


表单字段是可调用的,在模板中渲染会生成HTML。
假设视图函数把一个NameForm实力通过参数传进form表单,在模板中可以生成一个简单的表单验证用户登录信息。
创建一个model.py文件定义一个表单类LoginForm,其中有三个属性分别是name,password和submit,具体代码如下:
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField,SubmitField
from wtforms.validators import DataRequired,Length
class LoginForm(FlaskForm):
"""
登录表单类
"""
name = StringField(label='用户名', validators=[
DataRequired("用户名不能为空"),
Length(max=10,min=3,message="用户名长度必须大于3且小于8")
])
password = PasswordField(label='密码', validators=[
DataRequired("密码不能为空"),
Length(max=10, min=6, message="用户名长度必须大于6且小于10")
])
submit = SubmitField(label="提交")
在文件中分别创建首页视图index()函数和登录页视图login()函数。引入我们刚才创建的model.py文件并在login()视图函数中对用户登陆进行验证,验证通过则跳转至首页,否则提示错误
from flask import Flask ,url_for,redirect, render_template
from models import LoginForm
app = Flask(__name__)
app.config['SECRET_KEY'] = 'mrsoft'
@app.route('/login', methods=['GET', 'POST'])
def login():
"""
登录页面
"""
form = LoginForm()
if form.validate_on_submit():
username = form.name.data
password = form.password.data
if username== "admin" and password == "abcd1234":
return redirect(url_for('index'))
return render_template('login.html',form=form)
@app.route('/')
def index():
"""
首页
"""
name = "班德尔城"
message = """
约德尔人的故乡究竟在何处?对于这个问题人们众说纷纭,不过有一些凡人声称自己穿过了无形的传送门,进入了超越物质领域的奇异魔法世界。他们都描述了一个魔法奔放的地方,鲁莽蛮横的人会被无数的奇观带入歧途,最后迷失在梦境中,永远无法返回……
在班德尔城,任何约德尔人以外的种族都会感到自己的全部感官得到了强化。城中所见无不色彩斑斓,食物与水的味道让人经年沉醉——只要尝过一次,就终身难忘。这里日光溶溶,春水不休,每一株植物都会结出累累硕果。或许这些描述中有一部分属实,或许全都是假的——因为没有任何两个讲述者能够对所见所闻达成一致。
只有一件事可以肯定,那就是班德尔城和里面的居民都具有某种超脱时间的属性,这或许可以解释为什么从那里回来的凡人全都像是一夜苍老了许多年岁,更多人则根本是一去不复返。
"""
return render_template("index.html",name=name,message=message)
if __name__ == '__main__':
app.run(debug=True,
port=8000)
渲染login.html和index.html如下:
<div class="jumbotron">
<form action="" method="post">
<div class="form-group">
{{ form.name.label }}
{{ form.name(class="form-control")}}
{% for err in form.name.errors %}
<p style="color: red">{{ err }}</p>
{% endfor %}
</div>
<div class="form-group">
{{ form.password.label }}
{{ form.password(class="form-control") }}
{% for err in form.password.errors %}
<p style="color: red">{{ err }}</p>
{% endfor %}
</div>
{{ form.csrf_token }}
{{ form.submit(class="btn btn-primary") }}
</form>
</div>
<div class="jumbotron">
<h1 class="display-3">欢迎来到{{name}}</h1>
<p >
{{message}}
</p>
<hr class="my-4">
<p>
<a class="btn btn-primary btn-lg" href="#" role="button">了解更多</a>
</p>
</div>
当我们运行run.py函数,浏览器输入
http://127.0.0.1:5000/login

如果用户没有填入值就直接提交,DataRequired就会捕获这个异常

如果用户密码长度不满足要求,length()函数就会捕获这个异常

密码输入无误,则会成功跳转至首页

关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o
我想解析一个已经存在的.mid文件,改变它的乐器,例如从“acousticgrandpiano”到“violin”,然后将它保存回去或作为另一个.mid文件。根据我在文档中看到的内容,该乐器通过program_change或patch_change指令进行了更改,但我找不到任何在已经存在的MIDI文件中执行此操作的库.他们似乎都只支持从头开始创建的MIDI文件。 最佳答案 MIDIpackage会为您完成此操作,但具体方法取决于midi文件的原始内容。一个MIDI文件由一个或多个音轨组成,每个音轨是十六个channel中任何一个上的
本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
2022/8/4更新支持加入水印水印必须包含透明图像,并且水印图像大小要等于原图像的大小pythonconvert_image_to_video.py-f30-mwatermark.pngim_dirout.mkv2022/6/21更新让命令行参数更加易用新的命令行使用方法pythonconvert_image_to_video.py-f30im_dirout.mkvFFMPEG命令行转换一组JPG图像到视频时,是将这组图像视为MJPG流。我需要转换一组PNG图像到视频,FFMPEG就不认了。pyav内置了ffmpeg库,不需要系统带有ffmpeg工具因此我使用ffmpeg的python包装p