這個(gè)問(wèn)題經(jīng)常難道新手一下,因?yàn)榇蟛糠纸坛汤铮òń?jīng)典的《Flask
成都創(chuàng)新互聯(lián)專注于田林企業(yè)網(wǎng)站建設(shè),響應(yīng)式網(wǎng)站,商城開(kāi)發(fā)。田林網(wǎng)站建設(shè)公司,為田林等地區(qū)提供建站服務(wù)。全流程按需網(wǎng)站策劃,專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,成都創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)
Web開(kāi)發(fā)》一書(shū)),告訴了我們?nèi)绾问褂胒lask-sqlalchemy操作sqlite,但在生產(chǎn)環(huán)境(線上網(wǎng)站)上,我們肯定是使用MySQL或其
他,而大部分的教程里,又告訴我們flask-sqlalchemy使用MySQL的方式是:
mysql://username:password@server/db
結(jié)果我們照葫蘆畫(huà)瓢的來(lái)一下,發(fā)現(xiàn)壓根不行,寫(xiě)好的網(wǎng)站一跟數(shù)據(jù)庫(kù)沾邊就報(bào)錯(cuò)。
Python和MySQL是「兩個(gè)國(guó)家的人」,他們互不相通,因而需要一個(gè)中間代理,讓雙方互通有無(wú),跟翻譯一樣(這比喻不準(zhǔn)確,但足夠你明白意思就行)。翻譯又有很多選擇,不同的翻譯各有特色。
題
主解決問(wèn)題選擇的翻譯是「flask-mysqldb」,其背后的主子是「MySQL-python」。恩,說(shuō)到這里你應(yīng)該知道,「flask-xxx」
這樣的包都是對(duì)背后主子進(jìn)行了適合Flask封裝的插件,跟包子皮一樣,里面的餡才是重點(diǎn),「flask-mysqldb」的餡是「MySQL-
python」。
而我要推薦的是另一個(gè)翻譯:PyMySQL,這玩意的好處是可以做異步(「MySQL-python」也可以,個(gè)人口味罷了),簡(jiǎn)而言之,網(wǎng)站訪問(wèn)量大了就需要考慮異步,現(xiàn)在別管這是啥子。這玩意的安裝方式是:
pip install PyMySQL
之后,數(shù)據(jù)庫(kù)連接由:
mysql://username:password@server/db
改為
mysql+pymysql://username:password@server/db
就可以了。
用 Flask-SQLAlchemy(SQLAlchemy ORM 模塊的 Flask 定制版)。這個(gè)在定義 schema、連接數(shù)據(jù)庫(kù)、增刪改查方面都給你提供極大的便利。
這個(gè)對(duì)象就包含 sqlalchemy 和 sqlalchemy.orm 中的所有函數(shù)和助手。此外它還提供一個(gè)名為 Model 的類,用于作為聲明模型時(shí)的 delarative 基類:
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(120), unique=True)
def __init__(self, username, email):
self.username = username
self.email = email
def __repr__(self):
return 'User %r' % self.username
python3下用flask-sqlalchemy對(duì)mysql數(shù)據(jù)庫(kù)操作案例:
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://username:password@localhost/db_name'
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(80), unique=True)
email = db.Column(db.String(120), unique=True)
def __init__(self, username, email):
self.username = username
self.email = email
def __repr__(self):
return 'User %r' % self.username
admin = User('admin', 'admin@example.com')
db.create_all() # In case user table doesn't exists already. Else remove it.
db.session.add(admin)
db.session.commit() # This is needed to write the changes to database
User.query.all()
User.query.filter_by(username='admin').first()
用flask+mysql實(shí)現(xiàn)用戶的注冊(cè)和登錄:
一個(gè)簡(jiǎn)單的用戶注冊(cè)和登錄的頁(yè)面,就兩個(gè)部分。
涉及到數(shù)據(jù)庫(kù),存儲(chǔ)用戶數(shù)據(jù)(注冊(cè)),讀出用戶數(shù)據(jù)(登錄驗(yàn)證)。搞清楚如何用python連接和操作數(shù)據(jù)庫(kù)即可,還有了解sql數(shù)據(jù)庫(kù)語(yǔ)句,sqlite和mysql差不多的,看幾眼多試幾下就了解了。
網(wǎng)站程序,前端如何發(fā)送表單,后端獲取用戶發(fā)送的請(qǐng)求,和數(shù)據(jù)庫(kù)中數(shù)據(jù)驗(yàn)證是否能夠登錄,然后登錄后如何保存用戶登錄信息,就是使用的cookie,不過(guò)在flask中是session(其實(shí)session也是cookie,flask把它封裝了下,成了加密的cookie)。
舉例如下:
from?functools?import?wrapsdef?authorize(fn):
@wraps(fn)
def?wrapper(*args,?**kwds):
user?=?session.get('logged_in',?None)
if?user:
return?fn(user=user)
else:
return?redirect(url_for('signin',next=request.path))
return?wrapper@app.route('/home')@authorizedef?home(**kwds):
username?=?kwds['user']
return?render_template('index.html'?,username=username)#加密存儲(chǔ)密碼import?osimport?hashlibdef?encrypt_password(password,?salt=None):
if?not?salt:
salt?=?os.urandom(16).encode('hex')?#?length?32
result?=?password
for?i?in?range(3):
result?=?hashlib.sha256(password?+?salt).hexdigest()[::2]?#length?32
return?result,?salt#簡(jiǎn)單的錯(cuò)誤處理class?loginError(Exception):
def?__init__(self,?value):
self.value?=?value
def?__str__(self):
return?repr(self.value)#?注冊(cè)登錄(下面的代碼沒(méi)有實(shí)際運(yùn)行過(guò))#?連接數(shù)據(jù)庫(kù)我是使用的是?mysql.connector?#??寫(xiě)法和常用的MySQL-python稍有所不同#?下面沒(méi)有連接數(shù)據(jù)庫(kù)的代碼@app.route('/register/',?methods=['GET','POST'])def?request():
if?request.method?==?'GET':
return?render_template("register.html")
if?request.method?==?'POST':
#?這里最好需要驗(yàn)證用戶輸入,我就不寫(xiě)了
u?=?request.form['username']
p,s?=?encrypt_password(request.form['password'])
g.db.cursor.execute('INSERT?INTO?users?(name,password,salt)?VALUES?(%s,%s,%s)',(u,p,s,)
g.db.commit()
return?redirect(url_for('signin'))@app.route('/signin/',?methods=['GET','POST'])def?signin():
if?request.method?==?'GET':
referrer?=?request.args.get('next','/')
return?render_template("login.html",next=referrer)
if?request.method?==?'POST':
u?=?request.form['username']
p?=?request.form['password']
n?=?request.form['next']
try:
g.db.cursor.execute('SELECT?`name`?FROM?users?WHERE?name?=?%s',(u,))
if?not?g.db.cursor.fetchone():
raise?loginError(u'錯(cuò)誤的用戶名或者密碼!')
g.db.cursor.execute('SELECT?`salt`,`password`?FROM?users?WHERE?name?=?%s',(u,))
salt,password?=?g.db.cursor.fetchone()
if?encrypt_password(p,salt)[0]?==?password:
session['logged_in']?=?u
return?redirect(next)
else:
raise?loginError(u'錯(cuò)誤的用戶名或者密碼!')
except?loginError?as?e:
return?render_template('login.html',?next=next,error=e.value)@app.route('/signout/',?methods=['POST'])def?signout():
session.pop('logged_in',?None)
return?redirect(url_for('home'))
名稱欄目:flask整合nosql,flask框架
瀏覽地址:http://m.newbst.com/article12/dsijodc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站營(yíng)銷、微信公眾號(hào)、關(guān)鍵詞優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容