一、Flask數據庫操作
django中使用ORM連接操作數據庫,如果不使用數據庫,將會失去站點管理的功能。
python使用pymysql連接操作數據庫,flask中也可以使用pymysql連接。
sqlalchemy:python的開源數據庫框架
(一)flask-sqlalchemy
對sqlalchemy進行封裝
安裝
pip install flask-sqlalchemy
pip install pymysql
官方配置文檔:
http://www.pythondoc.com/flask-sqlalchemy/config.html#uil
使用
1.連接數據庫
sqlite
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import os
app = Flask(__name__)
# 學習sqlalchemy
# 連接數據庫
# app.config:類字典
print(__file__) # E:/第三階段/FlaskDemo/project/ORMtest.py
print(os.path.dirname(__file__)) # E:/第三階段/FlaskDemo/project
BASE_DIR = os.path.abspath(os.path.dirname(__file__)) # 當前文件,項目所在的根目錄
app.config['SQLALCHEMY_DATABASE_URI']='sqlite:///'+os.path.join(BASE_DIR,'test.db') # 連接sqlite3
print(app.config['SQLALCHEMY_DATABASE_URI'])
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True # 請求結束之後自動提交
app.config['SQLALCHEMY_RTACK_MODIFICATIONS'] = True # 跟蹤修改,flask 1.x之後增加的配置項
db = SQLAlchemy(app) # 創建對象,綁定flask項目
# 創建模型
class UserInfo(db.Model):
__tablename__ = 'userinfo'
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(32))
time = db.Column(db.DATETIME)
# 數據遷移
db.create_all() # 同步表結構
@app.route('/')
def index():
return 'ORMtest'
if __name__ == '__main__':
app.run()
mysql
2.創建模型
字段類型:
字符串:String(32),text
數字:Integer,Float
日期:DATE,DATETIME
字段屬性:
primary_key
autoincrement
nullable
unique
dafault
DATETIME默認當前時間:
from datetime import datetime
default=datetime.now()
create_all()同步表結構
- 表結構沒發生變化,再次執行不會報錯
- 修改模型屬性,不同步表結構
- 增加模型,同步表
數據遷移的應用
- django中,要使用數據遷移
- flask中可用可不用create_all()
- 用
- 少見
- 不用
- 先創建表和表結構
- 創建模型,進行映射
- 用
3.操作數據庫
-
增加
-
增加單條數據
-
增加多條數據
-
-
查詢
-
all():返回所有數據,列表類型
-
get():只能通過id進行查詢(直接寫id值或ident=xxx),不存在返回None
-
filter()和filter_by():過濾
-
first():獲取符合條件的第一條數據,不存在返回None
-
order_by():排序
-
分頁
-
-
修改
-
marge()
-
-
刪除
-
delete()
-
(二)數據庫封裝
# 基類
class BascModel(db.Model):
__abstract__ = True # 聲明當前類爲抽象類,會被繼承調用,不會被創建
id = db.Column(db.Integer,primary_key=True)
def save(self):
db.session.add(self)
db.session.commit()
def merge(self):
db.session.merge(self)
db.session.commit()
def delete(self):
db.session.delete(self)
db.session.commit()
# 繼承基類
class UserInfo(BascModel):
__tablename__ = 'userinfo'
# id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(32))
age = db.Column(db.Integer,default=1)
time = db.Column(db.DATETIME,default=datetime.now())
class User(BascModel):
__tablename__='user'
# id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(32))
phone = db.Column(db.String(11))
# 利用基類的方法操作數據庫
# 增加數據
userinfo = UserInfo(name='wo',age=99)
userinfo.save()
# 修改數據
userinfo = UserInfo.query.get(8)
userinfo.name='wowowo'
userinfo.merge()
# 刪除數據
userinfo = UserInfo.query.get(8)
userinfo.delete()
二、Flask項目目錄優化
上面的代碼,將視圖和模型寫在了一個文件當中。Flask是遵循MVC的解耦合的設計模式,應當把它們分開。
創建main.py–配置
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import os
import pymysql
pymysql.install_as_MySQLdb()
app = Flask(__name__)
BASE_DIR = os.path.abspath(os.path.dirname(__file__)) # 當前文件,項目所在的根目錄
# app.config['SQLALCHEMY_DATABASE_URI']='sqlite:///'+os.path.join(BASE_DIR,'test.db') # 連接sqlite3
app.config['SQLALCHEMY_DATABASE_URI']='mysql://root:181818@localhost/flask' # 連接mysql
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True # 請求結束之後自動提交
app.config['SQLALCHEMY_RTACK_MODIFICATIONS'] = True # 跟蹤修改,flask 1.x之後增加的配置項
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app) # 創建對象,綁定flask項目
創建views.py–視圖
from flask import render_template
from main import app
from date import MyDate
@app.route('/index/')
def index():
return render_template('index.html')
@app.route('/userinfo/')
def userinfo():
obj = MyDate()
result = obj.get_date()
n = len(result)
return render_template('userinfo.html',**locals())
創建models.py–模型
from datetime import datetime
from main import db
class BascModel(db.Model):
__abstract__ = True # 聲明當前類爲抽象類,會被繼承調用,不會被創建
id = db.Column(db.Integer,primary_key=True)
def save(self):
db.session.add(self)
db.session.commit()
def merge(self):
db.session.merge(self)
db.session.commit()
def delete(self):
db.session.delete(self)
db.session.commit()
class UserInfo(BascModel):
__tablename__ = 'userinfo'
# id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(32))
age = db.Column(db.Integer,default=1)
time = db.Column(db.DATETIME,default=datetime.now())
class User(BascModel):
__tablename__='user'
# id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(32))
phone = db.Column(db.String(11))
創建manage.py–項目管理文件
# 項目的管理文件
import sys
from views import *
from models import *
comment = sys.argv
# 啓動項目
# 從終端獲取輸入的參數
if comment[1]=='runserver':
if len(comment)>2:
host = comment[2].split(':')[0]
port = comment[2].split(':')[1]
app.run(host=host,port=port)
else:
app.run()
elif comment[1]=='migrate':
db.create_all()
三、Flask配置文件
(一)第一種–直接編寫
應用:比較直觀,應用於小型項目
(二)第二種–編寫配置文件settings.py
應用:作爲默認配置寫在文件中
(三)第三種–實用類對象
應用:在項目中使用固定的配置
settings.py
import os
BASE_DIR = os.path.abspath(os.path.dirname(__file__)) # 當前文件,項目所在的根目錄
class Product():
SQLALCHEMY_COMMIT_ON_TEARDOWN = True # 請求結束之後自動提交
SQLALCHEMY_RTACK_MODIFICATIONS = True # 跟蹤修改,flask 1.x之後增加的配置項
SQLALCHEMY_TRACK_MODIFICATIONS = True
DEBUG = True
# 正式環境配置
class Config(Product):
SQLALCHEMY_DATABASE_URI = 'mysql://root:181818@localhost/flask' # 連接mysql
# 測試環境配置
class TestConfig(Product):
SQLALCHEMY_DATABASE_URI='sqlite:///'+os.path.join(BASE_DIR,'test.db') # 連接sqlite3
(四)第四種–從環境變量中加載
環境變量:操作系統運行環境的時候需要的變量信息
應用場景:配置文件的地址不固定,配置文件私密
在linux中配置:export key=value
pycharm中設置環境變量
silent參數:決定加載環境變量時,若不存在,是否報錯
-
True:安靜處理
沒有對應環境變量的時候,不報錯,忽略
-
False:默認值,不安靜處理
沒有對應環境變量的時候,報錯
(五)第五種–從json串中加載
(六)第六種–從mapping(字典類型)中加載
四、登錄註冊
註冊
@app.route('/register/',methods=['get','post'])
def register():
if request.method == 'POST':
email = request.form.get('email')
password = request.form.get('password')
password2 = request.form.get('password2')
if email and password and password2:
user = User.query.filter_by(email=email).first()
# 郵箱已註冊
if user:
msg = '該郵箱已註冊,請登錄'
else:
if password == password2:
user = User(email=email,password=setPassword(password))
user.save()
msg = '註冊成功'
else:
msg = '兩次密碼不一致,請重新輸入'
else:
msg = '郵箱及密碼不能爲空'
return render_template('register.html',**locals())
登錄
@app.route('/login/',methods=['get','post'])
def login():
if request.method == 'POST':
email = request.form.get('email')
password = request.form.get('password')
user = User.query.filter_by(email=email).first()
if user:
if user.password == setPassword(password):
return redirect('/index/')
else:
msg = '密碼錯誤'
else:
msg = '該用戶不存在,請先註冊'
return render_template('login.html',**locals())
圖片常用屬性
@app.route('/perfect/information/',methods=['get','post'])
def perfect_information():
if request.method == 'POST':
data = request.files.get('photo')
print(data) # <FileStorage: '1.jpg' ('image/jpeg')>
method = [one for one in dir(data) if not one.startswith('_')]
print('filename:%s'%data.filename) # 文件名稱
print('content_length:%s'%data.content_length) # 文件長度
print('content_type:%s'%data.content_type) # 文件類型
print('headers:%s'%data.headers) # 請求頭部
print('mimetype:%s'%data.mimetype) # 內容類型
print('mimetype_params:%s'%data.mimetype_params) # 類型的參數
print('name:'+data.name) # 字段名稱
return '獲取圖片'
結果:
filename:1.jpg
content_length:0
content_type:image/jpeg
headers:Content-Disposition: form-data; name="photo";
mimetype:image/jpeg
mimetype_params:{}
name:photo