Python Web 之 Flask
FLASK
一、概述
flask是一个基于python并依赖于Jinja2模板引擎和WerkZeug WSGI(Web Server Gatewey InterFace.web)服务的框架
WSGI:服务网关接口,提供处理网络请求相关的功能
hello world
from flask import Flask
# 创建flask的程序实例
app = Flask(__name__)
@app.route('/') # 路由配置
# 视图函数
def index():
return "<h1>欢迎访问</h1>"
# 启动服务
if __name__ == "__main__":
app.run(debug=True)
二、 定义路由
路由是为了匹配用户的请求地址,会自动执行视图函数。视图函数中必须有返回值,返回字符串显示到响应的页面中。
2. 无参数
定义路由
@app.route('/地址')
定义视图函数
def funcName():
return "" # 响应到页面的内容
例如:
@app.route("/") # '/'表示根路径
def index(): #匹配到路径后执行的视图函数
return "首页"
3. 带参数
变量:<变量名>
@app.route("/login/<name>")
def login(name):
return "欢迎%s登陆"%name
如需要设置默认路由,则在视图函数中传参直接设置def login(name="Chancey")
还有一种方式,就是在路由装饰器中传入一个字典@app.route("/login/<name>",defaults={"name":"游客"})
4. 类型转换器
缺省:字符串,不能包含'/'
int
:转换整数 float
:转换小数 path
:字符串,运行包含'/'
使用:@app.route('/show/<int:num>')
在路径中直接转换
例如
配置路由:/calaute/<number1>/<number2>,视图函数中接收参数,返回类似于“3 + 5 = 8”
@app.route('/calaute/<num1>/<num2>')
def calaute(num1,num2):
return "%s + %s = %d"%(num1,num2,int(num1)+int(num2))
注意:路径中的参数变量永远是字符串
5. 多个URL
多个URL执行同一个视图函数
@app.route("/")
@app.route("/index")
def index():
return "首页"
例如
定义路由:127.0.0.1:5000/show 127.0.0.1:5000/show/list 127.0.0.1:5000/show/<name>,执行同一个函数,返回相应的内容
@app.route("/show")
@app.route("/show/list")
@app.route("/show/<name>")
def show(name="Chancey"):
return "show %s"% name
如果在
app.run()
设置host=0.0.0.0
不影响当前虚拟IP(127.0.0.1)
可以让当前局域网中的其他计算机通过内网IP访问服务器
二、模板
模板是一种特殊的HTML文件,Python+HTML网页结构,允许在模板文件中使用变量,定义流程控制。使用模板可以使用视图函数专注于处理业务逻辑,将页面渲染交由模板控制
导入
render_template
项目中创建“
templates
”文件夹,所有模板文件必须存放"template
"文件夹下在视图函数中使用
render_template("模板文件")
,生成模板字符串,交由浏览器解析
from flask import Flask,render_template app = Flask(__name__) @app.route("/info")
def info():
return render_template("01-show.html", name="flask", age=20)
1. 变量代码块
模板中使用变量
语法:
{{ 变量名(key) }}
从视图函数中获取相关的变量,传递到模板文件中
语法:
return render_template("模板文件", key1=value1, key2=value2)
函数中可以传递若干键值对,其中的key名就是在模板文件中使用的变量名
local()
函数,是将当前作用域中的所有局部变量打包成一个字典返回,可以用一个变量接收,然后传递到模板中.- 如果变量里面有字典类型的数值,有两种方法取值
variable["keyName"]
、variable.keyName
) - 如果变量里面有列表类型的数值,则直接用
list[number]
取值
- 如果变量里面有字典类型的数值,有两种方法取值
例如:
视图函数中定义变量(name="" age= dic= tub= list= ),将数据传递到模板文件中显示
from flask import Flask, render_template
# 创建实例
app = Flask(__name__)
# 定义动物类
class Pet(object):
name = None
def play(self):
return "来和" + self.name + "玩耍吧"
@app.route('/show')
def show():
name = "Chancey"
age = 18
dic = {
"name":"Waller",
"age":20
}
list = ["开车","保健"]
tup = ("波多","仓井","海翼")
# 实例化对象
cat = Pet()
cat.name = "妲己"
# locals() 将当前作用域中的局部变量包装成一个字典返回
# key=value
return render_template("01-show.html", d=locals())
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>show</title>
</head>
<body>
<h1>模板文件</h1>
<p>列表、元组、字典都可以使用[key/index]和点语法访问</p>
<p>name:{{ d["name"] }}</p>
<p>age:{{ d.age }}</p>
<p>name:{{ d.dic["name"] }}</p>
<p>宠物名:{{ d.cat.name }}</p>
<p>动作:{{ d.cat.play() }}</p>
</body>
</html>
2. 过滤器
允许模板中的变量在输出之前修改成其他的值,修改显示
upper
转大写字母lower
转小写字母title
首字母大写first
获取第一个last
获取最后一个length
获取列表长度default
如果变量未赋值,可采用默认值trim
去掉字符串两边的空格- ....
语法:{{ 变量|过滤器1|过滤器2 }}
<!-- 在python文件视图函数中自行添加s1变量,赋值" hello world" -->
<p>原版:{{ d.s1 }}</p>
<p>大写:{{ d.s1|upper }}</p>
<p>小写:{{ d.s1|lower }}</p>
<p>首字母大写:{{ d.s1|title }}</p>
<p>获取第一个:{{ d.s1|first }}</p>
<p>获取最后一个:{{ d.s1|last }}</p>
<p>获取长度:{{ d.s1|length }}</p>
<p>去掉两边空格:{{ d.s1|trim }}</p>
<p>未赋值的变量:{{ d.s2|default("默认变量") }}</p>
3. 控制代码块
在模板中书写条件语句和循环语句,使用{% python语句 %}
3.1 if
{% if 条件 %}
条件成立时。允许书写静态标签,也可以书写变量
{% endif %}
{% if 条件 %}
条件成立时执行
{% else %}
条件不成立时执行
{% endif %}
<!-- 多重分支 -->
{% if 条件1 %}
pass
{% elif 条件2 %}
pass
{% elif 条件3 %}
pass
{% endif %}
例如:
{% if d.age < 18 %}
<h3>{{ d.age }}岁未成年</h3>
{% elif d.age < 30 %}
<h3>{{ d.age }}岁青成年</h3>
{% elif d.age < 50 %}
<h3>{{ d.age }}岁中成年</h3>
{% else %}
<h3>{{ d.age }}岁老年人</h3>
{% endif %}
3.2 for
{% for 变量 in 可跌对象 %}
{% endfor %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>show</title>
<style>
.c1{
background: red;
}
.c2{
background: orange;
}
.c3{
background: cyan;
}
</style>
</head>
<body>
<table border="2px">
<tr>
<td>姓名</td>
<td>年龄</td>
</tr>
{% for item in info %}
<tr
{% if loop.first %}
class = c1
{% elif loop.last %}
class = c2
{% else %}
class = c3
{% endif %}
>
<td>{{ item.name }}</td>
<td>{{ item.age }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
def show():
info = [
{"name":"Chancey","age":18},
{"name":"Waller","age":35},
{"name":"Mary","age":16},
{"name":"Jacob","age":40},
{"name":"William","age":17},
{"name":"Samuel","age":37},
{"name":"Anthony","age":35},
]
return render_template("02-show.html", info=info)
if __name__ == '__main__':
app.run(debug=True, host="0.0.0.0")
3.3 loop
循环的内部变量loop
:直接在内部使用,表示本次循环相关的信息
常用属性:
loop.index
当前循环的次数,默认从1开始计算loop.index0
当前循环的次数,从0开始计算loop.first
是否为第一次循环,值为True表示第一次循环loop.last
是否为最后一个循环
实例在前边for循环中已使用
4. 静态文件
不与服务器交互的文件都是静态文件(css、js、图片、音频等)
所有静态文件都必须存储在一个名为
static
的文件夹下,Flask程序会自动查找静态文件的访问:必须使用
/static
访问url_for("视图函数名")
实现反向解析路由,后边可以跟参数url_for("login")
根据视图函数解析对应的URLurl_for("login", uname="chancey", passwd="123456")
反向解析带参数的路由/login/chancey/123
/static/css/base.css
<link rel="stylesheet" href="{{ url_for('static',filename='path') }}>"
5.模板继承
与类的继承相似
如果两个页面中大部分内容与结构都一致,可以采用模板继承
实现:
父模板:指定可以被子模板重写的内容
{% block 块名 %}
<h1>父模板</h1>
{% endblock %}
子模板中继承父模板
{% extends 父模板名称 %}
子模板中可以重写父模板中指定的块的内容
{% block 块名 %}
<h1>子模板</h1>
{% endblock %}
<!--路由自行配置,不再展示-->
<!-- 01-base.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>
{% block web_title %}
父模板
{% endblock %}
</title>
</head>
<body>
<h4>
{% block title %}
这里是标题
{% endblock %}
</h4>
<p>
{% block content %}
这里是内容
{% endblock %}
</p>
</body>
</html>
<!--路由自行配置,不再展示-->
<!-- 02-index.html -->
{% extends "02-base.html" %}
{% block web_title %}
佛曰
{% endblock %}
{% block title %}
佛曰
{% endblock %}
{% block content %}
写字楼里写字间,写字间里程序员;
程序人员写程序,又拿程序换酒钱。
酒醒只在网上坐,酒醉还来网下眠;
酒醉酒醒日复日,网上网下年复年。
但愿老死电脑间,不愿鞠躬老板前;
奔驰宝马贵者趣,公交自行程序员。
别人笑我忒疯癫,我笑自己命太贱;
不见满街漂亮妹,哪个归得程序员?
{% endblock %}
三、网络请求
利用网络通信协议实现前后端数据交互,常用的网络通信协议:HTTP(S),规定数据的传输格式
1. 请求
1.1 请求消息
客户端向服务端发送的消息
1.2 组成
请求起始行
协议、请求方式、资源路径
请求消息头
使用kry-value字典的方式存储相关信息
请求主体
get请求如果携带数据,以参数的形式直接拼接在URL后边(
?key1=value1&key2=value2
)只有POST方式才会有请求主体
2. 响应
2.1 响应信息
服务端接收到请求并且处理之后,返回给客户端的信息(数据)
2.2 组成
响应起始行
协议、响应状态码、原因短句
响应消息头
描述响应回来的数据,以
key:value
存储响应主体
保存响应数据
四、Flask中的HTTP
1. requests
在requests对象中封装了所有跟当前请求相关的信息
使用:
引入:
from flask import request
使用:在视图函数中获取request对象内部的信息
属性:
scheme
获取此次请求的协议method
获取请求方式args
获取GET提交的数据form
获取POST提交的数据cookies
获取cookies中保存的数据files
获取上传的文件path
获取请求的资源路径(无参数)full_path
获取请求的资源路径(携带参数)url
获取完整的请求地址headers
<h2>子模板</h2>
<p>协议:{{ params.scheme }}</p>
<p>请求方式:{{ params.method }}</p>
<p>请求的参数:{{ params.args }}</p>
<p>请求的参数的内容:{{ params.args.uname }}</p>
<p>请求的参数的内容:{{ params.args.age }}</p>
<p>cookies:{{ params.cookies }}</p>
<p>资源路径:{{ params.path }}</p>
<p>资源路径:{{ params.full_path }}</p>
获取请求中的数据
获取GET请求中的数据
request.args["key"]
request.args.get("key","默认值")
request.args.getlist("key")
适用于一个key对应多个值的情况(复选框)print(request.args.get("uname"))
print(request.args.get("passwd"))
print(request.args.getlist("hobby"))
#get当时如果未携带数据,在视图函数中直接读取request.args['']数据,报400
获取POST请求中的数据
request.form
获取数据字典
request.form["key"]
request.form.get("key")
request.form.getlist('key')
post即使未携带参数,直接获取字典的值,返回为空
页面重定向
由服务器端通知浏览器重新向新的地址发送请求
引入
redirect
使用函数
redirect("重定向地址")
视图函数中返回
return redirect("重定向地址")
页面源
当前的请求是从哪一个源地址发起的,保存在请求消息头中(
"Referer":""
)文件上传
使用表单控件
type="file"
向服务器发送文件,因为文件,图片,音频等都是为禁止数据,必须设置表单的提交方式和编码类型<form action="" method="post" ectype="multipart/form-data">
服务器端使用
request.files
获取上传的文件,返回字典例如:
f = request.files["key"]
f.save(保存路径)
@app.route("/add", methods=["GET", "POST"])
def add():
if request.method == "GET":
return render_template("02-add.html")
else:
title = request.form["title"]
type = request.form["type"]
content = request.form["content"]
print("标题:%s 类型:%s 内容:%s"%(title, type, content)) # 判断文件上传
if "userimg" in request.files:
file = request.files["userimg"]
file_name = generate_filename(file.filename)
up_path = generate_upload_path(__file__, "static/upload", file_name)
print("保存路径:" + up_path)
return "获取数据成功"
else:
return "已存在"
2. response
模型(Models)
模型:根据数据表结构而创建出来的class(一张表一个类,一个字段就是一个属性)
框架:ORM(Object Relational Mapping 对象关系映射)
特征:
- 数据表到编程类的映射
- 数据类型的映射
- 关系映射(将数据库中表与表之间的关系 对应到 编程语言中类与类的关系)
优点:
- 封装操作提升效率
- 省略庞大的数据访问层
五、ORM
1. SQLAlchemy
安装:pip install flask-sqlalchemy
导包:from flask_sqlalchemy import SQLAlchemy
配置数据库:app.config['SQLALCHEMY_DATABASE_URI']="MYSQL://用户名:密码@数据地址:端口/数据库名"
创建数据库:create database dbname default charset utf8 collate utf8_general_ci;
数据库自动提交:app.config["SQLALCHEMY_COMMIT_ON_TEARDOWN"] = True
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
# import pymysql
# pymysql.install_as_MySQLdb()
app = Flask(__name__)
#连接数据库
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:Asd.1234@127.0.0.1:3306/flaskDB"
#创建SQLAlachemy实例
db = SQLAlchemy(app)
print(db)
if __name__ == '__main__':
app.run(debug=True, host="0.0.0.0")
上边的代码中,
import pymysql \ pymysql.install_as_MySQLdb()
可以省略,简写在config中
2. 定义类
2.1 作用
通过编写模型类的方式,让程序自动生成数据表模型类也称为实体类
2.2 语法
# 代码中大写单词均为自定义
class MODELNAME(db.Model):
__tablename__ = "TABLENAME"
COLUMN = db.Column(db.TYPE, OPPTIONS)
"""
1. MODELNAME 定义模型类名称,参考表名
2. TABLENAME 指定要映射到的表名,如果不存在的话,则创建表
3. COLUMN 属性名,映射到数据表中就是列名
4. TYPE 映射到列的数据类型
5. OPPTIONS 列选项
"""
db.TYPE
列类型
OPPTIONS
列选项
class Usres(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
username = db.Column(db.String(20), nullable=False, unique=True)
age = db.Column(db.Integer)
email = db.Column(db.String(120), unique=True)
def __init__(self, username, age, email):
self.username = username
self.age = age
self.email - email
def __repr__(self):
return "<用户名:%r 年龄:%r 邮箱:%r>"%(self.username, self.age, self.email)
#将创建好的实体类映射回数据库
db.create_all()
## 创建Student实体类,表名student
"""
1. id 主键 自增
2. sname 姓名 长度30 不为空
3. sage 年龄 整数
4. isActive 启用状态 bool类型 默认为True
"""
## 创建Teacher类,表名teacher
"""
1. id 主键 自增
2. tname 姓名 长度30 不为空
3. tage 年龄 整数
"""
## 创建Course类,表名course
"""
1. id 主键 自增
2. cname 课程名称 长度30
"""
class Student(db.Model):
__tablename__ = "student"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
sname = db.Column(db.String(30), unique=True)
sage = db.Column(db.Integer)
isActive = db.Column(db.Boolean, default="True")
class Teacher(db.Model):
__tablename__ = "teacher"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
tname = db.Column(db.String(30), unique=True)
tage = db.Column(db.Integer)
class Course(db.Model):
__tablename__ = "course"
id = db.Column(db.Integer, primary_key=True, autoincrement=True)
cname = db.Column(db.String(30), unique=True)
3. 数据迁移
3.1 定义
将实体类的改动再次映射回数据库
3.2 依赖于第三方库
Flask-script
包:flask_script
类:Manager
作用:对项目进行管理(启动项目、增加管理指令)
flask-migrate
包:
flask_migrate
类:Migrate(协调app和db之间的关系)、MigrateCommand(在终端中提供实体类迁移的指令)
3.3 使用
修改app.config
#指定数据库不追踪
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 指定启动的模式为调试模式
app.config["DEBUG"] = True
创建管理对象:
manage = Manager(app)
启动:
manager.run()
(但是项目的启动需在终端中执行python demo.py runserver
)
在使用了manger启动项目的时候,如需开启相关服务,如debug。。。
在终端启动的时候加参数
python demo,py runserver --host 0.0.0.0
配置app.config:
app.config["DEBUG"] = True
- 导入
from flask_migrate import Migrate, MigrateCommand
- 在实体类之前创建
migrate = Migrate(app, db)
- 增加一个子命令
manage.add_command("db", MigrateCommand)
3.4 迁移
python run.py db init
作用:执行项目和数据库的初始化操作
特点:一个项目中只执行一次即可
python run.py db migrate
作用:将编辑好的实体类生成一个中间文件并保存
特点:只要检测到实体类有更改,就会生成中间文件
python run.py db upgrade
作用:将中间文件映射到数据库
from flask import Flask, request, render_template, url_for
from flask_sqlalchemy import SQLAlchemy
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = "mysql+pymysql://root:Asd.1234@127.0.0.1:3306/run02"
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["DEBUG"] = True
app.config["SQLALCHEMY_COMMIT_ON_TEARDOWN"] = True
db = SQLAlchemy(app)
manage = Manager(app)
migrate = Migrate(app, db)
manage.add_command("db", MigrateCommand)
六、模型
1. 增
创建实体类对象,并为对象的属性赋值
user = Users()
user.username = "Chancey"
user.age = 30
user.isActive = True
user.birthday = "2019-01-01"
将实体对象保存回数据库对象
db.session.add(user)
db.session.commit(user)
user = Users(username, age, email)
db.session.add(user)
db.session.commit()
2. 查
2.1 .基于db.session
参数:要查询的列,如果查询多个列的话使用,隔开,如果要查询所有列,参数为实体类名
2.1.1 query()
实例:
查询Users实体类中的id,username
db.session.query(Users.id, Users.username)
查询Users实体类中所有的列
db.session.query(Users)
查询Users以及wife实体类所有的列
db.session.query(Users, Wife)
返回值:返回一个Query对象(SQL语句)
# 返回一个query对象
query = db.session.query(Users.id,Users.uaername)
print(query)
print("type:",type(query))
2.1.2 查询执行函数
作用:在query的基础上得到最终的查询结果
语法:db.session.query(xxx)
查询执行函数()
函数:
all()
以列表的方式返回所有的数据
first()
以实体对象的方式返回第一条数据,没有查询到数据则返回None
first_or_404()
效果同上,没查询到结果则响应404
count()
返回查询结果的数量
s = db.session.query(Users.username, Users.age, Users.email).all()
for i in s:
print(i.username, i.age, i.email)
user = db.session.query(Users).first()
print(user.username, user.age, user.email)
print(db.session.query(Users).count())
2.1.3 查询过滤器函数
作用:在db.session.query()
追加条件
语法:db.session.query(xx).执行函数()
函数:
filter()
各种各样的查询条件均可实现filter_by()
只做等值条件判断limit()
限定行数offset()
指定结果的偏移量order_by()
按照指定条件排序group_by()
分组查询
返回值:均是query对象
实例:
查询年龄大于25的信息
db.session.query(Users).filter(Users.age>25).all()
查询id为2的User信息
db.session.query(Users).filter(Users.id==2).first()
查询idActive为true并且年龄大于30的
db.session.query(Users).filter(Users.isActive==True).filter(Users.age>30).all()
获取前5条数据
db.session.query(Users).limit(5).all()
对表中的所有数据按照id倒序排序
db.session.query(Users).order_by("id desc").all()
(1) or_
导入:from sqlalchemy improt or_
使用:
查询isActive为True或者年龄不小于30的
db.session.query(User).filter(or_(User.isActive==True,User.age>=30)).all()
(2) like
模糊查询like主要使用实体类属性所提供的的like()
函数
查询email中包含an的信息
db.session.query(Users).filter(Users.email.like("%an%")).all()
(3) in_
模糊查询in,需要使用实体类提供的属性in_
函数完成
查询年龄是30、17、45的*
db.session.query(Users).filter(Users.age.in_([30,17,45])).all()
(4) between
模糊查询between...and...需要使用实体类属性提供的between(值1,值2)
查询年龄在30到45之间的
db.session.query(Users).filter(Users.age.between(30,45)).all()
2.2 基于Models
Models.query.查询过滤(条件参数).查询执行函数()
例如:Users.query.filter(Users.id>3).all()
3. 删除
- 查询出要删除的实体
user = db.session.query(Users).filter_by(id=5).first()
- 根据所提供的删除方法将信息删除
db.session.delete(user)
- 提交(使用manger可自动提交)
db.session.commit()
@app.route('/delete')
def delete_view():
id = request.args.get("id")
user = Users.query.filter_by(id=id).first()
db.session.delete(user)
url = request.headers.get("referer", '/query_all')
return redirect(url)
4.修改
- 查
- 改
- 保存
user = Users.query.filter_by(id=5).first()
user.uaername = "老杨"
user.passwd = "abcdefg"
return "修改成功"
@app.route('/update', methods=["GET", "POST"])
def update_view():
if request.method == "GET":
id = request.args.get('id') # 获取前端传过来的id
user = Users.query.filter_by(id = id).first() # 根据id查询出对应的实体对象
return render_template("03-update.html", u = user)# 将实体对象放到前端页面显示
else:
id = request.form['id']
username = request.form["username"]
passwd = request.form["passwd"]
user = Users.query.filter_by(id = id).first() #查
user.uaername = username # 改
user.passwd = passwd # 改
db.session.add(user) # 保存
return redirect("/info?tiaojian=")
Python Web 之 Flask的更多相关文章
- python web框架Flask——csrf攻击
CSRF是什么? (Cross Site Request Forgery, 跨站域请求伪造)是一种网络的攻击方式,它在 2007 年曾被列为互联网 20 大安全隐患之一,也被称为“One Click ...
- 【简说Python WEB】Flask应用的文件结构
目录 [简说Python WEB]Flask应用的文件结构 1.文件结构的目录 2.配置程序--config.py 3.app应用包 4.剥离出来的email.py 5.蓝本(BLueprint)的应 ...
- Python Web框架——Flask
简介 Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理 ...
- Python web框架 flask
Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架,对于Werkzeug本质是Socket服务端,其用于接收http请求并对请求进行预处理,然后 ...
- [flask/python/web] 解析flask web开发(Miguel著)一书第11章主页不显示博文表单的问题
---------------------------------------------以下内容2017.7.14更新---------------------------------------- ...
- python web开发-flask访问请求数据request
Request对象在web应用的开发中是一个非常重要的对象,主要用来获取用户发来的请求数据. 常用属性参考:http://docs.jinkan.org/docs/flask/api.html#fla ...
- python web开发-flask中response,cookies,session对象使用详解
Response响应对象: 当一个web请求被服务器处理完后,会返回用户请求的响应,这时候就要用到响应对象,根据响应给用户的形式不同,响应对象有以下几种处理方式 如果返回的是一个合法的响应对象,它会从 ...
- python web开发-flask中日志的使用
Flask使用日志记录的方式: 初始化flask应用实例 在flask中使用logger,需要初始化一个flask的应用 app = Flask(__name__) 2. 调用logger 直接调用l ...
- python web开发-flask连接sqlite数据库
在之前的文章中我们介绍了如何在centOS中安装sqlite数据库. Sqlite安装完成后,本节就用flask来连接和操作sqlite数据库. 1. 数据准备 先在sqlite3中创建一 ...
随机推荐
- pycharm remote debug
换工作了好久没写blog了,堕落了,哈哈,发现了好的东西分享一下,和以前使用的pycharm的远程debug相比,更为方便,原理同步本地和远程的代码,加载远程的环境运行,使用本地的代码+远程的环境,方 ...
- 深入学习OpenCV检测及分割图像的目标区域
准备1:OpenCV常用图片转换技巧 在进行计算机视觉模型训练前,我们经常会用到图像增强的技巧来获取更多的样本,但是有些深度学习框架中的方法对图像的变换方式可能并不满足我们的需求,所以掌握OpenCV ...
- MySQL8.0 zip压缩包版本 Windows下安装
MySQL zip压缩包版本 Windows下安装 Download MySQL Community Server 解压到相应的目录 我的解压目录:D:\Program Files\mysql-8.0 ...
- java性能优化--字符串优化处理
String对象 String对象是java中重要的数据类型,在大部分情况下我们都会用到String对象.其实在Java语言中,其设计者也对String做了大量的优化工作,这些也是String对象的特 ...
- ASP.NET Core on K8S深入学习(1)K8S基础知识与集群搭建
在上一个小系列文章<ASP.NET Core on K8S学习初探>中,通过在Windows上通过Docker for Windows搭建了一个单节点的K8S环境,并初步尝试将ASP.NE ...
- 【Git】Found a swap file by the name ".git/.MERGE_MSG.swp"
最近合并分支的时候总是遇到这个问题,导致合并之后还需要再提交一次--有点烦-- 解决方案: 在项目根目录(如/StudioProjects/demo/Leave)下,找到 .git/.MERGE_MS ...
- Python开发异步任务Celery的使用教程!
1. 生产者消费者设计模式 最常用的解耦方式之一,寻找中间人(broker)搭桥,保证两个业务没有直接关联.我们称这一解耦方式为:生产者消费者设计模式 2.中间人broker 示例:此处演示Redis ...
- Windows 下配置 Vagrant 环境
Vagrant是一个基于 Ruby 的工具,用于创建和部署虚拟化开发环境.它使用 Oracle 的开源VirtualBox虚拟化系统. Vagrant 在快速搭建开发环境方面是很赞的,试想一个团队中, ...
- 【原创】JAVA进程突然消失的原因?
引言 值此七夕佳节,烟哥放弃了无数妹纸的邀约,坐在电脑面前码字,就是为了给读者带来新的知识,这是一件伟大的事业! 好吧,实际情况是没人约.为了化解尴尬,我决定卖力写文章,嗯,一定是我过于屌丝! 好了, ...
- cinder支持nfs快照
[问题描述] cinder后端设置为NFS,磁盘创建快照失败. 日志里面发现了这个错误: VolumeDriverException: Volume driver reported an error: ...