1.1.第一個flask程序
from flask import Flask
#創建一個Flask對象,傳遞__name__參數進去
app = Flask(__name__)
#url與視圖映射
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run() #flask中的一個測試應用服務器
瀏覽器訪問:http://127.0.0.1:5000/,也可以更改端口號: app.run(port=5001)
1.2.debug模式
作用:
- 如果拋出異常,在瀏覽器中可以看到具體錯誤信息
- 在修改代碼后,只要按“ctrl+s”,就會自動重啟項目,不用手動重新運行
四種配置方式
第一種
if __name__ == '__main__':
app.run(debug=True)
第二種
app.debug = True
第三種
app.config.update(DEBUG=True)
第四種
新建config.py
DEBUG = Ture
然后在主程序總導入引用
cnfig文件
import config app.config.from_object(config)
另外的執行文件
from flask import Flask
import config
#創建一個Flask對象,傳遞__name__參數進去
app = Flask(__name__)
# app.debug = True #第二種
# app.config.update(DEBUG=True) #第三種
app.config.from_object(config) #第四種
#url與視圖映射
@app.route('/')
def hello_world():
print('helloworkl')
return 'Hello World!'
if __name__ == '__main__':
# app.run(debug=True) #第一種
app.run()
1.3.配置文件
新建config.py
DEBUG =True
主程序中兩種引用方式
第一種:
import config app.config.from_object(config)
第二種
app.config.from_pyfile('config.py')
1.4.url傳參方式
普通傳參方式
@app.route('/p/<id>/')
def article_detail(id):
return '你訪問的文章第%s篇'%id

指定參數類型
有以下幾種類型:
- string:默認的數據類型
- int:接受整形
- float:浮點型
- path:和string的類似,但是接受斜杠
- any:可以指定多個路徑
- uuid:只接受uuid字符串
(1)any
@app.route('/<any(blog,user):url_path>/<id>')
def detail(url_path,id):
if url_path == 'blog':
return '博客詳情%s'%id
else:
return '用戶詳情%s'%id


(2)path
@app.route('/article/<path:test>/')
def test_article(test):
return 'test_article:{}'.format(test)

獲取參數
from flask import Flask,request
@app.route('/tieba/')
def tieba():
wd = request.args.get('wd')
return '獲取的參數的是%s'%wd

1.5.url_for的使用
(1)通過視圖函數解析出url
from flask import Flask,url_for
@app.route('/')
def hello_world():
return url_for('my_list',page=2) #url_for里面:第一個是視圖函數,第二個是url需要的參數
@app.route('/list/<page>/')
def my_list(page):
return 'my_list'

(2)url_for里面多的參數會當做搜索字符
@app.route('/')
def hello_world():
return url_for('my_list',page=2,count=2)
@app.route('/list/<page>/')
def my_list(page):
return 'my_list'

1.6.Response
視圖函數中可以返回的類型
- 可以返回字符串,返回的字符串其實底層將這個字符串包裝成了一個‘Response’對象
- 可以返回元組,形式(響應體,狀態碼,頭部信息),返回的元組其實底層將這個字符串包裝成了一個‘Response’對象
- 可以返回Response及其子類
實現一個自定義的Response對象
- 繼承自、‘Response’類
- 實現方法‘force_type’
- 指定‘app.response_class’為你自定義的‘Response’對象
- 如果視圖函數返回的數據,不是字符串,也不是元組,也不是Response對象,那么就會將返回值傳給‘force_type’,然后將‘force_type’的返回值返回給前端
實例:
from flask import Flask,url_for,Response,jsonify
app = Flask(__name__)
class JsonResponse(Response):
@classmethod
def force_type(cls, response, environ=None):
'''
這個方法只有視圖函數返回非字符、非元祖、非Response對象才會調用
:param response:
:param environ:
:return:
'''
#把字典轉換成json
if isinstance(response,dict):
#jsonify將字典轉換成json對象,還將該對象包裝成了一個Response對象
response = jsonify(response)
return super(JsonResponse, cls).force_type(response,environ)
app.response_class = JsonResponse
@app.route('/')
def hello_world():
return 'Hello world'
@app.route('/list1/')
def list1():
return Response('list1') #合法對象,直接返回
@app.route('/list3/')
def list3():
return {'username':'derek','age':18} #返回的是非字符、非元祖、非Response對象,所以執行force_type方法
if __name__ == '__main__':
app.run(debug=True)
因為/list3/返回的是字典類型,非字符、非元祖、非Response對象,所以執行force_type方法

1.7.add_url_rule
源碼
主程序
from flask import Flask,render_template,url_for
app = Flask(__name__)
app.config.update({
'DEBUG':True,
'TEMPLATES_AUTO_RELOAD':True
})
@app.route('/',endpoint='index')
def hello_world():
print(url_for("derek_list")) #通過endpoint找到對應的url /list/
return render_template('index.html')
def my_list():
return "列表頁"
#三個參數
#1.url
#2.給url起個別名,如果沒有指定endpoint,則默認使用視圖函數的名字作為endpoint的值
#3.視圖函數
app.add_url_rule('/list/',endpoint='derek_list',view_func=my_list)
with app.test_request_context():
print(url_for('index')) # /
if __name__ == '__main__':
app.run()

1.8.類視圖
之前使用的視圖都是函數,簡稱為視圖函數,視圖也可以基於類來實現,類視圖的好處是支持繼承,類視圖需要通過app.add_url_role(url_rule,view_func)來進行注冊,類里面要加裝飾器就用:detactors=[] ,里面可以添加多個裝飾器
(1)標准視圖
- 繼承views.VIew
- 必須實現‘dispatch_request’方法,以后請求過來后,都會執行這個方法,返回值相當於視圖函數一樣,必須返回'Response'或者子類的對象,或者是字符串,或者是元祖
- 必須通過app.add_url_role(url_rule,view_func)來做url與視圖的映射
實例
from flask import Flask,url_for,views
app = Flask(__name__)
app.config.update({
'DEBUG':True,
'TEMPLATES_AUTO_RELOAD':True
})
class ListView(views.View):
def dispatch_request(self):
return "我的列表頁"
# 1.ListView.as_view('list')里面必須傳個參數‘name’,給view_func起個別名,實際上就是dispatch_request函數
# 2.endpoint也可以不指定,則默認使用view_func的別名(name參數的值)
app.add_url_rule('/list/',endpoint='list',view_func=ListView.as_view('list'))
@app.route('/')
def hello_world():
return 'Hello World!'
with app.test_request_context():
print(url_for('list')) #/list/
if __name__ == '__main__':
app.run()

(2)通過類的繼承實現多個視圖返回json數據
from flask import Flask,url_for,views,jsonify
app = Flask(__name__)
app.config.update({
'DEBUG':True,
'TEMPLATES_AUTO_RELOAD':True
})
#父類,把數據轉換成json格式
class JsonView(views.View):
def get_data(self):
raise NotImplementedError
def dispatch_request(self):
return jsonify(self.get_data())
#子類只需要寫get_data方法
class ListView(JsonView):
def get_data(self):
return {"usernmae":'derek','age':18}
app.add_url_rule('/list/',endpoint='list',view_func=ListView.as_view('list'))
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run()

(3)基於調度方法的類視圖
class LoginView(views.MethodView):
def __render(self,error=None):
return render_template('login.html', error=error)
def get(self,error=None):
return self.__render()
def post(self):
username = request.form.get('username')
password = request.form.get('password')
if username == 'derek' and password == '123':
return '登錄成功'
else:
return self.__render(error='用戶名或密碼錯誤')
app.add_url_rule('/login/',view_func=LoginView.as_view('login'))
來源: https://www.cnblogs.com/sui776265233/p/9879533.html#_label0
后記:
這個傳慘的方法可能會報錯 UnicodeDecodeError: 'ascii' codec can't decode byte 0xe9 in position 0: ordinal not in range(128)
原因: 因為默認情況下,Python采用的是ascii編碼方式,而Python在進行編碼方式之間的轉換時,會將 unicode 作為“中間編碼”,但 unicode 最大只有 128 那么長,所以這里當嘗試將 ascii 編碼字符串轉換成"中間編碼" unicode 時由於超出了其范圍,就報出了如上錯誤。
解決方法: 在文件上方加上
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
例子:
#coding=utf-8
from flask import Flask
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
app = Flask(__name__)
app.config.from_object('config')
@app.route("/hello/<id>/")
def hello(id):
return '你訪問的文章第%s篇'%id
app.run(host="0.0.0.0",debug=app.config["DEBUG"])
后記: 有更加優雅和簡單的方法實現 https://www.cnblogs.com/kaibindirver/p/12637027.html

