Flask之入门笔记

Flask学习笔记

一、Flask基本使用

1、flask入门

from flask import Flask

# 决定网页寻找静态资源的网址是static_url_path
# app = Flask(__name__,static_folder='static',template_folder='templates',static_url_path='static')
以当前文件所在目录作为项目目录
app = Flask(__name__)  

@app.route('/')  地址:127.0.0.1:5000/
def index():
	return '哈哈'
if __name__ == '__main__':
	app.run()

2、读取配置文件

1. app.run方法里加入配置参数
```python
app.run(debug=True,host='127.0.0.0',post='3333')
```
2. 在当前目录新建myConfig.conf配置文件(**名字可以任意取**)
```text
DEBUG = True  # 参数一定要大写
NAME = 'zhangsan'
```
```python
加载配置文件
app.config.from_pyfile('./myConfig.conf')
```
3. 从类中读取配置文件
```python
class Config:
    DEBUG = True
    NAME = 'config666'
app.config.from_object(Config)
```

3、获取前端传来的信息

  • 从send_post页面传来了表单数据,因此用request.form获取数据
  • methods=[‘GET’,‘POST’]指的是能够接受get和post请求,默认是只能接受get请求
"""
request.form 可以获取表单post提交的数据
request.data 可以获取表单以外的数据
request.args 可以获取get请求的查询字符串 即地址栏中问号后面的数据
request.values 可以获取所有数据,包括表单提交的数据
request.headers 获取请求头部信息
"""
from flask import Flask,request
@app.route('/send_post/',methods=['GET','POST'])
def send_post():
    name = request.form.getlist('name')
    age = request.form.getlist('age')
    data = request.data
    args = request.args
    headers = request.headers
    print(headers)
    return f'姓名是{name},年龄是{age},data是{data},args是{args}\n'

4、route中获取参数传入视图函数

与django不一样的是获取路由中的参数

django: url(r'/page_(id)/',views.index) 

def index(id):
	pass

Flask从路由中获取参数的方式是:

@app.route('/blog_<int:id>/')
def get_id(id):
    return f'第{id}个小果'
转换器  默认是字符串
       <int:xxx>  整数
       <float:xxx>  浮点数
       <path:xxxx/xxx/xxx/xxx>  任意字符包括路径/
       
django 1.xx      url(r'',func)
django 2.xx以上   path('/blog_<int:xxx>',func)  路径与flask一致

自定义转换器类
from werkzeug.routing import BaseConverter
class PhoneConverter(BaseConverter):
    regex = r'1[0123456789]{10}'
app.url_map.converters['phone'] = PhoneConverter  # 注册在routing里
@app.route('/send/<phone:number>')
def send_num(number):
    return f'电话是{number}'

第二种定义的方式:

class PhoneConverter(BaseConverter):
    def __init__(self,map,regex):
        super(PhoneConverter, self).__init__(map)
        self.regex = regex
app.url_map.converters['phone'] = PhoneConverter  # 注册在routing里
#  '<phone(r"匹配规则"):变量>'
@app.route('/send/<phone(r"1[0123456789]{10}"):number>')
def send_num(number):
    return f'电话是{number}'

5、反向解析

from flask import Flask,redirect,url_for
@app.route('/')
def index():
    # 读取config里的内容
    # app.config是一个类字典对象,包含了所有当前项目的所有参数(键值对存在)
    # print(app.config.get('NAME'))
    return render_template('index.html')
@app.route('/index/',endpoint='haha')
def index1():
    print(app.url_map)  # 打印项目所有的路由
    return '你已经来到主页'
"""
url_for 反向解析视图函数名字,
如果route参数里有endpoint,则反向解析endpoint值
"""
@app.route('/login/',methods=['GET',"POST"])
def login():
    #return redirect(url_for('haha'))
    return redirect(url_for('index'))

6、返回json响应

django返回json响应的是 Jsonresponse函数
Flask返回json响应的是 jsonify函数

7、试图函数传参

Django视图函数传参

def func():
	id1 = 1
	name = 'zhangsan'
	return render(request,'index.html',{'id1':id1,'name':name})
from flask import Flask,render_template
@app.route('/')
def index():
    # 两种传参数方式
    data = {
        'name':'张三',
        'age':18,
        'dict':{'lua':'python','lut':'666'},
        'list':[2,3,4,5,6]
    }
    return render_template('index.html',**data)
    # return render_template('index.html',name='张三',age=18)

8、abort函数

abort函数:立即结束视图函数,并返回给前端特定信息

from flask import Flask,abort,Response
# todo:abort函数:立即结束视图函数,并返回给前端特定信息
@app.route('/send_error')
def send_error():
    detail = '给爷爬'
    if detail in ['色情','暴力','给爷爬']:
        # 1、接收Http状态码,并返回响应状态码的页面
        abort(404)
        # 2、可以接受Response响应
        # abort(Response('你已经触犯了法律法规,请重新打开'))

    # 响应具体信息,状态码,字典  元祖类型
    return 'OK',200,{'home':'guangzhou'}  返回到request请求头中

9、上传照片

上传照片只能用post提交

一定要加enctype="multipart/form-data"
<form action="/img_load/" method="post" enctype="multipart/form-data">
    <input type="file" name="pic">
    <input type="submit" value="提交">
</form>
from werkzeug.utils import secure_filename  # 将不合法的路径改为合法路径
@app.route('/img_load/',methods=['GET','POST'])
def img_upload():
    file_img = request.files.get('pic')
    if not file_img:
        return '你还没有上传照片'
    else:
        # 保存方法一:
        # with open(f'./static/{file_img.filename}','wb') as f:
        #     f.write(file_img.read())
        # 保存方法二:
        # 不合法名称有 'my word day.png' '../../xx.png'
        filename = secure_filename(file_img.filename)  # todo:将不合法的图片名称改为合法名称
        file_img.save('./static/'+filename)
        return '你已经上传了照片'

10、cookie和session

与django差别不大

  • 设置status登录状态
  • 设置请求头信息
from flask import Flask,make_response,request,session
@app.route('/')
def index():
    res = make_response('首页')
    res.status = '200'
    res.headers['name'] = 'zhangsan'
    return res
①cookie
  1. 设置cookie
@app.route('/set_cookie/')
def set_cookie():
    res = make_response('登录成功')
    res.set_cookie('islogin','ok')
    return res
  1. 删除cookie
@app.route('/del_cookie/')
def del_cookie():
    res = make_response('退出登录')
    res.delete_cookie('islogin')
    return res
  1. 读取cookie
@app.route('/check_cookie/')
def check_cookie():
    islogin = request.cookies.get('islogin')
    if islogin:
        return '已经登录成功'
    else:
        return '没有登录'
②session

设置session前需要添加密钥,内容自定

app.config['SECRET_KEY'] = 'm1m9w1e1126512;32[;3]12/>P{1|}#&*#;2<>1'

  • 设置session
from flask import Flask,make_response,request,session
@app.route('/set_session/')
def set_session():
    session['username'] = 'zhangsan'
    session['pwd'] = '123456'
    return '设置session'
  • 获取session
@app.route('/get_session/')
def get_session():
    username = session.get('username')
    pwd = session.get('pwd')
    return f'用户名是{username},密码是{pwd}'
  • 删除session
@app.route('/del_session/')
def del_session():
    session.clear()
    return '删除session'

二、Flask进阶学习

1、请求上下文和应用上下文

①请求上下文

request
session

②应用上下文

current_app对象
g对象

1)current_app对象

在创建app应用的时候,每个创建的对象名可能都不一样。
使用current_app 应用上下文,我们可以不用关心应用怎么创建的。

from flask import Flask,current_app,g
@app.route('/')
def index():
    # 获得当前应用对象
    print(app.config.get('NAME'))
    print(current_app.config.get('NAME'))
    return '首页'
2) g 对象

有时候应用上下文会在必要时被创建和销毁。它不会在线程间移动,并且也不会在不同的请求之间共享。

处理请求时,临时存储的对象,每次请求都会重设这个变量。

比如 数据库连接,请求进来的时候创建连接,在处理完成之后,释放连接。

g对象是应用上下文的一种,每一个请求过来都会创建一个g对象。g对象就是一个作用于app应用的全局变量。每个请求进来g对象都先置为空。

from flask import Flask,current_app,g
@app.route('/detail')
def detail():
    g.name = 'lisi'
    print(set_g())

    return '666'
def set_g():
    name = g.name
    return f'欢迎来到{name}'

2、请求钩子

相当于django的中间件

  • before_first_request:注册一个在处理第一个请求之前运行的函数。
  • before_request:注册一个在处理请求之前运行的函数。
  • after_request:注册一个函数,如果没有未处理的异常抛出,在每次请求之后运行,接收一个响应对象为参数,需要返回一个响应对象
  • teardown_request:注册一个函数,即使有未处理的异常抛出,也在每次请求之后运行,接收一个响应对象为参数,需要返回一个响应对象。
from flask import Flask, abort
import datetime
# Flask 接收一个参数__name__,
# 导入模块的目录, flask以这个目录为基础,寻找静态文件目录static和模板目录templates
app = Flask(__name__)


# 只有在第一次请求的时候执行
@app.before_first_request
def first_request():
    print("before_first_request 执行")


# 每次请求之前执行
@app.before_request
def before_request_():
    print('before_request执行')


# 每次执行完成后没有未处理的异常抛出才会执行
@app.after_request
def after_request(response):
    print('after_request 执行')
    return response


# 即使视图函数有未处理的异常抛出都执行
@app.teardown_request
def teardown_request_(response):
    print('teardown_request 执行')
    return response


@app.route('/')
def index():
    print('index 执行')
    return 'ok'


if __name__ == '__main__':
    # Flask 应用程序实例的方法run启动web服务器
    app.run(debug=True)

3、templates模板

①自定义过滤器
# todo:自定义一个过滤器
@app.template_filter('nums')
def nums(num,i=2):
    return num % i
②使用过滤器
  • 参数|过滤器名
  • 参数|过滤器名(参数)
{% for li in list %}
{% if li|nums(4) %}
    {{ li }}
    {% endif %}

{% endfor %}
③参数

视图函数传入参数

@app.route('/')
def index():
    # 两种传参数方式
    data = {
        'name':'张三',
        'age':18,
        'dict':{'lua':'python','lut':'666'},
        'list':[2,3,4,5,6]
    }
    return render_template('index.html',**data)
    # return render_template('index.html',name='张三',age=18)

Flask模板参数向python语法靠近,上下兼容
可以参数之间的运算等

<h>name = {{ name }}</h>
<h>name = {{ age }}</h>
<p>dict['lua'] = {{ dict.lua }}</p>
<p>dict['lua'] = {{ dict['lua'] }}</p>
<p>list[2] = {{ list[2] }}</p>
<p>list[1] + list[2] = {{ list[1]+list[2] }}</p>

设置参数

  • set 全局变量
  • with 局部变量
{% set hh = '哈哈哈' %}  {# set设置全局变量,with设置局部变量 #}
<p>hh = {{ hh }}</p>
{% with xixi = 'xixi'  %}
<p>{{ xixi }}</p>
{% endwith %}

查看循环次数

  • loop.index
遍历字典的键值对
{% for di in dict.items() %}
{{ loop.index }}{# 循环第几次 #}
    <p>{{ di }}</p>
{% endfor %}
④模板宏

简单的说,类似于python的自定义函数

{% macro index() %}
    {# 模板宏,类似python的def #}
    <input type="text" name="user" size="50">哈哈哈
{% endmacro %}
{{ index() }}  # 调用函数

导入其他模板的模板宏
比如:

{# 导入其他文件的模板宏 #}
{% import '11.html' as t %}  导入11.html的文件,并命名为t
{{ t.find() }}  调用11.html文件的find()函数
⑤特殊变量

特殊变量 说明
config 对象 config 对象就是Flask的config对象,也就是 app.config 对象。
request 对象 表示当前请求的 request 对象。
session 对象 表示当前请求的 session 对象。
url_for 方法 反解析 直接通过视图函数名称,逆向生成url
get_flashed_messages 方法 在视图中使用flash()函数传入的消息队列,在模板中使用get_flashed_messages 取出

特殊变量说明
config 对象config 对象就是Flask的config对象,也就是 app.config 对象
request 对象表示当前请求的 request 对象。
session 对象表示当前请求的 session 对象。
url_for 方法反解析 直接通过视图函数名称,逆向生成url
get_flashed_messages 方法在视图中使用flash()函数传入的消息队列,在模板中使用get_flashed_messages 取出
⑥flash()方法

flash 闪现方法
基于session实现一般用于给一些提示信息
get_flashed_messages 方法使用:

get_flashed_messages 必须配合 flash()函数使用,相当于 flash函数是生产者生产数据,get_flashed_messages是消费者将数据取出消费。

from flask import Flask, render_template,flash
app=Flask(__name__)
@app.route('/')
def hello_world():
    flash('python')
    flash('django')
    flash('flask')
    flash('scrapy')
    return render_template('index.html')

一定要加括号,否则报错

{% for msg in get_flashed_messages() %}  
{{ msg }}
{% endfor %}

4、表单

①表单模型制作

pip install flask-wtf
pip uninstall WTForms 最新版的不支持邮箱字段
pip install WTForms==2.1 下载2.1版本的WTForms

  • 新建forms.py文件
from flask_wtf import FlaskForm
from wtforms import StringField,PasswordField,SubmitField
from wtforms.validators import DataRequired,Length,Email,EqualTo
class UserInfoForm(FlaskForm):
    # todo:字段名是id和name的属性值
    username = StringField(label='用户名',validators=[DataRequired('用户名不能为空')])
    pwd = PasswordField(label='密码',validators=[DataRequired(u'密码不能为空'),Length(8,16,u'密码没有超过8位或者超过了16位')])
    pwd1 = PasswordField(label='重新输入密码',validators=[
        DataRequired(u'密码不能为空'),
        EqualTo('pwd')
    ])
    email = StringField(label='邮箱',validators=[
        DataRequired(u'邮箱不能为空'),
        Email(u'邮箱格式不正确')
    ])  # todo:需要使用WTForms==2.1
    submit = SubmitField(label='提交')
 """
WTForms 支持表单类型:
from wtforms import ...
字段对象	说明
StringField	文本字段
TextAreaField	多行文本字段
PasswordField	密码文本字段
HiddenField	隐藏文本字段
DateField	文本字段,值为datetime.date格式
DateTimeField	文本字段,值为datetime.datetime格式
IntegerField	文本字段,值为整数
DecimalField	文本字段,值为decimal.Decimal
FloatField	文本字段,值为浮点数
BooleanField	复选框,值为True和False
RadioField	一组单选框
SelectField	下拉列表
SelectMultipleField	下拉列表,可选择多个值
FileField	文本上传字段
SubmitField	表单提交按钮
FormField	把表单作为字段嵌入另一个表单
FieldList	一组指定类型的字段


WTForms常用验证函数
from wtforms.validators import ....
验证函数	说明
URL	验证 URL
Email	验证电子邮件地址
Length	验证输入字符串的长度  ## 参数:min,max,error_msg
DataRequired	确保字段中有数据  ## 参数:错误提示字符串
EqualTo	比较两个字段的值;常用于要求输入两次密码进行确认的情况
IPAddress	验证 IPv4 网络地址
NumberRange	验证输入的值在数字范围内
Optional	无输入值时跳过其他验证函数
Regexp	使用正则表达式验证输入值
AnyOf	确保输入值在可选值列表中
NoneOf	确保输入值不在可选值列表中
"""

②使用表单
  • 将表单模型加载并传参
@app.route('/register/',methods=['GET','POST'])
def register1():
    form = UserInfoForm()
    return render_template('register.html',form=form)
<form action="" method="post">
    {{ form.csrf_token }}  csrf验证
    {{ form.username.label }}
    {{ form.username }}
    {% for error in form.username.errors %}  # 错误信息打印
        {{ error }}
    {% endfor %}
    {{ form.pwd.label }}
    {{ form.pwd }}
    {% for error in form.pwd.errors %}
        {{ error }}
    {% endfor %}
    {{ form.pwd1.label }}
    {{ form.pwd1 }}
    {% for error in form.pwd1.errors %}
        {{ error }}
    {% endfor %}
    {{ form.email.label }}
    {{ form.email }}
    {% for error in form.email.errors %}
        {{ error }}
    {% endfor %}
    {{ form.submit }}
</form>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值