当前位置: 首页>后端>正文

我用Flask写网站《01 Hello Flask》

通过本文,你应该掌握:

  1. Hello World程序搭建
  2. 视图函数编写
  3. HTML页面渲染
  4. 前后端参数传递
  5. Jinja模板基础

原文链接

欢迎来我的论坛讨论Flask搭建博客网站的问题和经验。www.ahoh.club。
本系列所有文章都会同步到这里,如果不想关注博主,就来这里阅读吧!

使用Flask写一个博客系统

写在前面

我是一个毕业于计算机专业,却很遗憾没有进入互联网行业的人。直到我永远的离开了那个千万人唾弃的血汗工厂,才发现原来我一直深爱着这个行业。在工作的这段时间里,我每天都能感受到技能的流失、学业的荒废。

现在只希望能留下点代码,记录曾经七年的光阴,时间能带走我的技能,却不能停掉我的服务器!!

我也是在C、C++、Java各种技能都丢失后,才捡起了Python,在学习过程中,我发现很多教程都非常老旧,也有很精彩的教程断更,既然别人靠不住,那我就自己来!!

我会深耕这个系列,争取把它打造成一个精品教程!

1. 你好,Flask

在编程学习过程中,万物始于Hello World,我也不例外,在使用Flask开发Web应用之前,我想先创建一个Hello World应用。

首先,给项目起一个有意思的名字,作为一个美好的开始。我现在想命名我的项目为:Ahoh,也就是啊哦~,因为我遇到BUG都会啊哦一下。好吧,先创建项目文件夹并进入目录:

~$ mkdir ahoh # 创建项目文件夹(根目录)
~$ cd ahoh

另外,Python应用开发往往都是运行在虚拟环境中的,所以我还要Ahoh运行在虚拟环境中。创建虚拟环境,并激活:

~/ahoh$ python3 -m venv venv # 创建一个名字叫venv的虚拟环境目录
~/ahoh$ . venv/bin/activate  # 激活虚拟环境
(venv)~/ahoh$                # 激活成功后,可以看到命令行之前出现了venv字样

既然是写Flask应用,那安装Flask包肯定是必不可少的:

(venv)~/ahoh$ pip install -U pip  # 更新pip
(venv)~/ahoh$ pip install flask   # 安装Flask

OK,现在环境就布置好了,可以开始愉快的敲代码了。

首先,我需要一个Flask的入口文件,按照官方文档的建议,就起名app.py

(venv)~/ahoh$ touch app.py 

最简单的Flask项目,就只需要一个文件,我的Hello World也是这样。

app.py 文件中写入以下代码:

# ~/ahoh/app.py
from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return '你好, Flask'

你可以选择使用Vim,也可以选择VSCodePyCharm等集成开发工具。

到这里为止,整个Hello World项目就写完了,真是太容易了。

下面就要跑起来我的Hello World项目,只需要在命令行中输入flask run

(venv)~/ahoh$ flask run    # 启动Flask应用
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

如果输出和上面一样,很有可能就是成功了,这个时候,只需要在浏览器中输入127.0.0.1:5000就能访问网站了!

你的结果和我一样吗?为了写这个小项目,我还专门搭建了项目论坛:www.ahoh.club ,欢迎来访!(这不是广告,里面只有我一个人,哈哈哈)

我用Flask写网站《01 Hello Flask》,第1张
HelloFlask执行结果

2. 你好,HTML

上小节中,我已经成功让Hello World项目输出了你好,Flask,但这绝不是我最终的要求。

我想要的必然是花里胡哨的网页,也就是HTML页面。

既然需要HTML,那就直接写个HTML代码,并通过/html访问新的HTML页面,在app.py中追加代码如下:

# ~/ahoh/app.py
@app.route('/html')
def html():
    html_str = """
    <html>
    <head>
        <title>HTML页面</title>
    </head>
    <body>
        <h1>我的第一个HTML页面</h1>
        <hr>
        <p> Oh,我的老天爷啊,这真是一个了不得的项目,我向上帝保证这是真的。 </p>
    </body>
    </html>
    """
    return html_str

然后,使用flask run命令重新启动Ahoh项目,在浏览器中输入127.0.0.1/html,就可以看到一个简单的HTML页面了!

我用Flask写网站《01 Hello Flask》,第2张
hello HTML展示页面

虽然已经可以看到了HTML页面,还存在一个严重的问题:哪个小傻瓜还会在业务代码里面写HTML呢?

常规情况下,HTML都是存储在.html文件中的,和业务代码隔离,还好Flask早就想好处理方式。

Flask中,所有的HTML文件默认存储在templates文件夹下,所以,需要先创建templates文件夹,然后在文件夹内创建HTML文件,这里我就创建一个hello.html文件。

(venv)~/ahoh$ mkdir templates             # 创建templates文件夹
(venv)~/ahoh$ touch templates/hello.html  # 创建html文件

然后将上面例子中html_str中的值复制到hello.html文件中,然后稍作修改,如下:

<!-- ~/ahoh/templates/hello.html -->
<html>
<head>
    <title>HTML页面</title>
</head>

<body>
    <h1>我的第二个HTML页面</h1>
    <hr>
    <p> How Are You, Savior </p>
</body>
</html>

首先,在app.py文件的头部引入render_template函数:

from flask import render_template

然后,在app.py 中追加新的路由函数,访问路径就定为/hello

# ~/ahoh/app.py
@app.route('/hello')
def hello():
    return render_template('hello.html')

这样,就完成了hello.html文件的添加,此时,使用flask run重启服务,在浏览器中输入地址127.0.0.1:5000/hello就能看到第二个HTML页面了!

我用Flask写网站《01 Hello Flask》,第3张
第二个HTML页面

这里,我们使用了一个新的函数render_template(),这个函数可以直接渲染HTML文件,不需要我们从文件中读出HTML代码后再返回,后面我们使用的Jinja模板也需要通过这个函数渲染。

3. 你好,Jinja

截至小节2,我们已经可以成功的利用Flask返回一个HTML页面了。

但是,当前的页面只是一个静态的HTML,文件中的内容都是写死了的,这当然不是我想要的结果。

这里就要引入Flask默认的HTML模板引擎Jinja

templates文件夹中,新建jinja.html文件,然后将hello.html中的内容复制过去,并稍作更改。
如下:

<!-- ~/ahoh/templates/jinja.html -->
<html>
<head>
    <title>Jinja页面</title>
</head>

<body>
    <h1>我的第一个Jinja页面</h1>
    <hr>
    <p> How Are You, {{name}}</p> <!-- Jinja 使用 {{}} 作为变量 -->
</body>
</html>

然后,在app.py中新建一个路由函数(视图函数),即追加如下代码:

# ~/ahoh/app.py
@app.route('/jinja')
def jinja():
    return render_template('jinja.html',name='Jinja') # 使用name='Jinja'向HTML中传入值
我用Flask写网站《01 Hello Flask》,第4张
Jinja示例

这里,我们就成功的创建了一个动态的页面,在视图函数中,修改name的值,前端HTML就会做出相应的变化。

name的值,从后端(视图中)传递到前端(HTML页面中)也非常的简单,只需要在render_templates()函数中增加一个参数就可以了。

到这里就结束了吗?当然,没有,我们虽然创建了一个使用JinjaHTML页面,也实现了从后端向前端传递参数,可以动态的修改页面,但是,如何从前端向后端传递参数呢?

templates文件夹中创建文件新的HTML页面,命名为:para.html,然后将jinja.html中的内容复制过去,并稍作修改,如下:

<!-- ~/ahoh/templates/para.html -->
<html>
<head>
    <title>参数传递</title>
</head>

<body>
    <h1>传递参数页面</h1>
    <hr>
    <p> How Are You, {{name}}</p>
</body>
</html>

然后在app.py中创建一个新的视图函数,在app.py文件中追加如下内容:

# ~/ahoh/app.py
@app.route('/para')
@app.route('/para/<string:name>')
def para(name='God'):
    return render_template('para.html',name=name)

现在,就可以重启Ahoh应用,然后在浏览器地址栏中输入127.0.0.1:5000/para/老天爷,效果如下:

我用Flask写网站《01 Hello Flask》,第5张
Flask参数传递

这种传递参数的方式是通过URL路径传递,可能大多数人更熟悉的是使用?para_name=value的方式,在Flask中同样是可以用的,不过需要在视图函数中使用request.args.get('para_name')的方式获取传递的值。

感兴趣的童鞋赶快去试试吧,不会做可以留言讨论呦。

4. 你好,templates

最后,也是本文的重点内容,疲倦的同志提提神了!Jinja模板的引入。

经过第3小节的学习,相信童鞋们都已经非常清楚,如何添加一个HTML页面,并创建对应的视图函数了。

但是,有一个问题,当我创建一个HTML页面的时候,都要完整的在文件中写入一个页面的代码。

而这些代码,大部分情况下都是重复的。

通常情况下,一个页面的HTML代码是非常长的,如果每次建立新的页面会非常浪费时间。

我希望有一种类似于类继承的机制,可以避免重复代码的出现,这就是Jinja的模板机制。

首先,我需要先创建一个基础模板,类似于Python或者Java的基类。

templates文件夹下,创建文件base.html,内容如下:

<!-- ~/ahoh/templates/base.html -->
<html>
<head>
    <!-- Jinja使用{% %}定义代码块 -->
    {% block head %}
    <title>{{title}}</title>
    {% endblock %}
</head>
<body>
    {% block header %}
    <h1>{{header}}</h1>
    {% endblock %}
    <hr>
    {% block content %}
    <p> I want to be a good man. </p>
    {% endblock %}
</body>
</html>

此时,基础模板文件就搭建好了。

这个时候,我就想新建一个用于展示文章的页面,post.html

首先,在template文件夹下创建文件post.html,然后编辑文件如下:

<!-- ~/ahoh/templates/post.html -->
{% extends 'base.html' %}

<!-- head块不在当前页面展示,表示默认继承 -->

<!-- header块显式引用,表示覆盖原有代码,由于这里什么都没写,就是空的 -->
{% block header %}
{% endblock %}

<!-- content同样是显式引用,但是使用了super关键字,表示在继承原有内容的继承上添加。 -->
{% block content %}
{{super()}}
<p> I became a bad guy. </p>
{% endblock %}

然后,在app.py中添加/template视图,代码如下:

@app.route('/template')
def template():
    return render_template('post.html',title="Template")

重启服务器,后在地址栏输入127.0.0.1:5000/template,执行结果如下:

我用Flask写网站《01 Hello Flask》,第6张
Jinja模板示例

虽然,base.html非常简单,但是在post.html中同样展示了Jinja代码块的三种使用方法,即默认继承使用(head块)、覆盖(header块)、最后是继承继承上添加(content块)。

写在最后

本文重点是Jinja模板引擎,除了当前展示的简单用法之外,Jinja还有非常多方便、快捷的使用技巧。
在后继的文中都会一一展示的。

另外,说说本文的写作思路,本系列的文章将采用不求甚解、以功能实现为导向的介绍方法。

这么做的原因是,Flask全栈技术中的分支过于庞大,一一解读过于复杂。

本文,包括后继的文章,都以实现功能为目的,仅仅介绍需要使用的到的内容,不对技术栈横向发展。

但是,如果文中有讲解的不够清楚的地方,还请留言指正,我会实时更新文档。

此外,欢迎来我的论坛讨论Flask搭建博客网站的问题和经验。www.ahoh.club。

本系列所有文章都会同步到这里,如果不想关注博主,就来这里阅读吧!


https://www.xamrdz.com/backend/3tf1940050.html

相关文章: