欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

flask基础

时间:2023-09-02
一、flask安装和配置:

1、后端

服务器+wsgi+框架程序,flask是框架程序

2、前端

手机APP、浏览器、程序(爬虫)、urllib、urllib2、ajax

3、框架的核心

实现路由和视图(业务逻辑处理);

4、优势

dingo是重量级框架,提供了很多工具和组件,对后期扩展不友好;

5、flask的核心

werkzeug和jinja2(jinja2可以换)

6、flask扩展包:

Flask-SQLalchemy:操作数据库;Flask-migrate:管理迁移数据库;Flask-Mail:邮件;Flask-WTF:表单;Flask-script:插入脚本;Flask-Login:认证用户状态;Flask-RESTful:开发REST API的工具;Flask-Bootstrap:集成前端Twitter Bootstrap框架;Flask-Moment:本地化日期和时间;

7、虚拟环境:

cd ~/ :切换到家目录:ls -l: ls -a:cd .virtualenv: ls: 所有的虚拟环境cd flask_py2: 切换至某个虚拟环境cd bin:可执行的二进制文件;cd ..:返回上级目录;cd lib:所有的安装包;cd site-packages:可以修改第三方包中的源文件pip list :查看当前虚拟环境中安装了哪些包mkvirtualenv shop -p python3:创建虚拟环境shop,并指定python版本安装python包时加sudo,安装到系统环境中,并非虚拟环境中;

二、app对象的初始化和配置:

1、对象的初始化

__name__表示当前文件名字,如果这个文件为启动文件的话,__name__为 __main__app=Flask(__name__)表示以当前文件所在的目录为根目录,flask以这个模块所在的目录为根目录,默认以根目录下的static作为静态目录,以根目录下的templates作为模板目录,如果flask传的参数没有被找到,比如app=Flask('idbbkdsbkjabs'),flask会以当前文件为根目录Flask()的初始化参数:

import_name: static_url_path: 访问静态资源的默认名称,把在浏览器中访问的static换掉(120.0.0.1:5000/static/index.html换成120.0.0.1:5000/static1/index.html)static_folder: 静态文件的目录,默认‘static’template_folder: 模板文件的目录,默认‘templates’

2、app.run():

为简易的测试服务器

app.run(host='0.0.0.0',port=5000) # 既可以使用本地ip地址,又可以使用127.0.0.1访问,可以传debug

3、配置文件:

存值:

(1)app.config.from_pyfile(文件名) #指定文件名字,以当前根目录下的文件名查找(2)app.config.from_object(类名) # 从对象的方式导入,配置文件封装成类(3)app.config['DEBUG']=True # 指直接操作config的字典对象

取值

(1)app.config.get('')(2)app.config[''](3)current_app.config['']

三、视图函数的路由:

1、视图函数的路由规则:

app.url_map:可以查看整个flask的路由信息

返回Map([Rule'/'(HEAD,OPTIONS,GET)->index,...]) 路由 请求方式 视图函数名称

如果定义了两个相同的视图函数,路由也相同,则第一个会把第二个干掉一个视图函数可以添加多个路由url_for:通过视图函数名称找到路由,返回的是路由地址,即url

2、url中的传参:

(1)转换器(动态路由):127.0.0.1:5000/user/123

@apiBP.route('/user/', methods=['POST'])def login(user_id): """ 用户登录 """ print(user_id)默认的类型:int/float/path(和默认的相似,但也接受斜线),不加转换器类型的话,默认为字符串

(2)自定义转换器:

定义自己的转换器:

class ReqexConverter(Werkzeuq.rounting.baseConverter): def __init__(self,url_map,regex): # 调用父类的初始化方法 super().init() # 将自己使用的正则表达式的参数保存到对象的属性中, flask回去使用这个属性来进行路由的正则匹配 self.regex=regex def to_python(self,value): ''' 对regex值做更复杂的操作,传的值经过校验是正常的,则返回return中的值 路径中的值转换到python程序中 ''' return 处理过后的数据,即最终的mobile_id def to_url(self,value): return '15812345678'

将自定义的转换器添加到flask应用中

app.url_map.converters['re']=ReqexConverter

案例

@apiBP.route('/user/', methods=['POST'])def login(mobile_id): """ 用户登录 """ print(mobile_id) @apiBP.route('/index', methods=['POST'])def login(): """ 用户登录 """ url=url_for('send_sms',mobile='18611111111') # 相当于/send/15812345678 print(mobile_id)

四、request对象:

1、获取参数:

request.form:可以提取请求体中表单格式的数据:city=xxx&age=xxx&name=xxx,form表单中的参数;request.data:请求体中不是表单格式的数据,如json传过来的字符串;request.files['文件字段名']:返回的是文件对象

f=request.files['the_file']f.save('/download/test001.txt') # flask中文件特有的方法f.read()f.write()

五、abort函数、自定义错误,视图函数返回值:

1、abort函数的使用:

(1)视图函数中,可以使用abort(),终止视图函数执行,并将错误信息返回到前端。

可以传递状态码信息,必须是标准的http状态码:abort(404);传递详细信息(需要是Respoese对象):abort(Respoese());

2、自定义异常处理:

@app.errorhandler(404)def error(e): return '您请求的页面不存在了,请确认后再次访问!%s'%e

3、返回值信息:

(1)可以返回一个元组,这样的元组必须是 (response, status, headers) 的形式,且至少包含一个元素。 status 值会覆盖状态代码, headers 可以是一个列表或字典,作为额外的消息标头值。如果是列表,[(‘响应头1的名称’,‘响应头1的值’),(‘响应头2的名称’,‘响应头2的值’)];

(2)使用make_response

resp = make_response('响应体')resp.headers[“sample”] = “value”resp.status = “404 not found”

(3)返回json

@apiBP.route('/index')def index(): data={ 'name':'wmz', 'age':18 } # json_str=json.dumps(data) # return json_str,200,{'Content-Type':'application/json'} # jsonify将字典转换为json格式数据,并修改响应头为json return jsonify(data) return jsonify(city='shanghai',age=18)

六、cookie和session:

1、设置cookie

resp = make_response('响应体')

默认有效期是临时cookies,浏览器关闭即失效,max_age为有效期,单位为秒

(1)resp.set_cookies('Itcast','python',max_age=3600)(2)resp.headers['Set-cookies']='Itcast=python,Max-Age=3600'

2、操作cookies

获取cookies:request.cookies.get('Itcast')删除cookies:设置有效期,使有效期过期

resp = make_response('删除cookies')resp.delete_cookie('Itcast')

3、设置session数据

flask中session需要用到的秘钥字段

app.config['SECRET_KEY']='HAHAHHAHHAHAH'session['name']='python'session['age']=18

后端产生sessionId传给浏览器,浏览器下次再访问时,cookie中携带sessionId;flask把session数据保存在了cookie中,没有保存在后端服务器中;可以把session数据保存在数据库、redis、文件、程序内存中(定义一个全局变量)。

4、操作session数据

name=session.get['name']

七、flask上下文和钩子:

1、上下文

(1)请求上下文(request context),request和session都属于请求上下文对象,处理多个请求的情况;

request={'线程A':{'form':{'name':'zhangsan'},args:{}},'线程B':{'form':{'name':'lisi'},args:{}}}

(2)应用上下文(application context),处理有多个应用的情况;

current_app和g都属于应用上下文对象;current_app:表示当前运行程序文件的程序实例;g:处理请求时,用于临时存储的对象,每次请求都会重设这个变量。一次请求之内,需要调用多个函数,就可以用g变量来定义变量。

@apiBP.route('/index')def index(): data={ 'name':'wmz', 'age':18 } g.username='zhangsan' say_hello()def say_hello(): username=g.username

2、钩子

flask支持四种钩子:可以使用request方式进行处理:

before_first_request:在处理第一个请求前运行;

@app.before_first_requestdef handle_before_first_request(): print('在第一次请求前运行')

before_request:在每次请求前运行;

after_request(response):如果没有未处理的异常抛出,在每次请求后运行(前提是视图函数没有出现异常,必须有返回值);

teardown_request(response):在每次请求后运行,即使有未处理的异常抛出(不管视图函数是否有异常,都会执行,必须有返回值)。

3、flask-script

from flask-script import Manager # 启动命令的管理类manager=Manager(app) #创建manager的管理对象manager.run() # 启动flask,启动了之后,可以用命令执行

八、模板:

1、模板和自定义过滤器

return render_template('index.html',name='python')

2、模板中可以进行运算

{{myList[0]+myList[1]}}

3、默认的过滤器

(1)字符串过滤器:

safe:禁用转义;

{{ 'hello' | safe }}

capitalize:把变量值的首字母转成大写,其余字母转小写;

{{ 'hello' | capitalize }}

lower:把值转成小写;

{{ 'HELLO' | lower }}

upper:把值转成大写;

{{ 'hello' | upper }}

title:把值中的每个单词的首字母都转成大写;

{{ 'hello' | title }}

trim:把值的首尾空格去掉;

{{ ' hello world ' | trim }}

reverse:字符串反转;

{{ 'olleh' | reverse }}

format:格式化输出;

{{ '%s is %d' | format('name',17) }}

striptags:渲染之前把值中所有的HTML标签都删掉;

{{ 'hello' | striptags }}

支持链式使用过滤器:

{{ “ hello world “ | trim | upper }}

(2)列表过滤器

first:取第一个元素

{{ [1,2,3,4,5,6] | first }}

last:取最后一个元素

{{ [1,2,3,4,5,6] | last }}

length:获取列表长度

{{ [1,2,3,4,5,6] | length }}

sum:列表求和

{{ [1,2,3,4,5,6] | sum }}

sort:列表排序

{{ [6,2,3,1,5,4] | sort }}

4、自定义过滤器

(1)通过 add_template_filter (过滤器函数, 模板中使用的过滤器名字)

def filter_double_sort(ls): return ls[::2]app.add_template_filter(filter_double_sort,'double_2')

(2)通过装饰器 app.template_filter (模板中使用的装饰器名字)

@app.template_filter('db3')def filter_double_sort(ls): return ls[::-3]

5、处理表单

#设置csrf_token{{ form.csrf_token() }}{{ form.user_name.label }}

{{form.user_name}}

{% for msg in form.user_name.errors %}

{{msg}}

{% endfor %}{{form.user_name.errors}} # 校验失败的时候会弹出提示验证器中:user_name=StringField(label=u'用户名',validators=[DataRequired('这个是错误提示信息!')])submit按钮也需要被抽像

6、宏

(1)模板中多次使用的内容可以被定义为宏;

不带参数:

{% macro input() %} {% endmacro %}使用:{{ input() }}

带参数:

{% macro input2(type,value,size='30') %} {% endmacro %}使用:{{ input('password','name') }}

(2)外部引用:文件名可以自定义macro.html;

{% macro input() %} {% endmacro %}

在其它模板文件中先导入,再调用{% import 'macro.html' as func %}{{func.input()}}

7、模板的继承

父模板:

{% block top %}顶部菜单 {% endblock top %} {% block content %} {% endblock content %} {% block bottom %}底部 {% endblock bottom %}

子模板:

{% extends 'base.html' %} {% block content %} 需要填充的内容 {% endblock content %}

模板继承使用时注意点:

不支持多继承。为了便于阅读,在子模板中使用extends时,尽量写在模板的第一行。不能在一个模板文件中定义多个相同名字的block标签。当在页面中使用多个block标签时,建议给结束标签起个名字,当多个block嵌套时,阅读性更好。 九、数据库扩展包:

1、创建外键:

class User(UserMixin,base): """ 用户信息表 """ __tablename__ = 'sp_user' userid = Column(Integer, primary_key=True) user_name = Column(String(24),unique=True, nullable=False) # 用户名称 addresses=relationship('Address',backref='user')

class Address(base): """ 收货地址 """ __tablename__ = 'sp_address' addressId=Column(Integer, primary_key=True) userId=Column(Integer, ForeignKey('sp_user.userid')) # 创建人id provinceId=Column(Integer, nullable=False) # 省ID

2、查询数据

方法1:通过SQLA...方式查询db.session.query(Role).all()方法2:通过flask-sqla...方式查询Role.query.all()

3、条件查询

Role.query.filter(Role.name='管理员').all()Role.query.filter_by(name='管理员').all()

4、关联查询

user=User.query.get(1)user.Address # 可以返回userID等于1的所有地址信息address=Address.query.get(1)address.user #返回addressID等于1所属的人员信息

5、让查询出来的,在输出信息中的数据显示更直观

class User(UserMixin,base): """ 用户信息表 """ __tablename__ = 'sp_user' userid = Column(Integer, primary_key=True) user_name = Column(String(24),unique=True, nullable=False) # 用户名称 addresses=relationship('Address',backref='user') def __repr__(self): return 'User object name=%s' %self.user_name

6、更新操作

User.query_by(user_name ='zhou').update({'addresses':'上海'})

十、数据库迁移包,邮件扩展包:

pip install flask-migrate#coding=utf-8from flask import Flaskfrom flask_sqlalchemy import SQLAlchemyfrom flask_migrate import Migrate,MigrateCommandfrom flask_script import Shell,Managerapp = Flask(__name__)manager = Manager(app)app.config['SQLALCHEMY_DATAbase_URI'] = 'mysql://root:mysql@127.0.0.1:3306/Flask_test'app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = Trueapp.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = Truedb = SQLAlchemy(app)#第一个参数是Flask的实例,第二个参数是Sqlalchemy数据库实例migrate = Migrate(app,db) #manager是Flask-script的实例,这条语句在flask-script中添加一个db命令manager.add_command('db',MigrateCommand)#定义模型Roleclass Role(db.Model): # 定义表名 __tablename__ = 'roles' # 定义列对象 id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), unique=True) def __repr__(self): return 'Role:'.format(self.name)#定义用户class User(db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(64), unique=True, index=True) def __repr__(self): return 'User:'.format(self.username)if __name__ == '__main__': manager.run()

创建migrations文件夹,所有迁移文件都放在里面。

python database.py db init

创建自动迁移脚本

python database.py db migrate -m 'initial migration'

更新数据库

python database.py db upgrade

查看历史版本的具体版本

python database.py db history

复制具体版本号执行回退

python database.py db downgrade 版本号

十一、蓝图:

定义蓝图时,没有默认静态文件目录,需要手动定义,template_folder='templates';模板文件的查找顺序: 先去定义app时定义的模板目录查,定义app时默认的模板目录为根目录下的templates如果没有找到,再去定义蓝图的时候定义的模板目录里找。 十二、flask部署:

Gunicorn(绿色独角兽)是一个Python WSGI的HTTP服务器;WSGI:全称是Web Server Gateway Interface(web服务器网关接口),它是一种规范,它是web服务器和web应用程序之间的接口。它的作用就像是桥梁,连接在web服务器和web应用框架之间;uwsgi:是一种传输协议,用于定义传输信息的类型;uWSGI:是实现了uwsgi协议WSGI的web服务器。

gunicorn -w 4 -b 127.0.0.1:5000 -D --access-logfile ./ Logs/ Log main:app-D:以后台守护进程进行--access-logfile ./ Logs/ Log:日志文件(访问的历史记录)nginx(会保证轮着进行转发,访问每个服务的机会均等)

使用nginx部署,配置nginx.conf文件。

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。