python之 flask 框架(1)

这篇具有很好参考价值的文章主要介绍了python之 flask 框架(1)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

pycharm 查看方法的定义(类似.net 中 F12)
ctrl + 单击(对应的方法)
flask框架,python
flask框架,python

创建安装虚拟环境

两种方法
flask框架,python
flask框架,python
flask框架,python

第二种

# 先打开cmd 中断
# 查看virtual是否安装过
pip show virtualenv 
# 安装
pip install virtualenvwrapper-win
# workon 查看虚拟环境
vorkon
# 切换虚拟环境
# workon 虚拟环境 
# mkvirtualenv 创建新的虚拟环境
mkvirtualenv falsk2env
# 删除虚拟环境
#rmvirtualenv flask2env
#进入虚拟环境
workon flask2env

flask框架,python
flask框架,python
flask框架,python
flask框架,python
pip list 查看虚拟环境所有的包
pip freeze 查看自己安装的包
flask框架,python

创建Flask 项目

专业版pychram
flask框架,python
社区版 要手动创建
flask框架,python
flask框架,python
flask框架,python
flask框架,python
flask框架,python

from flask import Flask, render_template, jsonify

app = Flask(__name__)
# 路由可以多个对一个视图函数的
@app.route('/')
@app.route('/index/')
def index():
    # 返回值
    # 直接返回
    # return '<b>ZEN</b>'
    # 模板渲染
    # return render_template('index.html',name='123')
    # 返回json对象
    # return {'name':'Ares-Wang','Sex':'男'}
    # 返回json序列化
    return jsonify({'name':'Ares-Wang','Sex':'男'})

@app.route('/')
def home():
    return 'ARES-ZEN'
if __name__ == '__main__':
    app.run(host='0.0.0.0',debug=True)

flask框架,python

<!-- 引入css样式表    相对路径, 从根目录 -->
<!--    <link rel="stylesheet" href="../static/CSS/index.css">-->
<!--    <link rel="stylesheet" href="/static/CSS/index.css">-->
--url_for   反向解析
    <link rel="stylesheet" href="{{url_for('static',filename='CSS/index.css')}}">

Flask 项目拆分

flask框架,python

flask框架,python

# app.py
from APP import Create_App
app = Create_App()
if __name__ == '__main__':
    app.run(host='0.0.0.0',debug=True)


# views.py
# views.py   路径  +   视图函数
from flask import Blueprint
from .models import *
blue = Blueprint('BlueName', __name__)
@blue.route('/')
def Home():
    return 'SPlIT'


# __init__.py
# __init__.py :初始化文件、创建Flask应用
from flask import Flask
from .views import blue
def Create_App():
    # 返回Flask对象
    app = Flask(__name__)
    # print(app.config)
    # SECRET_KEY 是对称加密的密钥,存在浏览器的
    # session['xxx']='123',session 通过secret_key 把123 加密存在服务器端
    # 同时客户端cookie中存入cookieID 也是加密的 session 设置要配置secret_key
    # app.config['SECRET_KEY']='ZEN'
    # 设置session过期时间
    # app.config['PERMANENT_SESSION_LIFEATIME']=datetime.timedelta
    # 注册蓝图 可以注册多个蓝图
    app.register_blueprint(blueprint=blue)
    return app

路由参数

@app.route(‘/xxx/converter:variable_name’)

converter:参数类型
string:接受任何没有斜杠’/'的字符串 默认参数类型
int:接受整数
float:接受浮点数
path 接受路径, 可接受斜杠(’/‘)的字符串
uuid 只能接受uuid字符串,唯一码,一种生成规则 根GUID一样的
any 可以同时指定多种路径,进行限定

@app.route(‘/student//’) 与 @app.route(‘/student/string:username/’) 一样

@app.route(‘/student/int:id/’)
def get_student(id):
student= Student.query.get(id)

@app.route(‘/student/uuid:id/’)

@app.route(‘/student/float:num/’)

@app.route(‘/student/path:path/’)

@app.route(‘/student/<any(‘男’,女):gender>/’)

请求方法 常见POST GET
Flask 默认支持GET,不支持POST请求的
@app.route(‘/student/’)

同时支持get 、post 请求
@app.route(‘/student/’,methods=[‘GET’, ‘POST’])

flask框架,python

请求对象和响应对象 request response

request

服务器在接受客户端的请求后,会自动创建Request对象,有FLask框架创建,request对象不可修改

# requests 爬虫测试下面的请求对象
import requests
request = requests.get('http://127.0.0.1:5000/index/?user=123')
request = requests.post('http://127.0.0.1:5000/index/',data={'user':3456})
print(request.text)

flask框架,python
flask框架,python

from flask import Flask,request
@app.route('/index/>',methods=['GET',  'POST'])
def get_index():
    #   服务器在接受客户端的请求后,会   自动创建 Request 对象,由Flask 框架创建,request 对象不可修改,只能使用
	# 获取请求方式
	print(request.method)
	# url 完整请求地址    
	print(request.url)   		# http://127.0.0.1:5000/index/?user=123'
	# base_url   去掉get参数的url
	print(rquest.base_url)		# http://127.0.0.1:5000/index/
	# host_url   只有主机名和端口号
	print(rquest.host_url)		# http://127.0.0.1:5000/
	# remote_addr   请求的客户端地址
	print(request.remote_addr)   #IP地址
	# files 文件上传
	print(request.files)
	# 用户代理, 包括浏览器和操作系统的信息  反爬用的    类似 python-requests/2.31.0
	print(request.user_agent)
	# headers 请求头
	print(request.headers)
	# headers 请求中的cookie
	print(request.cookies)
	# 获取请求参数  get 请求,返回是字符串
	# request.args.get(key,defaultValue)   如果key,没有传参,可以赋默认值,
	print(request.args.get(key))
	# 返回是ImmutableMultiDict类型
	print(request.args)
	# 获取请求参数  post 请求
	print(request.from.get(key))
	#返回是ImmutableMultiDict类型
	print(request.from)

flask框架,python

ImmutableMultiDict类型
flask框架,python
Respone响应

# 导入模板渲染用的包
from flask import render_template, jsonify, make_response,Response
@app.route('/response/')
def  get_Response():
	# 响应的几种方式
	# 1、返回字符串(不常用)
	return 'AresZEN'
	# 2、模板渲染(前后端不分离) 在templates中创建模板 xx.html  中jinja2语法 {{}}  
	return render_template('xx.html',param1='' , param2='')
	# 3、返回json数据(前后端分离)
	return {'name':'Ares','age':30}
	# jsonify()  序列号    josn=>字符串
	return jsonify({'name':'Ares','age':30})
	# 4、自定义Response对象
	html= render_template('xx.html',param1='' , param2='')
	# 返回字符串(html格式的字符串)
	print(html,type(html))
	#  导入包make_response(返回的数据,状态码)
	res=make_response(html,200)   
	# res = Response(html)  跟上面效果一样
	res.set_cookie()  #  设置cookie
	#  上面任意一个都可以
	return res

Redirect 重定向

@blue.route('redirect')
def make_redirect():
	# 重定向的几种方式
	# return redirect('https://www.baidu.com')
	# return redirect('/路由/')   #  在程序中跳转

	# url_for():反向解析,通过视图函数名反过来找路由,    正常是通过路由找视图函数的,反向解析: 就是根据视图函数,找路由
	# url_for('蓝图名称.视图函数名')  #  注意是蓝图名称 ,不是蓝图对象   blue对象 = Blueprint('BlueName蓝图名称', __name__)
	# ret = url_for('蓝图名称.视图函数名')
	# return redirect(rect)

	# url_for 传参
	ret= url_for('蓝图名称.视图函数名',参数名=Value,参数名2=Value2)
	return redirect(rect2)

会话技术 Cookie和Session

flask框架,python
flask框架,python
设置cookie
flask框架,python

获取cookie
request.cookies.get(key)
删除cookie
response.delete_cookie(key)

cookie不能存中文

session

session服务器端会话技术,依赖于cookie
特点:
- 服务端的会话技术
- 所有数据存储在服务器中
- 默认存储在内存中
- 存储结构:key-value形式,键值对
- session 离不开cookie
- sessionID存储在客户端, session的值存在在服务端
flask框架,python
flask框架,python

session设置
session[‘key’]=‘value’
获取session 如果不存在,就返回 default指定的值
session.get(key,default=None)
删除session
session.pop(key) 删除某一值
session.clear() 清除所有session
flask框架,python

cookie VS session
cookie: ①存储在客户端(浏览器)②安全性较低③可以降低服务器压力
session:①存储在服务端(服务器)②安全性高③对服务器要求较高④仍然需要依赖cookie, 服务器生成的sessionID会返回给客户端,sessionID 存储在客户端。

模板Template

flask框架,python
flask框架,python

JinJa2 引擎的模板语法,及传参

模板语法主要分为两种:

  • 变量
  • 标签

模板中的变量 {{ 变量名 }} 变量不存在,默认忽略,不会报错
views 视图函数传递给模板的数据 return render_template(‘xxx.html’,参数1=value1,参数2=Value2)

或者
data ={ ‘age’ :20,‘name’:‘ZEN’ ,hobbys:[‘football’,‘basketball’]}
render_template(‘xxx.html’, **data)
模板中取值 {{ age }} {{name}}
{{ hobbys }} 返回是 [‘football’,‘basketball’] 的字符串 所以一般用for循环取值

循环 for

{% for hobby in hobbys %}
# segment
{% else %} #hobby 不存在了,就进入else 了。

segment

{% endfor %} 要有结束标签

使用 获取循环信息 loop

{% for hobby in hobbys %}

{{hobby}}


index:{{ loop.index }} # 从1开始的下标
index:{{ loop.index0 }} # 从0开始的下标
index:{{ loop.revindex }} # 反向下标,不包括0
index:{{ loop.revindex0 }} # 反向下标,包括0
index:{{ loop.first }} # 判断是否是第一个元素
index:{{ loop.last }} # 判断是否是最后一个元素

模板中的标签 {% tag %} 注意要有结束标签 注意要有结束标签
控制逻辑、使用外部表达式 创建变量 宏定义
{% if age >=18 %}

成年

模板继承

flask框架,python

<!-- 定义Base.html  模板页 -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ParentTemplate</title>
    <link rel="stylesheet" href="{{ url_for('static',filename='base.css') }}"/>
    {% block extcss %}
    {% endblock %}
</head>
<body>
    {% block head %}
    {% endblock %}
    {% block content %}
    {% endblock %}
    {% block foot %}
    {% endblock %}
    <script src="{{ url_for('static',filename='baseJS.js') }}"></script>
    {% block extjs %}
    {% endblock %}

</body>
</html>

在父模板挖坑

<!-- 定义inc.html  -->
<hr>
<h4>include文件</h4>
<hr>
<!-- 定义1.html  继承模板Base.html页 -->
{% extends 'Base.html'%}

{% block extcss %}
    <link rel="stylesheet" href="{{ url_for('static',filename='index.css') }}"/>
{% endblock %}
{% block head %}
<p>我是head标签</p>
{% endblock %}
{% block content%}
	{% include 'inc.html' %}
	<p>AAA</p>
{% endblock %}

在子模版填坑

在父模板Base.html挖坑,在子模版1.html填坑
include 包含,将其它的html包含进来

{% extends '1.html' %}
{% block content %}
{{super()}}
<p>AresZEN</p>
{% endblock %}
{# 定义 Python函数}
{% macro person(name.age) %}
	<b>姓名:{{ name }}, 年龄:{{ age }} </b>
{% endmarco %}

{% block foot %}
	{{ person('ZEN',27) }}
{% endblock %}
<!-- 定义2.html  继承模板1.html页 ,1.html又继承Base.html-->
{% extends '1.html' %}

{% block content %}
	<!-- 把父模版内容保留下来 -->
	{{super()}}
	<p>AresZEN</p>
{% endblock %}

flask框架,python

模型基础

flask框架,python
flask框架,python

安装 flask_sqlalchemy (用于ORM)
pip install flask_ sqlalchemy -i https://pypi.douban.com/simple
安装 flask_migrate (用于数据迁移 把数据库模型迁移到数据库中)
pip install flask_ migrate -i https://pypi.douban.com/simple
安装 pymysql (mysql 驱动)
pip install pymysql -i https://pypi.douban.com/simple

Flask中使用ORM
连接数据库需要指定配置

数据库模型的定义
一个数据库模型对应一个数据库中的表,所有的数据库模型都要基础ORM对象的Modle基类,即db.Model

#   models.py   模型  数据库
# 创建数据库模型
#	模型 	=》		数据库
#	类	 	=》		表结构
#	类属性 	=》		表字段
#	一个对象 =》		表的一个行数据
from .exts import db
class Account(db.Model):
	# 定义数据库的表名
	__tablename__ = "account"
	id = db.Column(db.Integer,primary_key=True, autoincrement=True)
	account = db.Column(db.String(10),unique=True,nullable=False)
	username = db.Column(db.String(30),nullable=False)
	# 定义显示信息   在模型类中,重写   __repr__   方法, 
    def __repr__(self):
        """定义之后,可以让显示对象的时候更直观"""
        return "User object : username =%s" % self.username 

# exts.py  插件管理


# 1、导入第三方插件
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate

# 2、 初始化对象
db = SQLAlchemy()   # ORM
migrate = Migrate() # 数据迁移

# 3、与app对象绑定
def init_exts(app):
    db.init_app(app=app)
    migrate.init_app(app=app,db=db)
#   __init__.py :初始化文件、创建Flask应用
import datetime

from flask import Flask

from .views import blue

from .exts import init_exts
def Create_App():
    # 返回Flask对象
    app = Flask(__name__)
    # ORM 数据库配置
    # SQLite 数据库连接不需要额外驱动,也不需要用用户名和密码  SQLite 一般是手机程序用的  本地数据库
    DB_URI='sqlite:///sqlite3.db'
    app.config['SQLALCHEMY_DATABASE_URI']=DB_URI # 配置连接数据库路径DB_URI
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=False   # 禁用对象追踪修改
    # 初始化插件
    init_exts(app=app)
    # 注册蓝图 可以注册多个蓝图
    app.register_blueprint(blueprint=blue)
    return app```

flask框架,python
数据迁移 : 就是把model模型在数据库中创建表

  1. 先在cmd 或Terminal 进入项目目录(可以把选择项目 拖入到terminal)(app.py所在目录)
  2. 返回执行如下命令
    1. flask db init # 创建迁移文件夹migrates,只能执行一次
    2. flask db migrate # 生成迁移文件
    3. flask db upgrade # 执行迁移文件的升级 数据库就有表啦 如果表结构变化要执行这个 把迁移中的改动应用到数据库中
    4. flask db downgrade # 执行文件中的降级

flask框架,python

配置mysql 前提 要存在这个数据库
DB_URI=’mysql+pymysql://root:root@localhost:3306/数据名‘

表的CRUD操作
要在视图函数操作数据模型,从而同步数据库

#  views.py 中
# 蓝图
from flask import Blueprint,render_template,request
from .models import *

# 蓝图
blue = Blueprint('bluename',__name__)
@blue.route('/')
def index():
	return render_template('index.html')
# 表单操作:CRUD操作
@blue.route('/accountadd/',methods=['GET','POST'])
def account_add():
	# 添加一个记录   Account 是类,定义在models.py
	u = Account()
	if request.method=='GET':
		u.account = request.args.get('account')
		u.username = request.args.get('username')
	else:
		u.account = request.from.get('account')
		u.username = request.from.get('username')	
	#  views.py中没有导入 exts为啥油db对象,因为db对象在models.py 导入了。   因此 views中导入model,相当于也导入了exts
	db.session.add(u)  			# 将u对象添加到session中	
	db.session.commit()			# 同步到数据库中
	return 'success!'

@blue.route('/accountaddall/')
def account_add():
	# 添加多条记录   Account 是类,定义在models.py
	users = []
	for i in range(1,10):
		u=Account()
		u.account = 'ZEN_'+str(i)
		u.username = 'Ares_'+str(i)	
		users.append(u)	
	#  views.py中没有导入 exts为啥油db对象,因为db对象在models.py 导入了。   因此 views中导入model,相当于也导入了exts
	# db.session.add_all(对象列表)
	try:
		db.session.add_all(users)  			# 将u对象列表添加到session中	
		db.session.commit()					# 同步到数据库中   事务提交
	except Exception as e:
		db.session.rollback()				# 回滚
		db.session.flush()					# 把session中数据清理掉											
		return 'fail: '+ str(e)
	return 'success!'

@blue.route('/accountdelete/')
def account_del():
	try:
		u=Account.query.first() # 查询第一条数据
	    db.session.delete(u)
	    db.session.commit()
	 except Exception as e:
	 	db.session.rollback()
	 	db.session.flush()  
    return 'success!'
 
@blue.route('/accountupdate/')
def account_update():
	try:
		u=Account.query.first() # 查询第一条数据
		u.username='yyds'	   
	    db.session.commit()
	 except Exception as e:
	 	db.session.rollback()
	 	db.session.flush()  
    return 'success!'



#  查询数据
@blue.route('/userget/')
def user_get():

	# all(): 以列表形式返回查询的所有结果,返回列表
	# users = Account.query.all()
	# first() 返回查询的第一个结果,如果没有结果,则返回None
	# user = Account.query.first()   可以继承  过滤器
	# filter() 把过滤器添加到原查询上,返回一个新查询,可以继续   . 过滤器
	# users = Account.query.filter()   可以继承  过滤器
	# user = Account.query.filter(Account.username=='yyds')
	# filter_by() 把**等值**过滤器添加到原查询上,返回一个新查询
	
	#  filter_by() 与  filter()  区别
	
	# user = Account.query.filter_by(username='yyds')
	# count() 返回查询结果的数量
	# users = Account.query.filter()  可以继承  过滤器
	print(users.count())
	# first_or_404() 返回查询的第一个结果,如果没有结果,则终止请求,返回404错误响应
	# user = Account.query.filter_by(username='yyds').first_or_404()
	# get()  返回指定主键对应的行,如果没有对应的行,则返回None ,此处家人username是主键
	# user = Account.query.get(username='yyds')
	# get_or_404()  返回指定主键对应的行,如果没有找到指定的主键,则终止请求,返回404错误响应
	#user = Account.query.get(username='yyds')
	# limit()  取前面几条 使用指定的值限制原查询返回的结果数量,返回一个新查询  可以继承 过滤器
	# offset() 跳过前几条 偏移原查询返回的结果,返回一个新查询  ,可以继承  过滤器
	# users = Account.query.offset(3).limit(4)
	# order_by()   排序  升序
	# users = Account.query.order_by('id')
	# order_by()       排序     降序     需要到包   from sqlalchemy import desc
	# users = Account.query.order_by(desc('id'))
	
	# 逻辑运算符   and_    ,    or_     ,  not_
	users = Account.query.filter(Account.username='yyds' , Account.id < 100)    #  且    默认
	#   需要到包   from sqlalchemy import and_ , or_ , not_
	users = Account.query.filter(and_(Account.username='yyds', Account.id < 100) #  且
	
	#  查询属性
	# contains   模糊查询   类似 sql  like
	users = Account.query.filter(Account.username.contains('yd'))
	# in_()   其中只有   类似  sql  in
	users = Account.query.filter(Account.username.in_(['yyds','jjz']))
	# startswith():			以某字符串开头
	# endswith():			以某字符串结尾
	users = Account.query.filter(Account.username.startswith('yy'))
	
	# __gt__     大于
	# __ge__     大于等于
	# __lt__	 小于
	# __le__	 小于等于
	users = Account.query.filter(Account.id.__gt__(300))
    return 'success!'

分页

flask框架,python

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<ul>
	{%  for item in Accounts %}
	    <li>{{ item.username }}</li>
	{% endfor %}
</ul>
</body>
</html>
@blue.route('/paginate/')
def get_info():
    page = int(request.args.get('page', 1))
    per_page = int(request.args.get('per_page', 5))
    Accounts = Account.query.paginate(
        page=page,
        per_page=per_page
    ).items
    return render_template('info.html', Accounts)

多表关联


##  model.py   一对多 案例
# models.py   模型  :和数据库相关的
from .exts import db
"""
 department :employee =》 1:N     1对多
外键要设置在 N: 多的 一个表  
"""
# 创建 department 部门表 即 Department 模型
# 模型需要继承db.Model,否则就普通的类
class Department(db.Model):
	# 表名
	__tablename__ = 'department'
	id = db.Column(db.Integer, primary_key=True, autoincrement=True)
	# 部门编号
	deptCode = db.Column(db.String(30), nullable=False)

	# 建立关联
	#		第一个参数:关联的模型名,因python语言是解释性语言,Employees, 需要需要 用  ''
	#		第二个参数:反向引用的名称,department 对象
	#				让employee去反过来得到department对象的名称    employee.department  是个department对象
	#		第三个参数: 延迟加载,懒加载,    用到的时候,才会建立关系,懒加载:为了提高性能,节约资源
	# 这里departments不是字段,不是字段 是类的属性
	employees = db.relationship('Employees', backref='department', lazy=True)

	"""
	查询员工所属的部门,反向引用department
	emp = Employee.query.get('emp_Code值')
	#  department 要跟  backref对应的值保持一致   
	#  emp.department   返回是department对象
	dept = emp.department   
	code=dept.deptCode	
	查询某部门下面的所有员工
	dept = Department.query.get('deptCode值')
	dept.employees  #  所有部门编码下的员工信息  返回是employee 对象列表
	"""
# 创建employee 员工表 即 Employee 模型
# 模型需要继承db.Model,否则就普通的类
class Employee(db.Model):
	# 表名
	__tablename__ = 'employee'
	id = db.Column(db.Integer,  autoincrement=True)
	# 员工姓名
	emp_name = db.Column(db.String(30), nullable=False)
	# 员工编号
	emp_Code = db.Column(db.String(30),nullable=False, unique=True, primary_key=True)

	# 外键 也是字段,  跟 员工表的 员工编号关联  1:N  外键也放在N的表中
	# 实现一对多关系,要在对应的表 添加 db.relationship
	department = db.Column(db.String(30),db.ForeignKey(Department.deptCode), nullable=False, unique=True)


flask框架,python

多对多关系表 N:M

N:M 多对多关系,还存在两个表的中间表:关联作用
flask框架,python
flask框架,python

# models.py
from .ext import db
# usermodel  和  usermodel  建立关联表
collect = db.Table(
	# 表名
	'collects',
	#  组合主键
	# 字段
	db.Column('user_id',db.Integer,db.ForeignKey('usermodel.id'),primary_key=True)
	db.Column('sysmodel_id',db.Integer,db.ForeignKey('sysmodel.id'),primary_key=True)
)
# 用户表
Class UserModel(db.Model):
	__tablename__='usermodel'
	# 字段
	id = db.Column(db.Integer,primary_key=True,autoincrement=True)
	username = db.Column(db,String(30))
	userCode = db.Column(db.String(30),)
# 系统模块
Class SysModel(db.Model):
	__tablename__:'sysmodel'
	id = db.Column(db.Integer,primary_key=True,autoincrement=True)
	name = db.Column(db.String(30))
	# 关联
	# secondary=collect:  设置中间表
	users =db.relationship('UserModel',backref='sysmodels',lazy=True,secondary=collect)
# views.py   
"""
用户表和系统模块表 追加数据略
"""
@blue.route('/addcollect/')
def add_collect():
	# 用户拥有的系统模块
	user = UserModel.query.get('key')
	sysmodel = SysModel.query.get('key')
	# user.sysmodels 是反向查询的  backref='sysmodels'
	user.sysmodels.append(sysmodel)
	db.session.commit()
	return 'success!'

@blue.route('/getcollect/')
def get_collect():
	# 查询某用户拥有的系统模块
	user = UserModel.query.get('key')
	print(user.sysmodels)  #  返回list
	# 查询系统模块拥有的用户
	sysmodel = SysModel.query.get('key')
	print(sysmodel.users) # 返回是查询集  可以继续用filter 、filter_by过滤方法
	print(list(sysmodel.usrs))  返回list
@blue.route('/deluser/')
def del_user():
	# 多对对 关联删除是级联删除,跟1对多删除不一样, 1对多, 1的一方删除数据,多的一方 对应数据外键 null
	user = UserModel.query.get('key')
	db.session.delete(user)
	db.session.commit()
	#  删除用户,对应用户在中间表collect中记录也会删除。

flask框架,python

插件管理 值 flask-caching

安装:

pip install flask-caching # 是连接符,不是下划线

# exts.py  插件管理

# 1、导入第三方插件
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
# 是下划线,不是连接符
from flask_caching import Cache
# 2、 初始化对象
db = SQLAlchemy()   # ORM
migrate = Migrate() # 数据迁移
cache = Cache(config = {
	'CACHE_TYPE':'simple'
})
# 3、与app对象绑定
def init_exts(app):
    db.init_app(app=app)
    migrate.init_app(app=app,db=db)
    cache.init_app(app=app)

flask框架,python

cache 应用

# views.py
# @ 装饰器
@blue.route('/')
@cache.cached(timeout=20)    @ 开始访问(执行里面的代码),第二个方法缓存(不执行代码),缓存有效期20s,超时,会再次访问执行里面的代码
def home():
	print('xxx')
	# 模拟访问复杂的逻辑运算
	time.sleep(5)
	return 'ZEN'

钩子函数= 中间件,类似AOP框架拦截,类似Vue中的挂载点

钩子函数(中间件 MIddleware)是执行函数(视图函数)和目标函数之前挂载的函数,框架开发者给调用方提供一个point-挂载点
是一个AOP切面编程思想
常用钩子函数

  1. before_first_request:处理第一次请求之前执行
  2. before_request: 在每次请求之前执行。通常使用这个钩子函数预处理一些比哪里,实现反爬 request.user_agent等
  3. after_request: 注册一个函数,如果没有未处理的异常抛出,在每次请求之后运行
  4. teardown_appcontext: 当app上下文被移除之后的函数,可以进行数据库的提交或者回滚

用爬虫访问 如果没有做反爬 (headers没配置 cookie、user-agent)
request.user_agent.string # python-requests/2.28.2 类似这种结果
flask框架,python

from .exts import *
# views.py 
#钩子函数不需要配置路由
@blue.before_request
def before():
	ip=request.remote_addr
	# cache.get()   cache.set()
	if cache.get(ip):
		# 做了拦截,不会进入视图函数
		return '禁止爬虫访问!'
	else# 对每个IP配置一个缓存,1秒内不让重复访问
		cache.set(ip,'value',timeout=1)
	# string 别忘记
	if "python" in request.user_agent.string:
		return "禁止用python爬虫"
	
	
# @ 装饰器
@blue.route('/')
@cache.cached(timeout=20)    @ 开始访问(执行里面的代码),第二个方法缓存(不执行代码),缓存有效期20s,超时,会再次访问执行里面的代码
def home():
	print('xxx')
	# 模拟访问复杂的逻辑运算
	time.sleep(5)
	return 'ZEN'

flask框架,python

Flask 内置对象

flask框架,python

# views.py   钩子函数
@blue.before_request
def before():
    # Flask内置对象
    # request :   请求对象
    # session  :  会话对象
    # g    :  global 全局对象
    # current_app   Flask应用对象
    g.xx = 'yyds'

flask框架,python

flask框架,python
默认 static、templates 跟__init__.py 是平级的, app=Flask(name
如果不是平级 要在初始化app=Flask(name,static_folder=‘路径’,template_folder=‘路径’)
flask框架,python

前端后端分离 值 Flask-RESTful

render_template 模板渲染 是前端和后端混在一起的
.net 中基于MVC框架的 webapi 是专门做接口的,后端的, python值flask框架提供了flask-restful包

render_template 用在views.py中的,是 # 视图函数: FBV Function Based View 路由用@装饰器
类视图 : CBV Class Based View 不需要是使用后端分离的, 不需要有views.py 不用路由@装饰器

flask-restful

安装
pip install flask-restful

# exts.py  插件管理
# 1、导入第三方插件
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
# 是下划线,不是连接符
from flask_caching import Cache
#  注意是Api
from flask_restfull import Api
# 2、 初始化对象
db = SQLAlchemy()   # ORM
migrate = Migrate() # 数据迁移
cache = Cache(config = {
	'CACHE_TYPE':'simple'
})
api = Api(# 3、与app对象绑定
def init_exts(app):
    db.init_app(app=app)
    migrate.init_app(app=app,db=db)
    cache.init_app(app=app)
    api.init_app(app=app)

flask框架,python
app.py
运行前先加载__init__.py
init.py中会加载三个包
from flask import Flask
– 插件管理—
from .exts import init_exts
– 路由—
from .urls import *

在执行app.py 的Create_App(),创建flask对象, 同时给这个flask对象绑定插件

flask框架,python

#	app.py
# Create_APP 写在__init__.py 中,所以导入把 要 包名 APP
from APP import Create_App
app = Create_App()
if __name__ == '__main__':
    app.run(host='0.0.0.0',debug=True)
# __init__.py :初始化文件、创建Flask应用
from flask import Flask
from .exts import init_exts
from .urls import *
def Create_App():
    # 返回Flask对象
    app = Flask(__name__)
    # 初始化插件,创建的app应用,附加了哪些插件
    init_exts(app=app)
    return app

# exts.py  插件管理  三部曲
# 1、导入第三方插件
from flask_restful import Api
# 2、 初始化对象
api=Api()
# 3、与app对象绑定
def init_exts(app):
    api.init_app(app=app)

flask框架,python

# apis.py  接口用的
from flask_restful import Resource
# 类视图  : CBV  Class  Based View
# 视图函数: FBV   Function Based View
# 继承Resource
class StudentResource(Resource):
    def get(self):
        return '我是get 请求'
    def post(self):
        return '我是Post请求'
# urls.py   路由文件
from .exts import api
from .apis import *
#  注册路由				api.add_resource(类视图 ,路由)
api.add_resource(StudentResource,'/stu/')

flask框架,python

字段格式化

为了定义规范接口输出数据格式,要对字段格式化
分两步:
1、fields进行定义
2、在接口用@装饰器修饰 @marshal_with(需要返回的数据格式)

说明:
如果返回的数据在预定义的结构中存在,数据会正常返回
如果返回的数据比预定义结构中字段少,预定义的字段会呈现默认值。默认值也可以设定
如果返回的数据不在预定义结构中,则数据会被自动过滤(舍弃)

flask框架,python
flask框架,python

#	apis.py
from flask_restful import Resource,fields,marshal_with

# 输出字段格式
ret_info={
    'name':fields.String,
    'age':fields.Integer,
    'SchoolName':fields.String,
    'address':fields.String
}
# 输出字段格式
ret_fields={
    'status':fields.Integer,
    'isSecces':fields.String(default='fail'),
    #  对方用data,其实映射是password数据的值
    'data':fields.String(attribute='password'),
    'msg':fields.String,
    'studentinfo':fields.Nested(ret_info)
}
# 继承Resource
class StudentResource(Resource):
    @marshal_with(ret_fields)
    def get(self):
    	# Student是models.py 需要数据迁移
        stu=Student.query.first()
        return {
            'status':200,
            'isSecces':'ok',
            'msg':'win',
            'password':'123',
            # Student信息
            'studentinfo':stu
        }

ret_fields2={
    'status':fields.Integer,
    'isSecces':fields.String(default='fail'),
    #  对方用data,其实映射是password数据的值
    'data':fields.String(attribute='password'),
    'msg':fields.String,
    'studentinfo':fields.List(fields.Nested(ret_info))
}
class StudentALLResource(Resource):
    @marshal_with(ret_fields2)
    def get(self):
    	# Student是models.py 需要数据迁移
        stu=Student.query.all()
        return {
            'status':200,
            'isSecces':'ok',
            'msg':'win',
            'password':'123',
            # Student信息
            'studentinfo':stu
        }
"""
# 返回的结果
{
    "status": 200,
    "isSecces": "ok",
    "data": "123",
    "msg": "win",
    "studentinfo":[
	    {
			"name":"ZEN",
			"age":33,
			"SchoolName":"家里蹲",
			"address":"中国"
		},   {
			"name":"ZEN1",
			"age":331,
			"SchoolName":"家里蹲1",
			"address":"中国1"
		}
	]

}
"""  
ret_url={
	'name':fields.String,
	'url':fields.url(endpoint='id',absolute=False)
}
class urlResource(Resource):
    @marshal_with(ret_url)
    def get(self):    	
        return {
            'name':200,
            'url':'/'                   
        }
"""
# 返回的结果
{
    "status": 200,
    "isSecces": "ok",
    "data": "123",
    "msg": "win",
    "studentinfo":{
		"name":"ZEN",
		"age":33,
		"SchoolName":"家里蹲",
		"address":"中国"
	}

}
"""
# urls.py   路由文件
from .exts import api
from .apis import *
#  路由
api.add_resource(StudentResource,'/')
api.add_resource(urlResource,'/url/',endpoint='id')
api.add_resource(StudentALLResource,'/stuall/')

参数解析

可以不通过post : request.form 或 get : request.args 获取参数。而是通过reqparse.RequestParser 来解析文章来源地址https://www.toymoban.com/news/detail-849218.html

# apis.py 
from flask_restful import Resource,reqparse
# 参数转换器
parser = reqparse.RequestParser()
parser.add_argument('name',type=str)
parser.add_argument('info',type=str,action='append') # 支持多个info
parser.add_argument('cookiex',type=str,location='cookies') # 获取cookies中数据
class StudentResource(Resource):
    def get(self):
        # 获取参数
        args=parser.parse_args()
        name=args.get('name')
        return {
            'key':name
        }
# spider.py  爬虫测试
import requests

request = requests.get('http://127.0.0.1:5000/',
                       json={
                           'name':'23',
                           'info':['123','erew']
                       },
                       headers={
                           'Content-Type':'application/json'
                       }
                       )
print(request.text)

到了这里,关于python之 flask 框架(1)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【小沐学Python】Python实现Web服务器(Flask框架扩展:Flask-Admin)

    flask作为一个微框架,Flask 允许您以很少的开销构建 Web 服务。 它为您(设计师)提供了自由,以适合您的方式实施您的项目 特定应用。 一个最小的 Flask 应用如下: Flask-Admin是一个batteries-included,易于使用的Flask扩展,可让您 向 Flask 应用程序添加管理界面。它的灵感来自 d

    2024年02月02日
    浏览(67)
  • Python-Web框架flask使用

    目录 1.Web框架 1.1 flask 1.1.1 debug调试  1.1.2 定义参数web服务 获取字符串 ​编辑 1.1.3 html网页渲染 1.13.1 带参数传给网页文件 普通元素 列表元素  字典元素 python的web框架,目录结构如下: 1.static存放的是css,js的样式文件 2.templates存放的是html文件 3.app.py是主要接口入口,默认创

    2024年02月16日
    浏览(45)
  • Python flask-restful 框架讲解

    Django 和 Flask 一直都是 Python 开发 Web 的首选,而 Flask 的微内核更适用于现在的云原生微服务框架。但是 Flask 只是一个微型的 Web 引擎,所以我们需要扩展 Flask 使其发挥出更强悍的功能。 python flask框架详解:https://blog.csdn.net/shifengboy/article/details/114274271 Flask-RESTful Flask-RESTful 就

    2024年02月13日
    浏览(31)
  • Python光速入门 - Flask轻量级框架

            FlASK是一个轻量级的WSGI Web应用程序框架,Flask的核心包括Werkzeug工具箱和Jinja2模板引擎,它没有默认使用的数据库或窗体验证工具,这意味着用户可以根据自己的需求选择不同的数据库和验证工具。Flask的设计理念是保持核心简单,同时提供强大的扩展性,用户

    2024年03月14日
    浏览(40)
  • Python第三方库 - Flask(python web框架)

    1.1 认识Flask Web Application Framework ( Web 应用程序框架)或简单的 Web Framework ( Web 框架)表示一个库和模块的集合,使 Web 应用程序开发人员能够编写应用程序,而不必担心协议,线程管理等低级细节。 1.2 Pycharm安装与简单测试 1.2.1 安装 Pycharm 安装 Flask 框架 File → Settings →

    2024年04月28日
    浏览(32)
  • python后端接口框架Flask的基本用法

    在现代Web开发中,后端接口是十分重要的一部分。它们建立了前端和后端之间的连接,使得数据能够在两者之间传递。Python是一门受欢迎的动态编程语言,它可以用来编写高效且功能强大的后端接口。本文将介绍如何使用Python编写后端接口,以及Python作为后端接口语言的优点

    2024年02月15日
    浏览(27)
  • 面试之 Python 框架 Flask、Django、DRF

    Django:大而全的框架。它的内部组件比较多,如 ORM、Admin、中间件、Form、ModelForm、Session、缓存、信号、CSRF等,功能也都很完善。 flask:微型框架,内部组件就比较少了,但是有很多第三方组件来扩展它,比如 wtform(与django的modelform类似,表单验证)、flask-sqlalchemy(操作数

    2024年02月05日
    浏览(39)
  • Python Web开发:Django与Flask框架

    Django和Flask都是Python中非常受欢迎的Web开发框架。虽然它们都是用于构建Web应用程序的工具,但它们在设计理念、使用方式和适用场景等方面存在一些差异。 Django Django是一个“大而全”的框架,遵循MVC设计模式。它内置了很多功能,如ORM(对象关系映射)、模板引擎、表单处

    2024年02月22日
    浏览(43)
  • Python Flask框架-开发简单博客-项目布局、应用设置

    作者:Eason_LYC 悲观者预言失败,十言九中。 乐观者创造奇迹,一次即可。 一个人的价值,只在于他所拥有的。所以可以不学无术,但不能一无所有! 技术领域:WEB安全、网络攻防 关注WEB安全、网络攻防。我的专栏文章知识点全面细致,逻辑清晰、结合实战,让你在学习路

    2024年02月02日
    浏览(38)
  • Python web 框架对比:Flask vs Django

    哈喽大家好,我是咸鱼 今天我们从几个方面来比较一些现在流行的两个 python web 框架——Flask 和 Django,突出它们的主要特性、优缺点和简单案例 到最后,大家将更好地了解哪个框架更适合自己的特定需求 参考链接:https://djangocentral.com/flask-vs-django-selecting-the-perfect-python-web

    2024年02月11日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包