flask1 + jinja2 day88

人工智能方向 - 智能玩具

-1 所學內容:

1.flask(先後端交互的接口)(返回api(json))html

2.MongoDB NoSQL(自由度高,(沒什麼限制),操做就難)4版本(多了個事務)+3.4前端

3.人工智能 A.I. 應用技術 Not 算法和機器學習java

4.webSocket 全雙工通信 IM即時通信python

5.Mui(佈局,佈局一個 ) + HTML5Plus(打開硬件有封裝) App (工做了,就是一個小兒科,這些框架,質的飛躍)程序員

6.智能玩具 + 機器學習web

0 Django 和 Flask 優劣勢

Django 15天面試

​ 優點:組件全 - admin - Model ORM - Forms
​ 教科書式(其餘框架和他像)算法

​ 劣勢:加載的組件是所有的組件 - 佔用資源較高
​ 重型框架django

Flask 3 天json

​ 優點:輕如鴻毛 擴展性極強 三方組件全

​ 劣勢:什麼組件都沒有
​ 三方組件全 - 版本兼容問題 致使不穩定
​ 線程的支持(不如dj)

1 flask 初識

1.1 flask 安裝+啓動

安裝

新建pure python項目
-new environment 選擇 Virtualenv
--選擇interpreter
---選擇make available to all projects

啓動

在大目錄下,新建一個py文件

from flask import Flask     #導入Flask以及別的
app=Flask(__name__)         #Flask第1個參數 模塊名 
app.run()    #默認訪問http://127.0.0.1:5000/ 端口啓動也能夠指定別的端口
好比:#  app.run('0.0.0.0',9527)

Flask 源碼:

def __init__(
        self,
        import_name,

返回錯誤 503 能夠鏈接,可是沒有返回視圖

1.2 模板的書寫

from flask import Flask,render_template  #返回模板
app=Flask(__name__)         
@app.route('/')   # route() 裝飾器 url 觸發--> 函數
def home():
    # return 1                  #不能返回整型
    return 'hello world'        #可字符,字典,列表
@app.route('/index')        
def index():                    
    return render_template('index.html')    #來渲染模板。
app.run()

方法:

1 寫一個templates
把index.html 放了裏面 而後飄黃

2 make dir template dir 選擇jinja2 (webpy ,django,等) (Django封裝了(要不也可使用jiaja2了) jinja2最好 )

Flask 會在 templates 文件夾裏尋找模板, 以後就能夠向django同樣使用模板了,自動補全
因此,若是你的應用是個模塊,這個文件夾應該與模塊同級;若是它是一個包,那麼這個文件夾做爲包的子目錄:

狀況 1: 模塊:

/application.py
/templates
    /hello.html

狀況 2: 包:

/application
    /__init__.py
    /templates
        /hello.html

1.3 flask1.1以前使用jsonify

jsonify 模塊

from flask import Flask,render_template,jsonify
@app.route('/json')
def my_jsonify():
    # return jsonify({'a':1})   #字典轉成json字符串
    return {'k':1}              #1.1後支持直接傳字典
return jsonify(username=g.user.username,...
--------》
This will send a JSON response like this to the browser::
  {
            "username": "admin",...

flask 中的返回特殊封裝 2個

1 jsonify 轉換標準JSON格式

​ 響應頭中加入 Content-type:application/json
​ app/json 自動的將 轉換成object?字典?

​ flask1.1下 直接返回字典了,能夠不用使用jsonify (向下兼容了) (flask以前的的必須使用jsonify,做爲一個開發兩年的mn)

2 send_file 發送文件

alt + 回車(補全import)
打開並返回文件內容,
自動識別文件類型,
響應頭中加入了 Content-Type

前端 : 只和request有關係
全部response都是後端處理的

text  image   audio/mpeg(MP3)  video/mp4(兩次請求,http請求數據是有限制的,流媒體,節省服務器資源)        my_file my_file 

全部瀏覽器沒法識別的東西: 都如下載的格式返回 
好比zip格式的    Content-Type: application/x-zip-compressed

爬蟲的時候: 採集視頻難,一段一段,中間還得帶驗證碼

當我傳MP3MP4格式的時候,發現MP3格式的圖標是? 而MP4的格式是文本同樣(可是能夠傳說明沒問題)

send_file代碼以下:(文件都在主目錄下)

@app.route('/my_file')
def my_file():
    # return send_file('1.png')
    # return send_file('app01.py')
    # return send_file('1.mp3')
    # return send_file('1.mp4')
    # return send_file('1.jpg')
    return send_file('1.zip')

if name == 'main':

做用:執行的時候才走,被別的調用的時候不走了

from flask import Flask,render_template
app = Flask(__name__)

@app.route('/login')
def login():
    return render_template('login.html')

if __name__ == '__main__':  # 只有調用的時候才執行  別的文件引入時候不執行
    app.run()

2 . request

<h1>login</h1>
<form action="" method="post">
    用戶名:<input type="text" name="username">
    密碼:<input type="password" name="pwd">
    <input type="submit" value="登陸">

405 : 請求方式不被容許

127.0.0.1 - - [10/Jul/2019 10:32:53] "GET /login HTTP/1.1" 200 -
127.0.0.1 - - [10/Jul/2019 10:33:03] "POST /login HTTP/1.1" 405 -

解決:

@app.route('/login',methods=['POST','GET'])

route容許post和get方法

request是全局的(公共對象),第一個用戶進來了,第二個用戶也都能用 那就不支持多進程了,有解決方法

request.form 獲取FormData的數據 - Form表單

request = LocalProxy(partial(_lookup_req_object, "request"))
if request.method == 'GET':     #請求方式
    return render_template('login.html')
if request.method == 'POST':
    print(request.form)
    print(request.form.get('username'))
    print(request.form.to_dict())
    return '200 OK'
ImmutableMultiDict([('username', 'asdfas'), ('pwd', 'adfasd')])         #多重字典    看到dict用get
2.2 request參數
request.headers      #請求頭中的數據

request.url #訪問路徑    http://127.0.0.1:5000/login
request.path#路由地址   /login

綜合獲取
request.values  #獲取URL中的參數 也能夠獲取FormData中的數CombinedMultiDict([ImmutableMultiDict([('id', '1'), ('ids', '2')]), ImmutableMultiDict([('username', '123'), ('pwd', '456')])])
request.values.get('id') # 

request.args.to_dict()   #獲取url參數{'id': '1', 'ids': '2'}
request.args['id'])     # key value key沒有值會報錯,get比較好     好比: KeyError: 'id'
request.args.to_dict()['id']

request.environ    #獲取請求原始信息 #{'wsgi.version': (1, 0), 'wsgi.url_scheme': 'http',  .........}

request.base_url     #獲取url頭,不包含參數                           #http://127.0.0.1:5000/login
request.json        #請求頭con-type:app/json 數據序列化  #None
request.data       #請求頭中contype 不包含Form or data #b''
      
      
request.headers      #Host: 127.0.0.1:5000

request.value的坑

因爲都是ImmutableMultiDict([('id', '1'),
若是前端提交name寫了id  那麼.to_dict() 就會被覆蓋
先寫的dataform後寫的url,url覆蓋
2. #指定目錄保存

默認保存到主目錄(項目)下

my_file = request.files.get('my_file')
my_file.save('save.jpg')
fp = os.path.join('templates',my_file.filename)  #
my_file.save(fp)  #指定目錄保存到templates下

區分form和from的方法

Form 表單 - FormData
f orm - 表單  
from
2.# 自動重啓

django自帶的

# app.config['DEBUG'] = True
app.debug = True #避免重啓

按ctrl + s  重啓 
切換也重啓
2.# url? 傳參
<http://127.0.0.1:5000/login?id=1>

這樣訪問 ?傳輸參數 不會對地址路由形成影響 是傳參了

3 模板傳參的寫法

3.1 py 視圖
STUDENT = {'name': 'Old', 'age': 38, 'gender': '中'}
STUDENT_LIST = [
    {'name': 'Old', 'age': 38, 'gender': '中'},...
STUDENT_DICT = {
    1: {'name': 'Old', 'age': 38, 'gender': '中'},..
  
  def 
  return render_template('index1.html', stu_info = STUDENT, stu_list = STUDENT_LIST, stu_dict = STUDENT_DICT,absum =ab)
3.2 模板文件寫法
(1)stu_info
<table border="1px">
    <tr>
        <td>name</td>
        <td>age</td>
        <td>gender</td>
    </tr>

  <tr>
        <td>{{ stu_info.name }}</td>
       <td>{{ stu_info.get('age') }}</td>
         <td>{{ stu_info['gender'] }}</td>
         #三種方式均可以得到字典的  可是key的慎用
(2)stu_list
{% for foo in stu_list %}   #(改性別)
   <td>{% if foo.gender!='男' and foo.gender!='女' %}
                女
                 {% else %}
                {{ foo.gender }}
(3)stu_dict(兩種方式 dict或者items()(不要忘了括號))
{% for id in stu_dict %}
    <tr>
        <td>{{ id }}</td>
        <td>{{ stu_dict[id].name }}</td>
        <td>{{ stu_dict.get(id).get('age') }}</td>
{% for id,s in stu_dict.items() %}
    <tr>
        <td>{{ id }}</td>
        <td>{{ s.name }}</td>
        <td>{{ s.get('age') }}</td>

id 和 s

{#    {{ id  }}   {#1 {'name': 'Old', 'age': 38, 'gender': '中'} 2 {'name': 'Boy', 'age': 73, 'gender': '男'} 3 {'name': 'EDU', 'age': 84, 'gender': '女'}#} #}
{#    {{ s }}#}
(4)全部的模板都用到這個函數(傳函數)
@app.template_global()      #全局的
def ab(a,b):
    return a+b

一般作一個模塊,到引入就好了,都引入

return render_template('index1.html',absum =ab)#傳到模板   #不用absum的  全局的

模板使用

center>{{ absum }}</center>
<center>{{ ab(2,2) }}</center>

#<function ab at 0x0000000003873488>
#4
(5)宏函數(什麼用?)生成一個標籤?
{% macro my_input(na,ty)%}
    <input type="{{ ty }}" name="{{ na }}">
{% endmacro %}

{{ my_input('uname','text')}}

傳給模板一個標籤

my_in = Markup("<input type= 'text',name='uname'>")
return render_template('index1.html',m=my_in)
{{m}}       #使用
3.2 jinja2

{{}} 引用 or 執行

{%%} 邏輯語法 if for else

今天上課都是由於一個,逗號困住,因此不得往下面的,惋惜,細節

4 session

登陸頁面提交方式

<h1>login</h1>
{#<form action="/login?id=1&ids=2" method="post" enctype="multipart/form-data">#}
                                                        #url倒是post方式的提交
<form action="" method="post">
    用戶名:<input type="text" name="username">
    密碼:<input type="password" name="pwd">
{#    <input type="file" name="my_file">#}              #提交文件
    <input type="submit" value="登陸">

session和request同級的,不和Django同樣,request.django

request = LocalProxy(partial(_lookup_req_object, "request"))
session = LocalProxy(partial(_lookup_req_object, "session"))            #基本同樣
登陸+加入session(默認31天)
app.secret_key = '*Ud8fadjfadkjfaidjf'  #驗證碼
@app.route('/login',methods=['POST',"GET"])
def login():
    if request.method == 'GET':
        return render_template('login.html')

    uname = request.form.get('username')
    pwd = request.form.get('pwd')

    if uname == '123' and pwd == '123':
        session['username'] = uname
session登陸
@app.route('/detail')
def detail():
    if session.get('username'):
        return render_template('index.html')
    else:
        return redirect('/login')

session存到哪了?

Flask中的Session 不是三方組件 //Flask-Session

  1. 內置的

from flask import session

session['username'] = uname #加入session

RuntimeError
The session is unavailable because no secret key was set.  Set the secret_key on the application to something unique and secret.
解決:   app.secret_key = '*Ud8fadjfadkjfaidjf'  ####密鑰的寫法不是app.session,而是app

session 交由客戶端保管

反序列化機制

當客戶端發起請求 -request 帶上cookie - cookie中有session的加密字符串 -flask 收到session加密字符串 - 經過 secret_key 解密session的加密字符串 得到 {username : 123}

app.permanent_session_lifetime = 15 (默認是秒)

均可以改 這些內容 (別再源碼裏改,提出來改)進入源碼: session-->global session app.py裏的內容

"PERMANENT_SESSION_LIFETIME": timedelta(days=31),

程序裏改:

app.permanent_session_lifetime = 15

查看在前端application-->Cookies--> 代替了cookie, network點擊login裏沒有改

app.session_cookie_name = "I am Not Session"
app.testing = True

序列化機制

開啓session - session['username'] = uname

建立一個字典 {username:123} 接下來 經過secret_key(密鑰安全) + 時間戳 + 簽名 加密 造成

eyJ1c2VybmFtZSI6IjEyMyJ9.XSVovw.g6ZxiiEw_0EhRHF--oTG9Ac-ZF8 session的加密字符串
簽名.時間戳.數據

if uname == '123' and pwd == '123':
        session['username'] = uname
if uname == '123' and pwd == '123':
        session['username'] = uname
        session['username1'] = uname
        session['username2'] = uname

.eJyrViotTi3KS8xNVbJSMjQyVtKBCxhiiBhhiBhDRWoBGaYU8w.XSXASw.cExXNorpTmERznwqRl9mdO4Tu7Y 寫了多個session,session就多了不少 由於{username:123,username1:123,} 有公共機制因此說: 不會太長了

if uname == '123' and pwd == '123':
    session['dasgas'] = '打分'
    session['ada'] =  '網頁'

.eJyrViotTi3KS8xNVbJSiik1NTK0iCk1SzFIUtKByxjiljLCLWWMLlULACpUIRM.XSXBYw.uZrsOt2eoTJX4pJPoxQk4wSxjJY(多了,由於2個漢字6個)

不能線上開debug,會暴露密鑰,在前端頁面顯示錯誤的時候,可能就會暴露,相對安全不是絕對的安全了

5 全局變量global

錯了好屢次了

a = 0

@app.route('/detail')
def detail():
    global a
    if session['username']:
        a += 1
        print(a)

做業:

1 用裝飾器裝飾一個登陸函數

​ 返回request(雙重裝飾器)

2 每個視圖函數都加上裝飾器

能寫三遍的不寫兩遍,背誦默寫,哪不會的

工具:

不要太依賴,若是沒有pycharm怎麼辦
記事本怎麼寫,能不能寫 (今天學的可不能夠寫)
以後多是各類工具

以後花錢買個 視頻 看看破解版的  專業的(兩三塊錢)
不要更新        (把算法替換掉)

pycharm 是java寫的, java的算法 , 亂碼是算法的值,就連上了

規劃:技術之上

技術:是掉接口的碼農?仍是
架構:更偏向技術
懂技術的產品還能夠

工做經驗

會,必需要全會,纔算掌握一個語言 --龍

面試

看面試官 眉心 就能夠把人看緊張了
吹了27k,原本15k。。。壓力也大
15 16 K的程序員 都是應用層次的 用過什麼
25k的左右的是接觸過什麼架構 什麼項目

吹得話: ai開放能力,找一個,學或者瞭解()
人工智能 有標籤 ,提上簡歷,有一個算法,招標籤

龍交的nlp,還真會點 18k,把本身吹太牛了,不敢去(很能吹的南方人 能吹offer多7個)

遇到特別不屑的,直接走,轉身走(不要回頭)

sanic

學習稍微難些
最新的框架,python最快的 (先天寫的東西都比他快的不少)(世界上沒有最好的語言,本身用的就是最好的,沒有最好的程序員,本身) python數據計算很是快

錯誤1 多加了個逗號字典變元祖

STUDENT = {'name': 'Old', 'age': 38, 'gender': '中'} ,

stu_info = STUDENT 時 , stu_info.name 等都沒有值,是空的 ,而stu_info 有值 等於:
({'name': 'Old', 'age': 38, 'gender': '中'},)

之後不要犯這種錯誤

多加了個,成了元祖類型了(其實提示了tuple not get ,可是不看提示,看了也不懂把)

本身寫程序出的錯

錯誤2 AttributeError

1 AttributeError: read only property

request.method = ['POST','GET']     --->request.methods = ['POST','GET']

2 jinja2.exceptions.TemplateNotFound
jinja2.exceptions.TemplateNotFound: login.html #---> 扔到主目錄下,把文件

3 Method Not Allowed (405 403)
The method is not allowed for the requested URL.

request.methods = ['POST','GET']    #這個寫法不對,無法分配POST方法

​ -->@app.route('/login',methods=['POST',"GET"])#直接寫上面

錯誤3 記錯命令 還一直堅持嘗試

ctrl + enter 不是快速導入的命令
alt + enter 纔是快速導入模塊的命令

快捷鍵1

再加個命令 ctrl+shift+i 是前端的檢查快捷鍵

相關文章
相關標籤/搜索