Python虛擬環(huán)境
python虛擬環(huán)境是為了解決電腦上存在一個框架的多個版本悉盆,使用虛擬環(huán)境解決這個問題
通過pip命令安裝虛擬環(huán)境:
pip3 install virtualenv
- 開辟新的虛擬環(huán)境:
/** [virtualenv-name] */ 是盒子的名字
virtualenv [virtualenv-name]
- 激活虛擬環(huán)境
- mac下激活虛擬環(huán)境命令:
source ~/Virtualenv/flask-env/bin/activate
- 退出虛擬環(huán)境 deactivate
- mac下激活虛擬環(huán)境命令:
安裝flask框架
- 需要在虛擬環(huán)境中安裝flask框架
(flask-env) Liu:flask-env liuzhanjun$ pip3 install flask
- 查看flask是否安裝成功
Flask
- flask入口詳解
#encoding: utf-8
from flask import Flask
app = Flask(__name__)
# @app.route 是一個裝飾器
# @開頭,并且在函數(shù)的上面馋吗,說明是裝飾器
# 這個裝飾器的左右焕盟, 是做一個url與試圖函數(shù)的映射
@app.route('/My_name/<string:name>')
def My_name(name):
return 'My name is: {}'.format(name)
# 入口程序
if __name__ == '__main__':
# 類似While True:一樣一直在監(jiān)聽
# 可以填寫參數(shù), 接收用戶信息的請求
app.run()
- 設置debug模式:
- 在app.run()中傳入一個關鍵字參數(shù)debug, app.run(debug=True)宏粤,就設置了當前項目為debug模式
2.debug模式的兩大功能:
- 當程序出現(xiàn)問題的時候脚翘, 可以在頁面中看到錯誤信息和出錯的位置弱匪。
- 只要修改了項目中的
python
文件翩瓜,不需要手動重新啟動服務器。
- 設置配置文件
1.新建一個
configLogic.py
文件
2.在住app文件到導入這個文件, 并且配置到app
中乘盼, 示例代碼如下:
import configLogic
app.config.from_object(configLogic)
3.還有許多的其他參數(shù)崇堰, 都是放置在這個配置文件中的沃于,比如
SECRET_KEY
和SQLALCHEMY
這些配置,都是在這個文件中的
- URL參數(shù)
1.參數(shù)的作用: 可以在相同的URL海诲,但是置頂不同的參宿繁莹, 來加載不同的數(shù)據(jù)。
2.在flask中如何使用參數(shù):
# 參數(shù)需要寫在 `<>` 中
# 視圖函數(shù)中需要放和url參數(shù)同名的參數(shù)
@app.route('/My_name/<string:name>')
def My_name(name):
return 'My name is: {}'.format(name)
- 反轉url
- 什么叫做反轉URL: 從視圖函數(shù)到url的轉換叫做反轉URL
- 反轉url的用處:
2.1在頁面重定向的時候特幔,會使用url反轉
2.2在模板中咨演,也會使用url反轉
頁面跳轉和重定向
1.用處: 在用戶訪問一些需要登錄的頁面的時候,如果用戶沒有登錄蚯斯, 那么可以讓它重定向到登錄頁面
2.代碼實現(xiàn):
#encoding: utf-8
from flask import Flask,redirect,url_for
app = Flask(__name__)
@app.route('/')
def hello_world():
# 使用url_for進行反轉的話薄风, 不論@app.route('/login/')中的/login/怎么改變零院,都不會印象到反轉的結果
# 使用url進行反轉時, url_for('接口函數(shù)名')村刨,直接調用接口函數(shù)告抄, 防止接口中參數(shù)改變影響請求結果
# login_url = url_for('login')
# return redirect(login_url)
return u'這是首頁'
@app.route('/login/')
def login():
return '這是登錄頁面'
@app.route('/requestion/<is_login>')
def requestion(is_login):
if is_login == '1' :
return '這是問答頁面'
else:
# 根據(jù)用戶傳來的參數(shù)重定向到login登錄頁面, 里邊使用是url反轉
return redirect(url_for('login'))
# 入口程序
if __name__ == '__main__':
app.run(debug=True, host='127.0.0.1',port=8080)
- Flask渲染Jinja2模板和傳值
- 如何渲染模板:
- 模板放在
templates
文件夾下- 從
flask
中導入render_template
函數(shù)- 在視圖函數(shù)中嵌牺,使用
render_template
函數(shù)打洼,渲染模板,注意:只需要填寫模板的名字逆粹,不需要填寫templates
這個文件夾的路徑募疮。
2.模板傳參:
- 如果只有一個或者少量參數(shù),直接在
render_template
函數(shù)中添加關鍵字參數(shù)就可以了- 如果有多個參數(shù)的時候僻弹, 那么可以先把所有的參數(shù)放到字典中阿浓, 然后在
render_template
中,使用兩個星號**
蹋绽,把字典轉換成關鍵字參數(shù)傳遞進去芭毙, 這樣的代碼更方便管理和使用。
3.在模板中卸耘, 如果要使用一個變量退敦, 語法是
{{ parms }}
4.訪問模型中的屬性或者是字典,可以通過{{params.property}}
的形式, 或者是使用{{params[‘a(chǎn)ge’]}}
, 示例代碼:
# 1.接口中定義好需要調用的模型Person類
@app.route('/')
def index():
class Person(object):
name = u'劉戰(zhàn)軍'
age = 25
p = Person()
context = {'username':'劉戰(zhàn)軍',
'age':18, 'sex':'男',
'friend': '王磊',
'person': p,
'websties': {
'baidu': 'www.baidu.com',
'google': 'www.google.com'
}
}
return render_template('index.html', **context)
# 2.模板中調用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
這是HTML種出現(xiàn)的文字
<p>姓名: {{ username }}</p>
<p>性別: {{ sex }}</p>
<p>年齡: {{ age }}</p>
<p>朋友: {{ friend }}</p>
<hr>
<p>名字: {{ person.name }}</p>
<p>名字: {{ person.age }}</p>
<hr>
<p>名字: {{ websties.baidu }}</p>
<p>名字: {{ websties.google }}</p>
</body>
</html>
- if判斷
1.語法:
{% if userInfo %}
<a href="#">{{userInfo.username}}</a>
<a href="#">注銷</a>
{% else %}
<a href="#">登錄</a>
<a href="#">注冊</a>
{% endif %}
2.if的使用蚣抗, 可以和python中相差無幾
3.在模板中使用if語句的時候注意
#encoding: utf-8
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/<is_login>/')
def index(is_login):
# 用戶使用傳值也需要注意侈百, 這里的`1`的類型
if is_login == '1' :
print('登錄狀態(tài)')
userInfo = {
'username': '劉戰(zhàn)軍',
'age': 18
}
websites = ['www.baidu.com', 'www.google.com']
return render_template('index_for.html', userInfo=userInfo, websites=websites) # 注意: 模板中需要獲取當前這個信息的話,必須使用這種方式傳值
else :
print('未登錄狀態(tài)')
return render_template('if_statement.html')
# 入口程序
if __name__ == '__main__':
app.run(debug=True, host='127.0.0.1',port=8081)
- for 的使用
- 字典的遍歷翰铡, 語法和
python
一樣钝域, 可以使用items()
、keys()
锭魔、values()
例证、iteritems()
、iterkeys()
赂毯、itrervalues()
{% for k,v in userInfo.items() %}
<p>{{ k }} : {{ v }}</p>
{% endfor %}
2.列表的遍歷: 語法和
python
一樣
{% for website in websites %}
<p>{{ website }}</p>
{% endfor %}
- 過濾器
過濾的對象是模板中的變量
- 語法:
- 介紹: 過濾器可以處理變量战虏, 把原始的變量經(jīng)過處理后再展示出來。 作用的對象是變量党涕。
- 語法:
default過濾器
{{ avatar|default('xxxxx') }}
2.default過濾器: 如果當前的變量不存在烦感,這時候可以指定默認值。
3.len過濾器:作為求列表膛堤、字符串手趣、字典、元組的長度。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<!--這里使用的是default()過濾器绿渣,可以作為placeholder使用-->
<img src="{{ avatar|default('http://upload.jianshu.io/users/upload_avatars/2542851/0dca220dd6bb.jpeg?imageMogr2/auto-orient/strip|imageView2/1/w/64/h/64') }}" alt="">
<hr>
<!--這里使用的是length過濾器朝群,可以作為求列表、字符串中符、字典姜胖、元組的長度-->
<p>評論數(shù): ({{ coments| length }})</p>
<ul>
{% for coment in coments %}
<li>
<a href="#">{{ coment.user }}</a>
<p>{{ coment.content }}</p>
</li>
{% endfor %}
</ul>
</body>
</html>
- 繼承和block
1.集成的作用和語法:
- 作用:可以吧一些公共的代碼都放在父模板中,避免每個模板寫同樣的代碼淀散。
- 代碼:{% extends 'index_base.html' %}
- block實現(xiàn):
- 作用:可以讓子模板實現(xiàn)一些自己的需求右莱,父模板需要提前定義好。
- 注意點:子模板中的代碼档插, 不許放在
block
塊中慢蜓。
- url鏈接
使用
url_for(試圖函數(shù)名稱)
可以翻轉成url
#encoding: utf-8
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def index():
return render_template('index_url.html')
@app.route('/login/')
def login():
return render_template('index_login.html')
# 入口程序
if __name__ == '__main__':
app.run(debug=True,host='127.0.0.1',port=8081)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<a href="{{ url_for('login') }}" id="">登錄</a>
</body>
</html>
- 加載靜態(tài)文件
1.語法:
url_for('static',filename='路徑')
2.靜態(tài)文件,flask會從static
文件夾中開始尋找郭膛,所以不需要再寫static
這個路徑了晨抡。
3.可以加載css
文件,可以加載js
文件则剃,還有images
資源等文件耘柱。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{{ url_for('static',filename='css/index.css') }}">
<script src="{{ url_for('static',filename='js/index.js') }}"></script>
</head>
<body>
<a href="{{ url_for('login') }}">登錄</a>
<img src="{{ url_for('static',filename='images/gonggao.png') }}" alt="">
</body>
</html>
SQLAIchemy數(shù)據(jù)庫
mysql mac安裝只需要到mysql官網(wǎng)下載進行安裝, 安裝步驟忍级,這里不贅述帆谍, 百度一大堆
Flask-SQLAlchemy介紹與安裝:
- ORM: Object Relationship Mapping(模型關系映射)
- flask-sqlalchemy是一套ORM框架
3.ORM的好處:可以讓我們操作數(shù)據(jù)庫跟操作對象一樣,非常方便轴咱。因為一個表就抽象成一個類, 一條數(shù)據(jù)就抽象成該類的一個對象烈涮。
4.安裝
flask-sqlalchemy
:sudo pip3 install flask-sqlalchemy
朴肺。
- Flask-SQLAlchemy的使用:
- 初始化和設置數(shù)據(jù)庫配置信息:
設置配置信息: 在config.py
文件中添加一下配置信息:
# encoding: utf-8
# dialect+driver:/username:password@host:prot/database
DIALECT = 'mysql'
DRIVER = 'mysqldb'
USERNAME = 'root'
PASSWORD = 'root'
HOST = '127.0.0.1'
PORT = '3306' # mysql自帶端口號
DATABASE =
2.沒有DATABASE需要創(chuàng)建一個
Last login: Sun Nov 19 17:10:14 on ttys002
# 打開數(shù)據(jù)庫
Liu:~ liuzhanjun$ mysql -uroot -p
Enter password: # 輸入密碼
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 498
Server version: 5.7.20 MySQL Community Server (GPL)
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
# 創(chuàng)建db_demoFrist指令:create database db_demoFrist charset utf8;
mysql> create database db_demoFrist charset utf8;
Query OK, 1 row affected (0.01 sec)
mysql>
3.初始化和設置數(shù)據(jù)庫配置信息:
- 使用flask——sqlalchemy中的SQLAlchemy進行初始化:
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# 鏈接數(shù)據(jù)庫配置信息
app.config.from_object(config)
# 初始化SQLAlchemy對象
db = SQLAlchemy(app)
4.在主
app
文件中, 添加配置文件:
import config
app = Flask(__name__)
# 鏈接數(shù)據(jù)庫配置信息 (暫時不會使用添加其他config配置文件方式)
# app.config.from_object(config)
# 這里登陸的是root用戶坚洽,要填上自己的密碼戈稿,MySQL的默認端口是3306,填上之前創(chuàng)建的數(shù)據(jù)庫名jianshu,連接方式參考 \
app.config['SQLALCHEMY_DATABASE_URI']='mysql+pymysql://root:root@127.0.0.1:3306/db_demo6'
#設置這一項是每次請求結束后都會自動提交數(shù)據(jù)庫中的變動
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN']=True
# 初始化SQLAlchemy對象
db = SQLAlchemy(app)
5.做測試讶舰,看有沒有問題:
# 測試數(shù)據(jù)庫用戶名密碼是否正確
db.create_all()
如果沒有報錯鞍盗, 說明配置信息沒有問題, 如果報錯跳昼, 根據(jù)錯誤進行更改
使用Flask-SQLAlchemy創(chuàng)建模型與表的映射:
- 模型需要繼承自
db.Model
般甲, 然后需要映射到表中的屬性,必須寫成db.Column
的數(shù)據(jù)類型鹅颊。參考如下圖
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import config
app = Flask(__name__)
# 鏈接數(shù)據(jù)庫配置信息(暫時不會使用配置文件方式進行配置數(shù)據(jù)庫信息)
# app.config.from_object(config)
# 這里登陸的是root用戶敷存,要填上自己的密碼,MySQL的默認端口是3306堪伍,填上之前創(chuàng)建的數(shù)據(jù)庫名jianshu,連接方式參考 \
app.config['SQLALCHEMY_DATABASE_URI']='mysql+pymysql://root:root@127.0.0.1:3306/db_demo6'
#設置這一項是每次請求結束后都會自動提交數(shù)據(jù)庫中的變動
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN']=True
# 初始化SQLAlchemy對象
db = SQLAlchemy(app)
# # 測試數(shù)據(jù)庫用戶名密碼是否正確
# db.create_all()
# creat table article (
# id int primary key autoincrement, # 自增長的一個之, primary 作為主鍵使用
# title varchar(100) not null, # 最長字符為100锚烦, 并且不能為空
# content text not null
# )
class Article(db.Model):
# 定義表名
__tablename__ = 'article'
# 定義列對象
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(100), nullable=False)
content = db.Column(db.Text, nullable=False)
# repr()方法顯示一個可讀字符串觅闽,雖然不是完全必要,不過用于調試和測試還是很不錯的涮俄。
# def __repr__(self):
# return '<Article {}> '.format(self.title)
# 映射到數(shù)據(jù)庫中 `這個方法只會映射到數(shù)據(jù)庫一次蛉拙,再次創(chuàng)建新的數(shù)據(jù)不會進行存儲`6
db.create_all()
@app.route('/')
def index():
return 'index'
if __name__ == '__main__':
app.run(debug=True)
查詢數(shù)據(jù)庫指令以及查詢時常見的問題
打開庫:
use 數(shù)據(jù)庫名;
1. 查詢數(shù)據(jù)庫表:
show tables;
例如:
mysql> show tables;
2. 查詢數(shù)據(jù)表內容:
desc 表名;
例如:
mysql> desc article;
常見問題: 在打開數(shù)據(jù)庫時提示重新設置密碼的問題
1820 (HY000): You must reset your password using ALTER USER statement before executing this statement
解決方式:
mysql> SET PASSWORD = PASSWORD('root這里需要輸入新密碼');
-
數(shù)據(jù)類型:
-
其他參數(shù):
-
primary_key
: 代表的是將這個字段設置為主鍵 -
autoincrement
: 代表的是這個主鍵為自增長的彻亲。 -
nullable
: 代表的是這個字段是否可以為空刘离,默認可以為空《闷埽可以將這個值設置為False
硫惕, 在數(shù)據(jù)庫中,這個值就不能為空了野来。 - 最后需要調用
db.create_all
來將模型真正的創(chuàng)建到數(shù)據(jù)庫中恼除。
-
Flask-SQLAlchemy 數(shù)據(jù)的增、刪曼氛、改豁辉、查;
數(shù)據(jù)的增刪改查都是db的session來進行操作舀患;
不論做增刪改查操作都需要進行事務的處理db.session.commit()來操作徽级;
- 增:
@app.route('/')
def hello_world():
# 增加數(shù)據(jù)
article1 = Article(title='aaa',content='bbb')
db.session.add(article1)
# 存儲數(shù)據(jù)
db.session.commit()
return 'Hello World!'
- 查:
* 查詢:
article1 = Article.query.filter(Article.title == 'aaa')
print('article1 = {}'.format(article1))
* 結果:
article1 = SELECT article.id AS article_id, article.title AS article_title, article.content AS article_content
FROM article
WHERE article.title = %(title_1)s
* 查詢:
article1 = Article.query.filter(Article.title == 'aaa').first()
print('article1 = {}'.format(article1))
print('title = {}'.format(article1.title))
print('content = {}'.format(article1.content))
* 結果:
article1 = <Article 1>
title = aaa
content = bbb
- 改:
# 3.1 先把你需要更改的數(shù)據(jù)查找出來
article1 = Article.query.filter(Article.title == 'aaa').first()
# 3.2 把這條數(shù)據(jù), 你需要修改的地方進行修改
article1.title = 'news title'
# 3.3 做事務的提交
db.session.commit()
- 刪:
# 4.1 先把你需要刪除的數(shù)據(jù)查找出來
article1 = Article.query.filter(Article.content == 'bbb').first()
# 4.2 刪除數(shù)據(jù)
db.session.delete(article1)
# 4.3 做事務提交
db.session.commit()
Flask-SQLAlchemy外鍵及其關系:
- 外鍵:
class User(db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(100), nullable=False)
class Article(db.Model):
__tablename__ = 'article'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(100), nullable=False)
content = db.Column(db.Text, nullable=False)
# 如果要使用【外鍵】進行鏈表查詢聊浅, db.Column中第一個參數(shù)必須和需要鏈接的另一個字段類型保持一致餐抢,第二個參數(shù)是使用db.ForeignKey()函數(shù)進行表名加字段的鏈接
author_id = db.Column(db.Integer, db.ForeignKey('user.id'))
-
author = db.relationship('User', backref = db.backref('articles'))
解釋:- 給
Article
這個模型添加一個author
屬性, 可以訪問這篇文章的作者的數(shù)據(jù)低匙, 像訪問普通模型一樣旷痕。 -
backref
是定義反向引用, 可以通過User
訪問這個模型寫的所有文章顽冶。
- 給
class Article(db.Model):
__tablename__ = 'article'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(100), nullable=False)
content = db.Column(db.Text, nullable=False)
# 如果要進行鏈表查詢欺抗, db.Column中第一個參數(shù)必須和需要鏈接的另一個字段類型保持一致,第二個參數(shù)是使用db.ForeignKey()函數(shù)進行表名加字段的鏈接
author_id = db.Column(db.Integer, db.ForeignKey('user.id'))
# 添加author屬性强重, 通過relationship這種方式可以直接訪問User模型中的屬性绞呈。
author = db.relationship('User', backref = db.backref('articles'))
@app.route('/')
def index():
# user = User(username = 'liuzhanjun')
# db.session.add(user)
# db.session.commit()
# article = Article(title = 'shuihu', content = 'shuihuzhuan')
# article.author = User.query.filter(User.id == 1).first()
# db.session.add(article)
# db.session.commit()
# 根據(jù)標題為sanguo的找作者是的名字
# article = Article.query.filter(Article.title == 'sanguo').first()
# print('username: {}'.format(article.author.username))
# 根據(jù)作者,查找作者寫的所有文章
user = User.query.filter(User.username == 'liuzhanjun').first()
result = user.articles
for article in result:
print('-'*10)
print(article.title)
return 'index'
- 前面是一對多的關系间景, 多對多關系如下:
- 1.多對多的關系要通過一個中間表進行關聯(lián)佃声。
- 2.中間表, 不能通過
class
的方式實現(xiàn)拱燃, 只能通過db.Table
的方式實現(xiàn)秉溉。 - 3.設置關聯(lián):
article_tag = db.Table('article_tag',
db.Column('article_id', db.Integer, db.ForeignKey('article.id'), primary_key=True),
db.Column('tag_id', db.Integer, db.ForeignKey('tag.id'), primary_key=True)
)
class Article(db.Model):
__tablename__ = 'article'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
title = db.Column(db.String(100), nullable=False)
# 第一個參數(shù)是需要關聯(lián)的模型名稱, 第二參數(shù)為鏈接的模型名稱(橋接), 第三個參數(shù)是方向參照
tags = db.relationship('Tag', secondary = article_tag, backref = db.backref('tags'))
class Tag(db.Model):
__tablename__ = 'tag'
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
name = db.Column(db.String(100), nullable=False)
注意: 需要使用一個關鍵字參數(shù)secondary = 中間表
來進行關聯(lián)召嘶。
- 訪問和數(shù)據(jù)添加可以通過以下方式進行操作:
- 添加數(shù)據(jù)
- 訪問和數(shù)據(jù)添加可以通過以下方式進行操作:
article1 = Article(title = "honglou")
article2 = Article(title="xiyou")
tag1 = Tag(name = "link-honglou")
tag2 = Tag(name="link-xiyou")
db.session.add(article1)
db.session.add(article2)
db.session.add(tag1)
db.session.add(tag2)
article1.tags.append(tag1)
article1.tags.append(tag2)
article2.tags.append(tag1)
article2.tags.append(tag2)
db.session.commit()
- 訪問數(shù)據(jù)
article1 = Article.query.filter(Article.title == 'xiyou').first()
tags = article1.tags
print(article1.tags)
for tag in tags:
print('link-name: {}'.format(tag.name))
Flask-Script的介紹與安裝:
- Flask-Script: Flask-Script的作用是可以通過命令行的形式來操作Flask父晶,例如通過命令跑一個開發(fā)版本的服務器、設置數(shù)據(jù)庫弄跌、定時任務等甲喝。
- 安裝:首先進入到虛擬環(huán)境中, 然后
pip3 install flask-script
來進行安裝铛只。 - 如果直接在主
manage.py
中寫命令埠胖, 那么在終端就只需要python3 manage.py command_name
就可以了。 - 如果把一些命令集中在一個文件中淳玩,那么在終端中就需要輸入一個命令直撤,比如
python3 manage.py db init
。 - 例子:
from flask_script import Manager
from Test_Script_demo import app
from db_scripts import DBManager
# 要初始化manager就需要使用到Flask框架
manage = Manager(app)
# 和數(shù)據(jù)庫相關的操作蜕着,我都放在一起
@manage.command
def runserver():
print("服務器已經(jīng)運行起來了D笔!承匣!")
# 終端運行結果:
# $ python3 manage.py runserver
# 服務器已經(jīng)運行起來了1统恕!
# 將DBManager中的命令全部引用到當前的manager的命令中
# db:使用命令時的前綴韧骗, DBManager添加的命令
manage.add_command('db',DBManager)
# 終端運行結果:
# $ python3 manage.py db init
# 數(shù)據(jù)庫已經(jīng)初始化完畢
if __name__ == '__main__':
manage.run()
- 有子命令的例子:
from flask_script import Manager
# 因為這里不需要直接運行這個管理類嘉抒, 所以不需要傳app進去
DBManager = Manager()
@DBManager.command
def init():
print('數(shù)據(jù)庫已經(jīng)初始化完畢')
@DBManager.command
def migrate():
print('數(shù)據(jù)表遷移成功')
終端命令調用方式:
localhost:~ liuzhanjun$ cd /Users/tangwenbin/Desktop/個人/python項目/Test_Script_demo
localhost:Test_Script_demo liuzhanjun$ python3 manage.py runserver
服務器已經(jīng)運行起來了!E郾些侍!
localhost:Test_Script_demo liuzhanjun$ python3 manage.py db init
數(shù)據(jù)庫已經(jīng)初始化完畢
localhost:Test_Script_demo liuzhanjun$ python3 manage.py db migrate
數(shù)據(jù)表遷移成功
localhost:Test_Script_demo liuzhanjun$
分開Models
和解決循環(huán)引用:
- 分開model的目的:為了讓代碼更加方便管理。
2.如何解決循環(huán)引用:把db
放在一個單獨文件中容诬,切斷循環(huán)引用的線條就可以了娩梨。
服務器沙箱操作:
- 我們雖然創(chuàng)建了一個新的app但是沒有吧app放到需要渲染的棧里面去, 需要手動置頂當前要進入到棧里的app是哪一個:
# 指定當前的app需要進行入棧操作
with app.app_context():
db.create_all()
Flask-Migrate的介紹與安裝:
- 介紹: 因為采用
db.create_all
在后期修改字段的時候览徒,不會自動的映射到數(shù)據(jù)庫中,必須刪除表颂龙,然后重新運行db.create_all
才會重新映射习蓬,這樣不符合我們的要求,因此flask-migrate
就是為了解決這個問題措嵌,它可以在每次修改模型后躲叼,可以將修改的東西映射到數(shù)據(jù)庫中。 - 首先進入到你的虛擬環(huán)境中企巢,然后使用
pip3 install flask-migrate
進行安裝就可以了枫慷。 - 使用
flask-migrate
必須借助flsk-scripts
,這個包的MigrateCommand
中包含了所有和數(shù)據(jù)庫相關的命令。 -
flask-migrarte
相關的命令:-
python3 manage.py db init
: 初始化一個遷移腳本的環(huán)境或听,只需要執(zhí)行一次 -
python3 manage.py db migrate
:將模型生成遷移文件探孝,只要模型更改了,就需要執(zhí)行一遍這個命令誉裆。 -
python3 manage.py db upgrade
: 將秦阿姨文件真正映射到數(shù)據(jù)庫中顿颅,每次運行了migrate
命令后, 就需要運行這個命令足丢。
-
- 注意點: 需要將你想要映射到數(shù)據(jù)庫中的模型, 例如:
from models import Article
粱腻,都要導入到manage.py
文件中,如果沒有導入進去斩跌,就不會映射到數(shù)據(jù)庫中绍些。
from flask_script import Manager
from migrate_demo import app
from flask_migrate import Migrate, MigrateCommand
from exts import db
from models import Article
# init
# migrate
# upgrade
# 模型 -> 遷移文件 -> 表
manager = Manager(app)
# 1. 要使用flask-migrate,必須綁定app和db
migrate = Migrate(app, db)
# 2. 把MigrateCommand命令添加到manager中
manager.add_command("db", MigrateCommand)
if __name__ == '__main__':
manager.run()
cookie:
-
cookie
出現(xiàn)的原因:在網(wǎng)站中耀鸦,http請求是無狀態(tài)的柬批。也就是說及時第一次和服務器連接后并且登錄成功后,第二次請求服務器依然不能知道當前請求時哪個用戶揭糕,cookie的出現(xiàn)就是為了解決這個問題萝快,第一次登錄后服務器返回一些數(shù)據(jù)(cookie)給瀏覽器,然后瀏覽器保存在本地著角,當用戶已發(fā)送第二次請求的時候揪漩, 就會自動的把上次請求存儲的cookie數(shù)據(jù)自動的攜帶給服務器,服務器通過瀏覽器攜帶的數(shù)據(jù)就能判斷當前是哪個了吏口。 - 如果服務器返回了
cookie
給瀏覽器奄容,那么瀏覽器下次再次請求相同的服務器的時候, 就會自動把cookie
發(fā)送給瀏覽器产徊,這個過程用戶根本不需要管昂勒。 -
cookie
是保存在瀏覽器中的,相對的是瀏覽器
session:
-
session
介紹:session和cookie的作用有點類似舟铜,都是為了存儲用戶相關的信息戈盈。不同的是,cookie是存儲在本地瀏覽器谆刨,而session存儲在服務器塘娶。存儲在服務器的數(shù)據(jù)會更加的安全,不容易被竊取痊夭,但存儲在服務器也有一定的弊端刁岸, 就是會占用服務器的資源, 但現(xiàn)在服務器已經(jīng)發(fā)展至今她我,一些session信息還是綽綽有余的虹曙。 - 使用
session
的好處:
- 銘感數(shù)據(jù)不是直接發(fā)送回給瀏覽器迫横,而是發(fā)送回一個
session_id
,服務器將session_id
和銘感數(shù)據(jù)做一個映射存儲在session
(在服務器上面)中酝碳,更加安全矾踱。 -
session
可以設置過期時間,也從另外一方面击敌,保證了用戶的賬號安全介返。
flask中的session工作機制:
- flask中的session機制是: 把銘感數(shù)據(jù)經(jīng)過加密后放入
session
中, 然后再把session
存放到cookie
中沃斤,下次請求的時候圣蝎, 再從瀏覽器發(fā)送過來的cookie
中讀取session
,然后再從session
中讀取敏感數(shù)據(jù)衡瓶,并進行解密徘公,獲取最終的用戶數(shù)據(jù)。 - flask的這種
session
機制哮针,可以節(jié)省服務器的開銷关面,因為把所有的信息都存儲到了客戶端(瀏覽器)。 - 安全是相對的十厢,把
session
放到cookie
中等太,經(jīng)過加密, 也是比較安全的蛮放。