flask學習筆記

flask

運行流程

  1. creat一個app對象,通過Flask(name)來註冊方法,然後run_app

  2. 通過flask_script將app註冊到manager 可以自定義一些其他的command manager=Manager(app)

  3. 在creat_app方法中註冊app的一些功能模塊

    moment=Monment() moment.init_app(app)

  4. app.register_blueprint() 註冊藍圖:

    auth_blueprint=Blueprint(‘sd’, _ name _)

    app.register_blueprint(auth_blueprint, url_prefix=’/auth’)

  5. 5.

博客項目

將程序實例的創建推遲到配置文件的載入後
推遲到工廠函數中

app=Flask(name) app的名稱

app.config 加載配置文件
使用藍本來處理路由
. 從init.py 中引入
- 避免循環導入依賴的方法 依賴放在最後面

密碼

通過散列來保存密碼
通過設置屬性來調用方法

  • 通過使用itsdangerous生成確認令牌
    包含用戶id,感覺和散列有點像

必須先提交數據庫,然後再郵件認證

用戶

認證

註冊先存入數據庫,然後根據數據庫返回的序列號生成一個鏈接,email發送,如果點擊鏈接,跳轉到函數,讓數據庫中is_confirmed那項爲true

如果沒認證,每次登陸都跳轉到index頁面

  • 通過token 來得到data,data是一個字典類型
    然後 data.get(id)來得到用戶的序號

_external=True 參數在
url_for()中 的路由的參數是函數的名字

  • 通過before login 來確定是否認證,如果沒認證就跳轉到認證頁面

用戶登錄

讓數據庫 User models 增加 userMinxin from flask_login導入的。
- 從view頁面得到當前user的數據庫模型,user.get_or_create(id)

重置密碼:

兩種重置密碼方式

一種是登錄的情況下,一種是非登錄的情況下,都應該郵件確認,保證安全

和郵件認證用戶一個道理,但不同的是,這個token中要包含用戶的信息,那個token是固定的密碼.

所以這個token解密後應該是 包含用戶信息的。

token的有效載荷是固定的,不能被僞造。 有效載荷中包含用戶的信息以及祕鑰的信息

{‘reset_password’:user_id,’exp’:token_expiration}

python2.7用serilize包, 把需要添加的值dump進去

需不需要一個實用的工具包

來處理瑣碎的事情

比如說生成密碼token,發送郵件什麼的。

反正發送郵件要交給後臺來處理

pip

安裝到某個文件夾下的txt中
pip install -r requirements/dev.txt

測試

單元測試
文件都寫在tests文件夾下

在manage.py中寫的命令
@manager.command
def test():
import unittest
tests = unittest.TestLoader().discover(‘tests’)
unittest.TextTestRunner(verbosity=2).run(tests)
- python manage.py test

操作權限

關注用戶:1
發表評論:2
寫文章:4
管理評論:8
管理員權限:128

用戶權限

用戶的等級
匿名:0
正式用戶:7
協管員:15
管理員:255

current_user方法

is_anonymous 判斷是否是匿名用戶

藍本

來處理路由,不同的功能使用不同的藍本
相當於django中的分開處理路由

在工廠函數中註冊藍本,相當於django在主頁面的Url添加輔助功能的url

template

template中可以讀取txt路徑,作爲html的內容

路徑問題

模板的路徑是相對於程序模板文件夾來說的

base中auth.logout對應的是方法名,而不是路徑名

方法名和路徑名好像必須要一樣。。。

在html中添加動態路徑

路由跳轉

接受函數名作爲參數

url_for(‘main.user’,username=current_user.username)

return redirect(url_for('main.user',username=current_user.username))

flask-login

將login_manager添加在login中
LoginManager 對象的 session_protection 屬性可以設爲 None、’basic’ 或 ‘strong’,以提 供不同的安全等級防止用戶會話遭篡改。設爲 ‘strong’ 時,Flask-Login 會記錄客戶端 IP 地址和瀏覽器的用戶代理信息,如果發現異動就登出用戶
表單: user email password remember submit

數據庫

sqlalchemy

用來更新Model表的參數

類型於django migration 和migrate
- 初始化 創建migrations文件夾
python manage.py db init

  • 遷移 相當於django中的migrate
    python manage.py db migrate -m ‘second migrate’
  • 實際遷移到數據庫中 相當於django makemigraions
    python hello.py db upgrade

  • event sqlalchemy set 時間的監聽程序,只要進行了set 就會調用on_changed_body函數
    on_change_body函數將markdown渲染爲html,然後返回

聯結操作

在文章頁面只顯示用戶關注用戶的文章
Post.join(Follow,Follow.follow_id==Post.author.id)

相關知識

  • 主鍵是不唯一的

  • casacde 級聯刪除的意思,當刪除外鍵依賴的主表時,子表內容自動刪除

api

  • order_by.all()
  • filter_by().first()
  • 對主鍵進行查找 .get_or_404()

分頁

  • query.order_by(Post.timestamp.desc()).paginaton()
    分頁的屬性:
  • items 查詢到的記錄
  • query 源查詢
  • page 當前頁數
  • prev_num 上一頁的頁數
  • next_num 下一頁的頁數
  • has_next 是否有上一頁
    -has_prev 是否有上一頁
  • pages 總頁數
  • per_page 每頁的記錄數量
  • total 記錄總數、

在對象上調用的方法
iter_pages 迭代器,返回一個頁數列表

寫好一個分頁頁面, _macros,然後在其他需要分頁的html中將這個頁面插入

alembic

  • 初始化
mbic init YOUR_ALEMBIC_DIR

relationship

關係之間的便捷調用

Student model:
classes=db.relationship(‘class’,secondary=restrations,backerf=db.backref(‘students’,lazy=’dynamic’),
lazy=’dynamic’)

student的clsses屬性和class表建立relationship,
同時提供一個反向聲明, class表中的對象可以直接classe.students來篩選出選了該課的學生

flask中session操作

  • 增加 和更新

db.session.add(user)

db.session.commit()

  • 刪除

    db.session.delete(user)

    db.session.commit()

查詢方式

主鍵查詢
receive_user=User.query.filter_by(username=recepient).first_or_404()
receive_user=User.query.get_or_404(id)
其他條件查詢:
receive_user=User.query.filter_by(username=recepient).first()

多對多的關係

兩個表對一個輔助表建立外鍵索引,然後根據約束來查找
比如:
class 和student 再建立一張表:sdu_class, 表中的屬分別和兩個子表建立索引關係

具體實現

通過 兩個表建立relationship 同時在relationship中聲明secondary實現many to many

自引用

上面的學生和老師有兩個實體

如果是用戶和用戶之間,那麼只有一個關係。
一個實體之間的多對多稱爲自引用

給用戶添加兩個屬性
follower和followed

要額外儲存兩個實體間的額外信息,比如關注者的關注日期

建立一個新的表,同時在user中添加,followed和follwer 和follow表建立自引用

lazy

lazy決定了什麼時候從數據庫中加載數據
lazy的三個參數
dynamic joined select
dynamic 應該是relationship被調用時返回一個query()對象
joined relationship被調用時返回兩個表join的結果值
select 是訪問到屬性時,會加載全部的屬性。

backref

第一個字段是表的名稱,第二個字段是給第一個字段表中調用的別名

post=db.relationship(‘Post’,backref=’author’,lazy=’dynamic)

backref提供反向聲明
user和post形成一對多的關係,一個user可以生產多個post
Post在找user時可以根據author直接找到,而不需要再根據author_id在User中查找

back_populates

和backref的不同點,在於back_populates是顯式聲明瞭關係的應用

版本遷移 遷移腳本中的函數

  • current 查看當前版本的信息
  • upgrade upgrade() 函數把遷移中的改動應用到數據庫中
  • downgrade() 函數則將改動 刪除。

回退

數據庫根據 migrations 回退的方法

downgrade後刪除一個版本的函數就好

  • 增加用戶
    db.session.add(user)

db shell

from app.models import *

Role.insert_roles()

date

date.utcnow 沒有括號,default可以接受函數作爲參數

連接mysql

dir=mysql://root@localhost:3306/hello_flask?charset=utf8mb4


解決bug

  • 配置名必須大寫…
  • TypeError: init() takes at most 2 arguments (3 given) form表格中沒有添加路徑

  • 書中的bug
    在User model中的is_following(user)方法中,檢查當前用戶是否關注了user用戶,應該用self.followed.filter_by(follower=user)
    self.followed爲current_user關注的所有人的集合,在這個集合中,所有的followed項都爲current_user,所有的follower項爲各個被關注的用戶,所以要找出是否關注了某個用戶,應該是,
    self.followed.filter_by(follower=user)

View

bootstrap

限制了內容的長度

jinjia

safe 標籤,告訴jinjia 不要轉義html標籤

問題

爲什麼在分頁篩選中得不到自己關注自己的那個結果
解決:在follower.html中設置一下。。

評論

一個文章有多個評論。屬於一對多關係
一個用戶能發表多個評論,然後文章可以有多個評論

在user和post中添加relationship和comment關聯

在文章的Index頁面每篇文章下顯示comment數量,
然後點擊可以進入查看post發表文章的主界面,
在主界面下有文章的所有評論,評論的發表時間以及,詳細日期

restful api

  • 因爲是無狀態的,又要經過客戶端驗證,所以用http-auth

進行httpie測試

http –json –auth [email protected]:cat GET http://127.0.0.1:5000/api/posts

g.current_user

g.current_user的初始化在before_request那裏

所以在請求api時會出現錯誤是因爲在初始化時沒有加入before_request()

http狀態碼

200 響應成功

201 創建成功

202 接受

301 Moved Permanently 永久的移動了

項目部署 和環境

https://icecola.herokuapp.com/ | https://git.heroku.com/icecola.git

運行

python hello.py runserver --host 0.0.0.0

連接數據庫:

musql :mysql://username:password@localhost/database

postgresql://username:password@localhost/database

sqlite : sqlite:///absolute/path/to/databse

部署gunicorn

將flask部署在5001端口上

gunicorn -b 0.0.0.0:5001 -w 4 manage:app

gunicorn -b localhost:5000 -w 4 hello_flask:app

supervisor 來部署gunicorn

supervisor 進程管理工具

~/django_1/VENV_flask/hello_flask

利用supervisor來監視進程,在進程死亡後拉起

sudo mkdir /etc/supervisor

sudo echo_supervisord_conf > /etc/supervisord.conf 生成配置文件

查看默認配置文件

查看supervisord是否在運行

ps aux | grep supervisord

echo_supervisord_conf

  • 啓動服務
supervisord -c /etc/supervisor/supervisord.conf
運行自己寫的配置文件:
supervisord -c /etc/supervisor/conf.d/hello_flask.conf


使用 supervisorctl

Supervisorctl 是 supervisord 的一個命令行客戶端工具,啓動時需要指定與 supervisord 使用同一份配置文件,否則與 supervisord 一樣按照順序查找配置文件。

進入客戶端

supervisorctl -c /etc/supervisord.conf
 supervisorctl -c /etc/supervisor/conf.d/hello_flask.conf
  • 進入之後

    • status 查看狀態
    • reread 重新啓動
    • restart program_name 重啓某個項目
    • stop all 停止所有
    • update 更新
  • 啓動某個進程

    supervisorctl starprogram_name

    重新加載

     supervisorctl reload

配置了http服務後的啓動 sudo supervisorctl -u chris -p 123

  • gunicorn直接啓動命令

     /home/ubuntu/django_1/VENV_flask/bin/gunicorn -b localhost:5000 -w 4 hello_flask:app

​conf文件的配置

[program:hello_flask ]

command=/home/ubuntu/django_1/VENV_flask/bin/gunicorn -b localhost:5000 -w 4 hello_flask:app

directory=/home/ubuntu/django_1/VENV_flask/hello_flask

user=ubuntu

autostart=true

autorestart=true

stopasgroup=true

killasgroup=true

stdout_logfile=/home/ubuntu/django_1/VENV_flask/hello_flask/log/out_log.log

stderr_logfile=/home/ubuntu/django_1/VENV_flask/hello_flask/log/err_log.log

[supervisord]

575報錯:

關聯到nginx
    location {
    # forward application requests to the gunicorn server  

    proxy_pass http://localhost:5000;

    proxy_redirect off;

    proxy_set_header Host $host;

    proxy_set_header X-Real-IP $remote_addr;

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

}

location /static {

    # handle static files directly, without forwarding to the application

    alias /home/ubuntu/django_1/VENV_flask/hello_flask/app/static;

    expires 30d;

}

# write access and error logs to /var/log

access_log /var/log/hello_flask_access.log;

error_log /var/log/hello_flask_error.log;
}

部署到heroku

登錄

heroku login

輸入在官網註冊的賬戶和 密碼

創建應用

heroku create 名字可以自己選

heroku create –buildpack heroku/python

Creating heroku-postgresql on ⬢ floating-ravine-41608… free
https://floating-ravine-41608.herokuapp.com/ | https://git.heroku.com/floating-ravine-41608.git

添加數據庫

heroku addons:create heroku-postgresql -a floating-ravine-41608

Database has been created and is available
! This database is empty. If upgrading, you can transfer
! data from another database with pg:copy
Created postgresql-parallel-90394 as DATABASE_URL
Use heroku addons:docs heroku-postgresql to view documentation

顯示git和網頁地址

git remote show heroku

進入數據庫

heroku pg:psql -a floating-ravine-41608

DATABASE_URL: postgres://xriuxrfpqtfmpj:f10a0a38f76e0e2be3bc52e69aa477d161736775976c93ce6e0470bce8c92d82@ec2-107-21-126-193.compute-1.amazonaws.com:5432/d9uqv1edl13ka8

如果運行git push heroku出錯,運行這步

heroku git:remote -a floating-ravine-41608

push上去 即可運行

git push heroku master

部署flask 需要的文件

runtime.txt 表示運行時的python環境
python-2.7.14
requirements.txt 用 pip freeze > requirements.txt 生成
Flask==0.10.1
Flask-SQLAlchemy==2.0
Flask-WTF==0.12
Jinja2==2.8
MarkupSafe==0.23
SQLAlchemy==1.0.8
WTForms==2.0.2
Werkzeug==0.10.4
click==4.1
decorator==4.0.2
geocoder==1.4.1
gunicorn==19.3.0
itsdangerous==0.24
psycopg2==2.7.3.1
ratelim==0.1.6
requests==2.7.0
six==1.9.0
wsgiref==0.1.2
Procfile 顯示路由的app和 運行的服務器
web: gunicorn routes:app
.env.env 配置環境變量 ,heroku會直接從這裏讀取
FLASK_APP=flasky.py
FLASK_CONFIG=heroku
MAIL_USERNAME=fjl2401
MAIL_PASSWORD=youpass

添加後臺任務

在views中用current_user來調用,實現跳轉到models的方法

用rq來處理,在models.user中定義launch方法,實現跳轉到current_app的隊列

然後通過rq_job這個名字自動加入到消息隊列中,任務的名稱爲name+user.id

在app的init中 任務隊列初始化,連接到redis服務器

在當前目錄下找tasks這個文件,然後根據 views傳進來的名稱來定位到對於的目錄下的py文件的函數名,

運行對應的函數。

在指定name任務隊列中分配worker,保證該任務隊列有worker

然後實例化一個隊列對象

queue = rq.Queue(‘new_work’, connection=Redis.from_url(‘redis://’))

將方法添加到隊列生成job

job = queue.enqueue(‘app.tasks.example’, 23)

rabbit-rmq

地址

http://localhost:15672/

用戶名和密碼 guest

啓動: ./rabbitmq-server

ps -ef|grep rabbit

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章