原文:https://blog.csdn.net/u014793102/article/category/9285123
Flask從入門到做出一個博客的大型教程(一)
本項目全部在虛擬環境中運行,因此請參照前面的文章,鏈接為https://blog.csdn.net/u014793102/article/details/80302975 建立虛擬環境后,再接着完成本教程的學習。
0 開始之前
網上看了很多教程,都不是很滿意,因此自己寫一個大型教程,從入門到做出一個比較完整的博客。此次教程不是直接把整個博客直接代碼整理出來然后運行一遍就完事,我會從flask的各個模塊講起。所以,如果你沒有接觸過flask,按照整個教程完整做一遍會掌握flask。(前提是你要有一定Python和web基礎)
1 Hello world !
如果你接觸過任何編程語言,對這個小標題都會很熟悉,此次對flask的學習也是從這個小例子開始。
准備工作環境
1 duke@coding:~$ mkdir flask_tutorial 2
3 duke@coding:~$ cd flask_tutorial/
4
5 duke@coding:~/flask_tutorial$ virtualenv --no-site-package venv 6 Using base prefix '/home/duke/.pyenv/versions/3.6.4'
7 New python executable in /home/duke/flask_tutorial/venv/bin/python3.6
8 Also creating executable in /home/duke/flask_tutorial/venv/bin/python 9 Installing setuptools, pip, wheel...done. 10
11 duke@coding:~/flask_tutorial$ source venv/bin/activate 12 #進入Python虛擬環境
13 (venv) duke@coding:~/flask_tutorial$ 14 (venv) duke@coding:~/flask_tutorial$ pip install flask 15 #創建flask目錄
16 (venv) duke@coding:~/flask_tutorial$ mkdir flask 17
18 (venv) duke@coding:~/flask_tutorial$ cd flask/
19
20 (venv) duke@coding:~/flask_tutorial/flask$
正式開始
1 (venv) duke@coding:~/flask_tutorial/flask$ mkdir app 2
3 (venv) duke@coding:~/flask_tutorial/flask$ cd app/
4 #創建初始化文件
5 (venv) duke@coding:~/flask_tutorial/flask/app$ touch __init__.py
在_ _ init _ _.py中寫如下代碼,你可以使用pycharm,vscode等IDE來更快的書寫代碼。
app/_ _ init _ _.py : 項目初始化
1 from flask import Flask 2 #創建app應用,__name__是python預定義變量,被設置為使用本模塊.
3 app = Flask(__name__) 4 #如果你使用的IDE,在routes這里會報錯,因為我們還沒有創建呀,為了一會不要再回來寫一遍,因此我先寫上了
5 from app import routes
創建路由模塊,你可以使用IDE直接新建,沒有必要要使用命令行創建
1 (venv) duke@coding:~/flask_tutorial/flask/app$ touch routes.py
app/routes.py : 主頁路由
1 #從app模塊中即從__init__.py中導入創建的app應用
2 from app import app 3
4 #建立路由,通過路由可以執行其覆蓋的方法,可以多個路由指向同一個方法。
5 @app.route('/') 6 @app.route('/index') 7 def index(): 8 return "Hello,World!"
現在基本都齊全了,但是我們還是需要在app模塊之外創建一個主入口,即執行這個主入口就可以達成運行整個項目的目的。
1 (venv) duke@coding:~/flask_tutorial/flask/app$ cd .. 2 (venv) duke@coding:~/flask_tutorial/flask$ touch myblog.py
myblog.py : 項目入口
1 #從app模塊中導入app應用
2 from app import app 3
4 #防止被引用后執行,只有在當前模塊中才可以使用
5 if __name__=='__main__': 6 app.run()
現在整個小demo就完成了,結構應該是這樣的
1 flask 2 ├── app 3 │ ├── __init__.py 4 │ └── routes.py 5 └── myblog.py
ok,接下來就讓項目跑起來
1 (venv) duke@coding:~/flask_tutorial/flask$ export FLASK_APP=myblog.py 2
3 (venv) duke@coding:~/flask_tutorial/flask$ flask run 4 * Serving Flask app "myblog.py"
5 * Environment: production 6 WARNING: Do not use the development server in a production environment. 7 Use a production WSGI server instead. 8 * Debug mode: off 9 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
在瀏覽器里輸入http://127.0.0.1:5000/ 或者 http://127.0.0.1:5000/index 都可以訪問你的項目啦!

2 模板
在1里,我們完成了一個返回值的顯示,但這肯定遠遠不能滿足我們需求的。因為我們希望看到的是豐富多彩的網頁呀~,有什么辦法呢?上一步咱們返回了一個值,那咱們返回一個網頁會怎么樣呢?
app/routes.py : 返回一個網頁
1 from app import app 2
3 @app.route('/') 4 @app.route('/index') 5 def index(): 6 user = {'username':'duke'} 7 html = '''
8 <html> 9 <head> 10 <title>Home Page - Microblog</title> 11 </head> 12 <body> 13 <h1>Hello, ''' + user['username'] + '''!</h1> 14 </body> 15 </html> 16
17 '''
18 return html
如圖所示,這樣就完成了返回網頁的目的,但是這樣實在是太麻煩了,因此肯定有解決這個問題的辦法嘍。對,模板就是解決這個問題的辦法。
1 (venv) duke@coding:~/flask_tutorial/flask$ mkdir app/templates 2 #在新建的templates中新建一個index.html
3 (venv) duke@coding:~/flask_tutorial/flask/app/templates$ touch index.html
app/templates/index.html : 主頁模板,將數據顯示在其中
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8">
5 <title>{{ title }} - 博客</title>
6 </head>
7 <body>
8 <h1> Hello ,{{ user.username }} !</h1>
9 </body>
10 </html>
這里出現{{ }} 意味着變量,可以接受數據的地方。既然在這里寫了變量,那么就要在路由中修改對應的格式,因為要把數據返回才可以。
app/routes.py : 將寫在路由中的html刪除,並增加一些變量。
1 #導入模板模塊
2 from flask import render_template 3 from app import app 4
5 @app.route('/') 6 @app.route('/index') 7 def index(): 8 user = {'username':'duke'} 9 #將需要展示的數據傳遞給模板進行顯示
10 return render_template('index.html',title='我的',user=user)
從新運行后,效果還是符合預期的。但是,如果你傳遞至模板的數據是空的,那頁面顯示豈不是很難看?因此我們需要在模板中加上一些判斷,看數據是否為空。
app/templates/index.html : 主頁模板,完善模板
1 <!DOCTYPE html>
2 <html >
3 <head>
4 <meta charset="UTF-8">
5 {% if title %} 6 <title>{{ title }} - 博客</title>
7 {% else %} 8 <title>歡迎來到博客!</title>
9 {% endif %} 10 </head>
11 <body>
12 <h1>Hello, {{ user.username }}!</h1>
13 </body>
14 </html>
如果傳進來的數據很多,那么就可以使用循環來展示數據。首先,還是對路由里的方法進行修改。
app/routes.py : 增加一些數據
1 from flask import render_template 2 from app import app 3
4 @app.route('/') 5 @app.route('/index') 6 def index(): 7 user = {'username':'duke'} 8 posts = [ 9 { 10 'author':{'username':'劉'}, 11 'body':'這是模板模塊中的循環例子~1'
12
13 }, 14 { 15 'author': {'username': '忠強'}, 16 'body': '這是模板模塊中的循環例子~2'
17 } 18 ] 19 return render_template('index.html',title='我的',user=user,posts=posts)
增加了這些數據之后要對模板中的結構進行一些修改。
app/templates/index.html : 循環展示數據
1 <!DOCTYPE html>
2 <html >
3 <head>
4 <meta charset="UTF-8">
5 {% if title %} 6 <title>{{ title }} - 博客</title>
7 {% else %} 8 <title>歡迎來到博客!</title>
9 {% endif %} 10 </head>
11 <body>
12 <h1>你好呀, {{ user.username }} !</h1>
13 {% for post in posts %} 14 <div><p>{{ post.author.username }} 說:<b>{{ post.body }}</b></p></div>
15 {% endfor %} 16
17 </body>
18 </html>
我們發現,每次修改頁面都是要有很多重復的不必要代碼,因此把重復的代碼放到一個基類模板里,在里面留上占位符,這樣只需要修改其中一部分就可以了,十分方便。
創建一個基類模板
1 (venv) duke@coding:~/flask_tutorial/flask/app/templates$ touch base.html
app/templates/base.html : 填充內容
1 <!DOCTYPE html>
2 <html >
3 <head>
4 <meta charset="UTF-8">
5 {% if title %} 6 <title>{{ title }} - 博客</title>
7 {% else %} 8 <title>歡迎來到博客!</title>
9 {% endif %} 10 </head>
11 <body>
12 <div>博客 : <a href="/index">首頁</a></div>
13 {% block content %} 14
15 {% endblock %} 16 </body>
17 </html>
那么這有什么作用呢?注意這里面有{% block content %} {% endblock %}這一對標簽,因此其他頁面只需要繼承這個頁面,然后寫上相同的標簽,在標簽內寫上內容,就可以完整的在頁面上顯示所有內容。既然有了基類模板,那么index.html顯示就不需要那么多代碼了,這里對index.html進行修改。
app/templates/index.html : 修改格式和內容
1 {% extends 'base.html' %} 2
3 {% block content %} 4
5 <h1>你好呀, {{ user.username }} !</h1>
6
7 {% for post in posts %} 8 <div><p>{{ post.author.username }} 說:<b>{{ post.body }}</b></p></div>
9 {% endfor %} 10
11
12 {% endblock %}
再此訪問主頁面的地址試一試!

