文章目录
SQLAlchemy
SQLAlchemy是一个数据库的ORM框架,让我们操作数据库的时候不要再用SQL语句了,跟直接操作模型一样。安装命令为:pip install SQLAlchemy。
通过SQLAlchemy连接数据库
1.SQLAlchemy是一个独立的ORM框架,可以独立于FLask存在,也可以再其他项目使用
2.Flask-SQLAlchemy:对SQLAlchemy的一个封装,能够更适合在Flask中使用
#coding=utf-8
from flask import Flask,render_template
from sqlalchemy import create_engine
from flask_sqlalchemy import SQLAlchemy
app=Flask(__name__)
# 数据库的配置变量
# 数据库的配置变量
HOSTNAME = '127.0.0.1'
PORT = '3306'
DATABASE = 'ppl_flask01'
USERNAME = 'root'
PASSWORD =
DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME,PASSWORD,HOSTNAME,PORT,DATABASE)
app.config['SQLALCHEMY_DATABASE_URI']=DB_URI#配置数据库的连接
# 创建数据库引擎
db=SQLAlchemy(app)
@app.route('/')
def index():
#测试代码测试是否连接成果
engine=db.get_engine()
# 创建连接
with engine.connect() as conn:
result = conn.execute('SELECT 1')
print(result.fetchone())
return "hello"
if __name__=='__main__':
app.run(debug=True)
后期补上的利用ORM与Mysql进行数据交互
db.create_all()没有解决,但是可以利用pymysql在数据库中新建表,连接表后进行增删查改
在表中添加数据
#coding=utf-8
from flask import Flask,render_template
from flask_sqlalchemy import SQLAlchemy
import mysql.connector
app=Flask(__name__)
# 数据库的配置变量
HOSTNAME = '127.0.0.1'
PORT = '3306'
DATABASE = 'ppl_flask01'
USERNAME = 'root'
PASSWORD =
DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME,PASSWORD,HOSTNAME,PORT,DATABASE)
app.config['SQLALCHEMY_DATABASE_URI']=DB_URI
app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=True
db=SQLAlchemy(app)
# 创建数据库引擎
@app.route('/article')
def article_view():
#1.添加数据
# article=Article(title="感叹",content="xxxxx")
# db.session.add(article)
# #做一个提交操作
# db.session.commit()
# 2.查询数据
#filter_by:返回一个类列表对象
# article=Article.query.filter_by(id=1)[0]
# print(article.title)
#3.修改数据
# article=Article.query.filter_by(id=4)[0]
# article.content="yyy"
# db.session.commit()
#删除数据
article=Article.query.filter_by(id=4).delete()
db.session.commit()
return "操作成功"
#定义ORM模型
class Article(db.Model):
__tablename__='article'
id =db.Column(db.Integer,primary_key=True,autoincrement=True)
title=db.Column(db.String(200),nullable=False)
content=db.Column(db.Text,nullable=False)
@app.route('/')
def hello_world():
#写一个测试代码来验证是否连接成功
engine=db.get_engine()
with engine.connect() as conn:
result =conn.execute("select 1")
print(result.fetchone())
return 'Hello World!'
if __name__=='__main__':
app.run(debug=True)
db.create_all()
python在MySQL新建表
以下操作的前提代码均有:
import mysql.connector
mydb = mysql.connector.connect(
host="localhost",
user="root",
passwd=,
database = "zl_flask",
)
mycursor = mydb.cursor()
db.create.all()无法解决,所以直接用mysql.connector
import mysql.connector
mydb = mysql.connector.connect(
host="localhost",
user="root",
passwd=,
database = "ppl_flask01",
)
mycursor = mydb.cursor()
mycursor.execute("CREATE TABLE customers (name VARCHAR(255), address VARCHAR(255))")
python在MySQL增删改查
插入表
要把记录插入到MySQL中的表中,使用“INSERT INTO”语句。
#coding=utf-8
import mysql.connector
mydb = mysql.connector.connect(
host="localhost",
user="root",
passwd=,
database = "ppl_flask01",
)
mycursor=mydb.cursor()
sql = "INSERT INTO book (name, address) VALUES (%s, %s)"
val = ("红楼梦", "Highway 21")
mycursor.execute(sql, val)
mydb.commit()
print(mycursor.rowcount, "条记录已插入")
插入多行
要将多行插入到表中,使用executemany()方法。
executemany()方法的第二个参数是一个元组列表,包含了要插入的数据:
#coding=utf-8
import mysql.connector
mydb = mysql.connector.connect(
host="localhost",
user="root",
passwd=,
database = "ppl_flask01",
)
mycursor=mydb.cursor()
# mycursor.execute("CREATE TABLE book (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), address VARCHAR(255))")
sql = "INSERT INTO book (name, address) VALUES (%s, %s)"
val = [
('三国演义', 'Lowstreet 4'),
('西游记', 'Apple st 652'),
('水浒传', 'Mountain 21'),
('云间有个小卖部', 'Valley 345'),
('你听我说', 'Ocean blvd 2'),
('落霞', 'Green Grass 1'),
]
mycursor.executemany(sql, val)
mydb.commit()
print(mycursor.rowcount, "条记录已插入")
从表中选取(SELECT)数据
从MySQL表中选取(SELECT)数据
使用“SELECT”语句:
注意: 使用了fetchall()方法,它从最后所执行语句的结果中,获取所有行。
#coding=utf-8
import mysql.connector
mydb = mysql.connector.connect(
host="localhost",
user="root",
passwd=,
database = "ppl_flask01",
)
mycursor=mydb.cursor()
# mycursor.execute("CREATE TABLE book (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), address VARCHAR(255))")
mycursor.execute("SELECT * FROM book")
myresult = mycursor.fetchall()
for x in myresult:
print(x)
选取表中的部分字段,
使用“SELECT 字段1, 字段2 …”语句
mycursor.execute("SELECT name,address FROM book")
myresult = mycursor.fetchall()
只取一行
mycursor=mydb.cursor()
mycursor.execute("SELECT * FROM book")
myresult = mycursor.fetchone()
for x in myresult:
print(x)
WHERE筛选数据
从表中选取记录时,可以使用“WHERE”语句筛选
sql = "SELECT * FROM book WHERE name ='三国演义'"
mycursor.execute(sql)
myresult = mycursor.fetchall()
通配符
WHERE语句中可以使用通配符%。关于SQL中,WHERE子句使用通配符
防止SQL注入
什么是SQL注入? SQL注入是一种攻击,当web服务器从浏览器接受用户输入时,如果web应用程序有漏洞,攻击者有可能注入恶意SQL代码。
SQL注入攻击可能引起敏感信息暴露,如用户的联系电话、电子邮件地址、信用卡信息等。利用它,攻击者甚至能绕过身份验证,访问整个数据库。
一种比较简单的方法
当用户提供查询值时,为了防止SQL注入,应该转义这些值。
SQL注入是一种常见的web黑客技术,用于破坏或误用数据库。
使用占位符%s方法转义查询值:
sql = "SELECT * FROM customers WHERE address = %s"
对结果排序
可以使用ORDER BY语句,按升序或降序对结果排序。
默认情况下,ORDER BY关键字按升序排列结果。要按降序排列,可使用DESC关键字。
sql = "SELECT * FROM book ORDER BY name"
mycursor.execute(sql)
myresult = mycursor.fetchall()
for x in myresult:
print(x)
删除记录
可以使用“DELETE FROM”语句,从现有表中删除记录
sql = "DELETE FROM book WHERE name='John'"
mycursor.execute(sql)
mydb.commit()
删除表
sql = "DROP TABLE IF EXISTS customers"
mycursor.execute(sql)
更新表
可以使用“UPDATE”语句,更新表格内的现有记录:
sql = "UPDATE book SET address='Canyon 123' WHERE address='Valley 345'"
mycursor.execute(sql)
mydb.commit()
print(mycursor.rowcount, " 条记录已更新")
限制结果数量
可以使用“LIMIT”语句,限制查询返回的记录数量
mycursor = mydb.cursor()
mycursor.execute("SELECT * FROM book LIMIT 5")
myresult = mycursor.fetchall()
for x in myresult:
print(x)
从指定位置开始如果想返回,从第3条记录开始的5条记录,可以使用“OFFSET”关键字
mycursor.execute("SELECT * FROM book LIMIT 5 OFFSET 2")
cookie和session
1.cookie:在网站中,http请求是无状态的。也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户。cookie的出现就是为了解决这个问题,第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当该用户发送第二次请求的时候,就会自动的把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪个了。cookie存储的数据量有限,不同的浏览器有不同的存储大小,但一般不超过4KB。因此使用cookie只能存储一些小量的数据。
2.session: session和cookie的作用有点类似,都是为了存储用户相关的信息。不同的是,cookie是存储在本地浏览器,session是一个思路、一个概念、一个服务器存储授权信息的解决方案,不同的服务器,不同的框架,不同的语言有不同的实现。虽然实现不一样,但是他们的目的都是服务器为了方便存储数据的。session的出现,是为了解决cookie存储数据不安全的问题的。
cookie和session结合使用:web开发发展至今,cookie和session的使用已经出现了一些非常成熟的方案。在如今的市场或者企业里,一般有两种存储方式:
-
存储在服务端:通过cookie存储一个session_id,然后具体的数据则是保存在session中。如果用户已经登录,则服务器会在cookie中保存一个session_id,下次再次请求的时候,会把该session_id携带上来,服务器根据session_id在session库中获取用户的session数据。就能知道该用户到底是谁,以及之前保存的一些状态信息。这种专业术语叫做server side session。存储在服务器的数据会更加的安全,不容易被窃取。但存储在服务器也有一定的弊端,就是会占用服务器的资源,但现在服务器已经发展至今,一些session信息还是绰绰有余的。
-
将session数据加密,然后存储在cookie中。这种专业术语叫做client side session。flask采用的就是这种方式,但是也可以替换成其他形式。
flask中使用cookie和session
- cookies:在Flask中操作cookie,是通过response对象来操作,可以在response返回之前,通过response.set_cookie来设置,这个方法有以下几个参数需要注意:
- key:设置的cookie的key。
- value:key对应的value。
- max_age:改cookie的过期时间,如果不设置,则浏览器关闭后就会自动过期。
- expires:过期时间,应该是一个datetime类型。
- domain:该cookie在哪个域名中有效。一般设置子域名,比如cms.example.com。
- path:该cookie在哪个路径下有效。
- ession:Flask中的session是通过from flask import session。然后添加值key和value进去即可。并且,Flask中的session机制是将session信息加密,然后存储在cookie中。专业术语叫做client side session
from flask import Flask,Response,request,session
app = Flask(__name__)
app.config['SECRET_KEY'] = "12asdfadfdsfasd3"
#定义两个视图函数
@app.route("/set_cookie")
def set_cookie():
response = Response("cookie 设置")
response.set_cookie("user_id","xxx")
return response
@app.route("/get_cookie")
def get_cookie():
user_id = request.cookies.get("user_id")
print("user_id:",user_id)
return "获取cookie"
@app.route("/set_session")
def set_session():
# 在flask中,session是先把数据经过加密,然后用session_id作为key,存放到cookie中
# 因为session会经过加密再存储到cookie中,所以我们的敏感信息,会存放到session中
session['username'] = "zhiliao"
return "session设置成功"
@app.route("/get_session")
def get_session():
username = session.get('username')
print("username:",username)
return "get session"
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run(debug=True)
wtforms表单验证
wtforms表单的两个主要功能是验证用户提交数据的合法性以及渲染模板,当然还包括一些其他功能:CSRF保护、文件上传等。安装Flask-WTF也会安装WTFroms,使用pip install flask-wtf或者
pip install wtforms -i http://pypi.douban.com/simple
--trusted-host pypi.douban.com
一、表单验证
安装完Flask-WTF后。来看下第一个功能,就是用表单来做数据验证,现在有一个forms.py文件,然后在里面创建一个RegistForm的注册验证表单。
所有用到的代码文件:
app.py
#coding=utf-8
from flask import Flask,request,render_template
from forms import LoginForm
app = Flask(__name__)
@app.route('/login',methods=['GET','POST'])
def login():
if request.method == 'GET':
return render_template("login.html")
else:
form = LoginForm(request.form)
if form.validate():
return "登录成功!"
else:
return "邮箱或密码错误!"
@app.route('/')
def hello_world():
return 'Hello World!'
if __name__ == '__main__':
app.run(debug=True)
和form.py
#coding=utf-8
import wtforms
from wtforms.validators import length,email
class LoginForm(wtforms.Form):
email=wtforms.StringField(validators=[length(min=5,max=20),email()])
password=wtforms.StringField(validators=[length(min=6,max=20)])
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<form action="/login" method="post">
<table>
<tbody>
<tr>
<td>邮箱:</td>
<td>
<input type="text" name="email">
</td>
</tr>
<tr>
<td>密码:</td>
<td><input type="text" name="password"></td>
</tr>
<tr>
<td></td>
<td><button>登录</button></td>
</tr>
</tbody>
</table>
</form>
</body>
</html>