0%

CS50_Flask

CS50 Flask

Flask是一个python的后端微型框架,用来方便快捷的生成前端界面。而目前我需要学习FaskAPI,由于和Flask类似,所以我打算先来回顾一遍这一课。

最基础的一集

1
2
3
4
5
6
7
8
from flask import Flask

app = Flask(__name__)


@app.route("/")
def index():
return "Hello, world!"

下面是对这段代码的逐行精讲:

from flask import Flask

从flask依赖包中导入了某些功能,你可以先把当当作某种惯例。

app = Flask(__name__)

__name__相当于一个特殊变量,指向当前文件本身,而这行代码的意思是告诉Flask,请把我当前的文件转换为web应用程序吧,并用app变量接收。

@app.route("/")

这是python中一个叫做装饰器的特性,指定了当前应用的根目录。作用是在用户访问了当前路由时,自动调用底下的函数并将返回返回到web页面。

现在运行 flask run, f12就会发现源码界面只有纯文本。如何显示一个html格式的页面呢?或许我们只要改变返回值就可以了。

1
2
3
4
5
6
7
8
9
from flask import Flask

app = Flask(__name__)


@app.route("/")
def index():
return '<!DOCTYPE html><html lang="en"><head><title>hello, title</title></head><body>hello,body</body></html>' # 为了和内部的双引号区分,外部用了单引号

现在我想把html文件和代码文件分离,在app.py同一个文件夹下新建/templates文件夹,并放在index.html文件中即可。flask会自己在同目录下的templates文件夹下识别找到要用的模板文件。

1
2
3
4
5
6
7
8
9
10
11
<!DOCTYPE  html>
<html lang="en">
<head>
<title>
Hello, title
</title>
</head>
<body>
Hello,{{ name }}!
</body>
</html>

将需要的动态变量用双花括号括起来,这是一种flask特有的语法。

现在我们需要直接返回html文件,要怎么办呢?flask库中有一个render_template(渲染模板)函数可以帮我们做到这一点。

return render_template("index.html")

如果需要添加指定的name并让他替换到html的变量位置中,第一步要接受参数:flask中的request可以做到。

name = request.args["name"]

request.args的结果可以看作一个python字典,如果传入name参数,便会接收到并存在name变量中。

第二步便是替换,只需要在render_template("index.html")括号后面添加 name=name,左边name表示html文件中的变量名,右边表示用户输入的参数。实现如下

1
2
3
4
5
6
7
8
9
10
from flask import Flask, render_template, request

app = Flask(__name__)


@app.route("/")
def index():
name = request.args["name"]
return render_template("index.html", name=name)

这样已经很好了,但是如果你现在直接访问5000端口不带任何参数你就会发现400错误,这是因为我们默认了一定有name参数传入,而没有处理没有参数时候的逻辑。或许可以用逻辑语句解决,但flask有一种更便捷的方式。

1
2
3
4
5
6
7
8
9
10
11
from flask import Flask, render_template, request

app = Flask(__name__)


@app.route("/")
def index():

name = request.args.get("name", "world") # 直接用get方法进行获取,然后跟上默认参数
return render_template("index.html", name=name)

现在默认访问根目录也能看到回显页面。

image-20250502031119239

现在我们已经实现了动态显示参数了,

POST提交

现在我想写一个表单来提交参数,而不是直接去手写URL(毕竟一般用户都不会这样)。于是新建一个index.html,把原来的文件改名为greet.html。

index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!DOCTYPE  html>
<html lang="en">
<head>
<meta name="viewport" content="initial-scale=1, ,width=device-width">
<title>
Hello
</title>
</head>
<body>
<form action="/greet" method="get">
<input autocomplete="off" autofocus name="name" placeholder="your_name" type="text">
<button type="submit">提交</button>
</form>
</body>
</html>

而为了数据的安全性,我们可能会用post方式来提交数据,怎样修改呢?

  1. 把index.html中from标签中的method进行更改。
  2. 把app.py中name = request.args.get("name", "world")改为name = request.form.get("name", "world")

html模板 block

现在看看我们的index.html,greet.html,有没有感觉很相似?或许我们可以和总结函数一样,为这些页面相同的部分总结一个函数。

新建一个layout.html:

把其中相同的部分写上去,并用{% block body %} {% endblock %}替换掉不同的部分(body是一个可自定义的块名称):

1
2
3
4
5
6
7
8
9
10
11
12
<!DOCTYPE  html>
<html lang="en">
<head>
<meta name="viewport" content="initial-scale=1, ,width=device-width">
<title>
Hello
</title>
</head>
<body>
{% block body %} {% endblock %}
</body>
</html>

然后再另外两个文件中删去重复部分仅保留不同,以index.html为例,格式如下:

1
2
3
4
5
6
7
8
{% extends "layout.html" %}

{% block body %}
<form action="/greet" method="post">
<input autocomplete="off" autofocus name="name" placeholder="your_name" type="text">
<button type="submit">提交</button>
</form>
{% endblock %}

将另一个也修改之后回到app.py,发现并没有需要改的东西,因为render_template函数会把自动识别其中的语法并生成内容。

使用一个路由实现

现在我们需要两个路由来实现 这个功能,其实用一个也行。

app.py:

1
2
3
4
5
6
7
8
9
10
11
12
13
from flask import Flask, render_template, request

app = Flask(__name__)


@app.route("/", methods=["GET", "POST"])
def index():
if request.method == "POST":
name = request.form.get("name", "world")
return render_template("greet.html", name=name)
return render_template("index.html")


别忘了把表单提交路径也改了,这样就完成了。

if语句

如果我不想设置默认值,那么也可以这样实现:

1
2
3
4
5
6
7
8
9
10
{% extends "layout.html" %}

{% block body %}
Hello,
{% if name %}
{{ name }}!
{% else %}
world!
{% endif %}
{% endblock %}

提交空表单时显示默认值。

requirments.txt文件

通常在app.py同级目录下,用来列出需要安装的依赖名,使用方法:pip install -r requirments.txt