django中使用ORM连接操作数据库,如果不使用数据库,将会失去站点管理的功能。
python使用pymysql连接操作数据库,flask中也可以使用pymysql连接。
sqlalchemy:python的开源数据库框架
对sqlalchemy进行封装
pip install flask-sqlalchemy
pip install pymysql
官方配置文档:
http://www.pythondoc.com/flask-sqlalchemy/config.html#uil
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()
字段类型:
字符串:String(32),text
数字:Integer,Float
日期:DATE,DATETIME
字段属性:
primary_key
autoincrement
nullable
unique
dafault
DATETIME默认当前时间:
from datetime import datetime
default=datetime.now()
# 基类
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是遵循MVC的解耦合的设计模式,应当把它们分开。
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项目
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())
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))
# 项目的管理文件
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()
应用:作为默认配置写在文件中
应用:在项目中使用固定的配置
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
silent参数:决定加载环境变量时,若不存在,是否报错
@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) #
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