Flask第三方模块部分汇总

1.Flask配置文件之from_object篇

app = Flask(__name__)
app.config.from_object(Flask.config[config_name])
Flask.config[config_name].init_app(app)

#app是通过Flask创建的,app的config方法肯定是从Flask类里面获得的
查看原码可以发现app的config属性的定义
self.config=self.make_config(instance_relative_config)

make_config(instance_relative_config)这个函数定义的内容
def make_config(self,instance_relative=False):
    return self.config_class(root_path,self.default_config)
#最终返回的是一个config_class方法,它是一个类对象,这个类对象是从Config类而来。

#这种方式的效果是直接从文件中加载对项目的配置

2.flask第三方扩展之Moment模块

Moment.js 是一个简单易用的轻量级JavaScript日期处理类库,提供了日期格式化、日期解析等功能。
它支持在浏览器和NodeJS两种环境中运行。此类库能够 将给定的任意日期转换成多种不同的格式,具有
强大的日期计算功能,同时也内置了能显示多样的日期形式的函数。另外,它也支持多种语言,你可以
任意新增一种 新的语言包。
#首先初始化Flask-Moment
from flask.ext.moment import Moment
moment = Moment(app)

在base.html模板种的head标签中导入moment.js,jquery.js
<html>
    <head>

        {{ moment.include_jquery() }}
        {{ moment.include_moment() }}

        <!--使用中文,默认是英语的-->
     {{ moment.lang("zh-CN") }} 
     
</head> <body> ... </body> </html>
使用Flask-moment

from flask import render_template
from datetime import date
@main.route('/')
def index ():
    return render_template('index.html', time = date(1994,8,29))
#在模板中渲染
<p>现在时间时: {{ moment().format('YYYYMD日, h:mm:ss a') }}.</p>
<p>已经过去了: {{ moment().fromTime(time) }}.</p>
<p>{{ moment().calendar() }}.</p>

结果:

现在时间时: 2015年4月22日, 10:06:33 上午.

已经过去了: 21年内.

今天上午10点06.

3.flask扩展之flask_login模块

这里将详细讲述flask_login模块的使用流程和机制

1.使用前首先要配置和初始化

from flask_login import LoginManager
login_manage=LoginManager()

def init_ext(app):
    login_manage.init_app(app)
   #这里要指定登陆函数的端口,以方便login跟踪操作
    login_manage.login_view='main.login'
    这个配置的是当给视图加@login_required的时候非登陆用户操作出现的message
    login_manage.login_message='需要登陆才能执行此操作'
    login_manage.login_message_category='info'
    #设置对session的保护等级
    login_manage.session_protection='strong'

2.配置完成后,我们要在模型中实现一个继承和回调

from flask_login import UserMixin
from App.extensions import login_manage

#如果不继承UserMixin是无法满足使用flask_login的条件的
class User(db.Model,UserMixin):
    __tablename__='user'
    id=db.Column(db.Integer,primary_key=True)
    username=db.Column(db.String(10),unique=True)
    password=db.Column(db.String(128))
    sex=db.Column(db.Boolean,default=1)
    email=db.Column(db.String(100),unique=True)

#这个回调是用来接收一个用户id的时候返回一个用户对象
#如果没有会返回None但是不会报错
@login_manage.user_loader
def load_user(uid):
    return User.query.get(int(uid))

3.好了,基本配置已经完成了,现在我们来看看flask_login怎么使用

#蓝本(视图函数)当中
from flask_login import current_user,login_user,logout_user,login_required

main=Blueprint('main',__name__)
@main.route('/login/',methods=['GET','POST'])
def login():
    form=Login()
    if form.validate_on_submit():
        u = User.query.filter(User.username==form.username.data).first()
        if not u:
            return '用户不存在'
        elif not u.password==form.password.data:
            return '密码输入有误'
        #直接通过此方法可以实现用户的登入,其实就是将用户的id存到session当中
        login_user(u)
        #如果需要实现记住我,请在form表单里添加相关字段
        return render_template('success.html')
    return render_template('login.html',form=form)

@main.route('/logout/',methods=['GET','POST'])
def logout():
    #此函数的作用是实现用户的登出,其实就是从session中删除用户的id
    logout_user()
    return  redirect(url_for('main.main_s'))

@main.route('/picture/')
#此装饰器限制的是一些只有登陆才能进行的操作,如果没有登陆,会重定向到用户登陆页面
#同时将提示信息存入flash当中
@login_required
def picture():
    return render_template('picture.html')
picture.html中
#如果是非登陆用户执行越权限操作被传送过来,想显示相关flash内容
#这里是从消息中取出对应flash内容
{%  for message in get_flashed_messages() %}
            <div class="alert alert-warning alert-dismissible" role="alert" style="text-align: center;font-size: 30px">
                <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span>
                </button>
                <strong>Warning!</strong>{{message}}
            </div>
         {% endfor %}
除此之外,还有一些非常方便的操作
1.判断是否是当前登陆用户在操作:
 {% if current_user.is_authenticated %}{% end if %}
2.如果想使用当前用户的代理用户
from flask_login import current_user
会得到当前用户对象的代理对象,在任何地方都可以使用,类似于将用户的id从session当中取出,然后在数据库当中匹配得到对应的对象,不过这里使用的是一个代理对象
3.如果要使用真正的当前用户(比如根据当前用户搜索内容,发帖子)
u = current_user._get_current_object()
********
current_user如果此时是非登陆的用户,那么它代表的就是一个
<flask_login.mixins.AnonymousUserMixin object at 0x000001F00664BF28>
一个匿名用户对象
如果此时是登陆用户:
那么它代表的就是用户本身,跟_get_current_object()表示的是一样的,是一个用户对象
<class 'App.models.user.User'>
*******
补充:
如果想在除setting之外地方获取setting的配置信息,可以使用App代理
例如:
    current_app.config['UPLOADED_PHOTOS_DEST']

4.fllask_uploads模块

1.原生上传

在使用up_loads模块之前,有一个不得不提的原生上传文件的几个知识点

1.form表单里面如果不设置它会把你的请求当成get请求来处理

2.request.files得到的是一个类似字典的形式,key是你在传文件里面给定的name属性,value是你上传的文件

3.有一个很巧妙的方法:img.save(path) path要给定包含名字在内的路径,可以快速将文件保存

2.使用模块上传

from flask_uploads import UploadSet,patch_request_class,IMAGES,configure_uploads
from flask import Flask,render_template,request
from flask_script import Manager
from flask_uploads import UploadSet,IMAGES,patch_request_class,configure_uploads
import os

app = Flask(__name__)
app.config['MAX_CONTENT_LENGTH'] = 1024*1024*64  判断大小的字节数
app.config['UPLOADED_PHOTOS_DEST']=os.path.join(os.getcwd(),'static/upload')配置参数固定了,后面文件会直接上传到配置好的文件夹中

file = UploadSet('photos',IMAGES)  
pthotes是图片参数,IMAGES是过滤条件
上传文件对象配置(IMAGES是过滤图片类型的)
configure_uploads(app,file)
pathch_request_class(app,size=None) 如果size为none则自动寻找MAX_CONTENT_LENGTH
(setting为最终的配置的文件app.config)
app.config['MAX_CONTENT_LENGTH']自己可以配置文件尺寸

(manager一般是放在最后,用来运行文件)
manager = Manager(app)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/upload/',method=['GET','POST'])
def upload():
    img_url = None
    if request.method=='POST' and 'file' in request.files:
        #文件上传
        fileName = file.save(request.files.get('file'))
        print(fileName) 可以看到保存成功了
        img_url = file.url(filename) #只要告诉名称就可以返回完整的路由地址    
        print(img_url)

    return render_template('flask-uploads-form/form.html',img_url=img_url)


if __name__ = "__main__":
    manager.run()

实际应用中可能会用到拆分,请把上传文件的配置分别拆分到extentsion和setting中

5.flask发送邮件的方法之flask_mail模块

from flask import Flask,render_template_string
from flask_script import Manager
from flask_mail import Mail,Message
import os
from threading import Thread   #导入线程

app = Flask(__name__)

#这里使用的是163邮箱的服务器地址
app.config['MAIL_SERVER']=os.environ.get('MAIL_SERVER','smtp.163.com')

app.config['MAIL_USERNAME']=os.environ.get('MAIL_USERNAME','这里输入发邮件的邮箱号')
app.config['MAIL_PASSWORD']=os.environ.get('MAIL_PASSWORD','邮箱密码')

mail = Mail(app)
manager=Manager(app)



def async_send_mail(msg):
    with app.app_context():
        mail.send(message=msg)

@app.route('/send/')
def send_mail():
    msg = Message(subject='我是主题', recipients=['[email protected]'], sender=app.config['MAIL_USERNAME'])
    msg.html = render_template_string('<h1>你好,很高兴认识你</h1>')
    thr = Thread(target=async_send_mail, args=(msg,))
    thr.start()

    return '发送成功'


if __name__ == '__main__':
    manager.run()
os.environ  的含义:一个字典对象表示是的当前环境,environ是一个字符串所对应环境的映像对象
比如os.environ['HOME'],可以往里面存东西
windows:
    os.environ['HOMEPATH']:当前用户主目录。
    os.environ['TEMP']:临时目录路径。
    os.environ[PATHEXT']:可执行文件。
    os.environ['SYSTEMROOT']:系统主目录。
    os.environ['LOGONSERVER']:机器名。
    os.environ['PROMPT']:设置提示符。
linux:
    os.environ['USER']:当前使用用户。
    os.environ['LC_COLLATE']:路径扩展的结果排序时的字母顺序。
    os.environ['SHELL']:使用shell的类型。
    os.environ['LAN']:使用的语言。
    os.environ['SSH_AUTH_SOCK']:ssh的执行路径。

注意字典的一个用法
dict1.get('a','b')有就获取a的值,没有b就是它的值

6.一个控制图片尺寸的函数

from PIL import Image
import os

def img_zoom(path,width=300,height=200,prefix='s_'):
    #图片缩放处理
    img=Image.open(path)
    print(img.size) #获取图片大小
    #重设图片的大小
    img.thumbnail((width,height))
    #保存图片缩放后的新图片路径(原图和缩放图片都保存)
    newPath=os.path.join(os.path.split(path)[0],prefix+path.split('/')[-1])
    img.save(newPath)
img_zoom('C:/Users/Administrator/Desktop/2.jpg')

7.Flask缓存之falsk_caching模块

1.安装
pip install flask_caching
2.配置
from flask_caching import Cache(注意这个导包千万不要导错)

cache=Cache(config={
  'CACHE_TYPE':'simple'  (也可以是redis的缓存方式)
})

cache.init_app(app)

3.再视图函数当中使用
from App.extensions import cache

@main.route('/')
@cache.cached(timeout=300)
def main_content():
    cache.set('a',10)
    return '存入缓存了一个数'


@main.route('/get/')
def get_cache():
    print(cache.get('a'))
    return 'success'
缓存的作用是提高交互效率同时可以往缓存里面存入数据

清除缓存
cache.delete('get_list')                     # 删除'get_list'缓存项
cache.delete_many('get_list', 'view_hello')  # 同时删除'get_list'和'view_hello'缓存项
cache.delete_memoized('create_list', 5)      # 删除调用'create_list'函数并且参数为5的缓存项
cache.clear()                                # 清理所有缓存
注意缓存模块
@cache.cached(timeout=300,key_prefix='View_%s')
timeout:过期时间
key_prefix:缓存项键值的前缀,默认为view/%s

除了装饰视图函数,cache.cached()装饰器也可以用来装饰普通函数
但是装饰普通函数必须指定明确的key_prefix参数,

@cache.memoize()与@cache.cached()的区别就是它会将函数的参数也放在缓存项的键值中
我们可以在jinjia2模板当中使用缓存
{% cache 50, 'temp' %}
<p>This is under cache</p>
{% endcache %}
这里temp就是键值对的键
在实际使用中我们可以通过这种方式获取到缓存
from flask_cache import make_template_fragment_key
key = make_template_fragment_key('temp')
这样就把缓存获取到了

如果缓存设置的是redis,那么在redis里面是可以获取到其缓存的
flask_cache_缓存的键的名字

7.flask样式之bootstrap模块

其他方面和正常使用基本一样,但是在使用继承样式的时候,一定要把块声明出来,不然样式为空
{% extends 'bootstrap/base.html'  %}

{% block title %}
    主题
{% endblock %}

{% block navbar %}
    这里粘贴bootstrap代码
{% endblock%}


<a href="{{ url_for('main.index') }}">

如果想导入外边带验证器快速生成的表单

{% import'bootstrap/wtf.html' as wtf%}
{% block page_content %}
        <div class="row">
        <div class="col-md-8">.col-md-8</div>
        <div class="col-md-4">{{ wtf.quick_form(form) }}</div>
    </div>
{% endblock %}

8.flask快速生成轮播图

 <div class="carousel-inner" role="listbox">
            {% for i in range(1,3) %}
                <div class="item {% if i==1 %}active{% endif %}" style="height: 400px;">
                <img src="{{ url_for('static',filename='img/'+i|string+'.jpg') }}" alt="...">
                <div class="carousel-caption">
                    ...
                </div>
            </div>
            {% endfor %}
        </div>

        <!-- Controls -->
        <a class="left carousel-control" href="#carousel-example-generic" role="button" data-slide="prev">
            <span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
            <span class="sr-only">Previous</span>
        </a>
        <a class="right carousel-control" href="#carousel-example-generic" role="button" data-slide="next">
            <span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
            <span class="sr-only">Next</span>
        </a>

9.快速生成表单得flask_wtf模块

是一个用于表单处理的扩展库 提供了csrf 和表单验证等功能

字段类型

字段名称 字段说明
StringField 普通文本字段
SubmitField 提交字段
PasswordField 密码字段
HiddenField 隐藏域
TextAreaField 多行文本域字段
DateField 日期字段
DateTimeField 日期时间字段
IntegerField 整形字段
FloatField 浮点形字段
BooleanField bool字段
RadioFIeld 单选
SelectField 下拉字段
FileField 文件上传

验证器

验证器 验证器说明
DataRequired 必填
Length 长度 min max
IPAddress ip地址
URL url地址验证
NumberRange 值的范围
EqualTo 验证俩个字段值的是否相同
Regexp 正则匹配
Email 验证邮箱

实例

models.py

#创建表单类
from flask_wtf import FlaskForm
from wtforms import StringField,PasswordField,SubmitField
from wtforms.validators import DataRequired,Length

class Login(FlaskForm):
    #参数1 为label中的内容显示
    username = StringField('用户名',validators=[DataRequired(message='用户名不能为空'),Length(min=6,max=12,message='用户名在6-12位之间...')])
    userpass = PasswordField('密码',validators=[DataRequired(message='密码不能为空'),Length(min=6,max=10,message='密码长度为6-10位')])
    submit = SubmitField('登录')

manage.py

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/login/',methods=['GET','POST'])
def login():
    form = Login() #实例化登录的表单类
    # if request.method=='POST':
    if form.validate_on_submit(): #当前表单的csrf验证通过 和数据正确 则为真
        # print(request.form) #使用request获取数据
        print(form.username.data) #使用表单对象获取数据
        print(form.userpass.data)
        return '表单提交'
    return render_template('flask-wtf-form/form2.html',form=form)


if __name__ == '__main__':
    manager.run()

使用bootstrap快速渲染表单

{% extends 'common/base.html' %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block page_content %}
    <div class="row">
        <div class="col-md-8"><img src="{{ url_for('static',filename='img/meinv.jpg') }}" alt=""></div>
        <div class="col-md-4">{{ wtf.quick_form(form) }}</div>
    </div>
{% endblock %}

上述封装实际是完成了下面得所有效果

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>wtf-form</title>
</head>
<body>
<form action="" method="post">
    {{ form.csrf_token }}
    {{ form.username.label() }}
    {{ form.username(placeholder='请输入用户名...',style='color:red;') }}
{#    {{ form.username.errors }}#}
    {% if form.username.errors %}
        <span style="color: red;">{{ form.username.errors.0 }}</span>
    {% endif %}
    <br>
    {{ form.userpass.label() }}
    {{ form.userpass() }}
{#    {{ form.userpass.errors }}#}
    {% if form.userpass.errors %}
        <span style="color: red;">{{ form.userpass.errors.0 }}</span>
    {% endif %}
    <br>
    {{ form.submit() }}
</form>
</body>
</html>

10.flask之flash消息闪现得使用

flash存储消息

get_flashed_messages()获取消息

也可以在视图函数中使用得到当前存储的消息列表,get_flashed_messages()得到的是一个消息列表

导入

from flask import flash.get_flashed_message

{%extends 'common/base.html' %}
{% block page_content%}
    <h1> 首页</h1>
{% endblock%}

flash:存消息
get_flashed_message  取消息
    if form.username.data !='lisi':
        flash('当前用户不存在')
    elif form.confirm.data!=1234:
        flash('密码错误')
    else:
        flash('欢迎{}.format(form.username.data)')
        return redirect(url_for('index'))  重定向到首页
    print(get_flashed_messages())   可以查看存到flash里面的内容
        (['当前用户不存在'])得到一个列表,当初flash的消息列表
return render_template('form.html',form=form)
不管成功还是失败只有只会跳到一个模板中
(login表示登陆页面,index表示首页页面)
取出的消息列表放在base里面的原因:因为每一个函数里面都有一个get_flash_message,所以存放在base里面的content block里面
在page_congtent block的上面

{% block content%}
    {% for info in get_flashed_messages()%}
            <p>{{info}} </p>
            {% endfor %}
    {% block page_content%}
    {% endblock%}
{%  endblock %}
flash只是为了在模板中显示出对应的提示消息。

11.flask_sqlalchemy与数据库交互的模块

1.比较表的存储引擎的区别

MyISAM

文件存储为 3个 数据,表结构,索引 MYD MYI

InnoDB

文件存储为 2个 表结构 数据和索引

  1. MyISAM 不支持外键
  2. innodb支持
  3. innodb支持事物 所以安全性高
  4. myisam不支持事物
  5. myisam查询效率高于innodb
  6. innodb用于对数据安全性较高的存储
  7. myisam用于对数据安全性要求不高 但是查询效率高的网站 帖子

2.字段类型

类型名称 python类型 字段说明
Integer int 存储整形
SmallInteger int 小整形
BigInteger int 长整形
Float float 浮点形
String string varchar类型
Text string 长文本
Boolean bool tinyint
Date datetime.date 日期
Time datetime.time 时间
DateTime datetime.datetime 时间和日期
Enum str 枚举

可选条件

选项 说明
primary_key 主键 True
index 常规索引 True
unique 唯一索引 True
nullable 是否为空 False
default 默认值

注意:使用索引会加快查询效率,但是会减缓运行效率

​ 数据库中不允许同名的表

3.连接数据库,创建表,完成迁移

class Config:
    SECRET_KEY='asdnjasd'
    SQLALCHEMY_DATABASE_URI='mysql+pymysql://root:root@localhost:3306/circle'
    DEBUG=True
    SQLALCHEMY_COMMIT_ON_TEARDOWN=True
    SQLALCHEMY_TRACK_MODIFICATIONS=False
from flask_sqlalchemy import SQLALchemy
from flask_migrate import Migrate
db=SQLALchemy()
migrate=Migrate(db=db)

def extension_init(app):
    db.init_app(app)
    migrate.init_app(app)
class User(db.Model,UserMixin):
    __tablename__='user'
    id=db.Column(db.Integer,primary_key=True)
    username=db.Column(db.String(10),unique=True)
    password=db.Column(db.String(128))
    sex=db.Column(db.Boolean,default=1)
    email=db.Column(db.String(100),unique=True)

如果要使用迁移,需要添加迁移命令(manage.py中)

from flask_migrate import MigrateCommand
manage.add_command('db',MigrateCommand)

使用下列指令可完成迁移

python manage.py db init

python manage.py db migrate

python manage.py db upgrade

注:如果完成发现表没有更新,将model导入App的init.py文件当中

4.数据库操作语句

(1)给表中添加行

增加一条
    u=User(name='liu',age=20)
    db.session.add(u)
    db.session.commit()     如果配置里设置了自动提交,则不用使用这个
    db.session.rollback()   用于在事务当中回滚
增加多条
    u1=User(...)
    u2=User(....)
    db.session.add_all([u1,u2])

(2)修改表中某条内容

u= User.query.get(1)    #查询id为1的对象
u.username='新值'        

(3)删除某个对象(注意,删除是建立在查询的基础上的)

u=User.query.get(1)
db.session.delete(u)
db.session.commit

(4)对表中内容的一些操作方法

User.query.all() 获取到所有的数据

User.query.filter()

​ 注意filter得到的是一个查询集

​ User.query.filter(‘1’) 直接写默认是查询id,如果想使用条件查询:

​ User.query.filter(User.name==’liujie’)

User.query.offset(4) 获取偏移4之后的其他所有数据

User.query.limit(3) 只获取3条数据

User.query.first() 只查询第一条

User.query.get(10) 获取id为10的数据

User.query.filter(User.username.contains(‘l’)) 获取名字中包含l的

User.query.filter(Usr.username.like(‘%3%’)) 包含3,3只能在中间

User.query.filter(Usr.username.like(‘3%’)) 以3开头

User.query.filter(Usr.username.like(‘%3’)) 以3结尾

类似startwith和endwith

猜你喜欢

转载自blog.csdn.net/lj1029351265/article/details/82153260