博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Flask(二)
阅读量:5085 次
发布时间:2019-06-13

本文共 8491 字,大约阅读时间需要 28 分钟。

 

钩子函数

from flask  import Flask

app = Flask(__name__)

# 第一次请求之前会来调用

# 初始化操作

@app.before_first_request

def demo1():

      print("第一次请求会调用"")

# 每次请求之前都会调用,应用场景:封装ip处理

@app.before_request

def demo2():

  print("每次请求之前会被调用")

#每次请求之后都会调用这个钩子函数,应用场景:对response进行统一处理

@app.after_request

def demo3(response):

  # response.headers["Content-Type"] = "application/json"

  print("每次请求之后才会调用")

  return response

 

# 每次都会执行,都会带入一个服务器的错误过来

@app.teardown_request

def demo4(err):

  print(err)

  print("每次请求之后都会调用一个服务器错误过来)

 

if  __name__ == "_main__":

  app.run(debug=True)

 

 

对cookie进行操作:

from flask import Flask, make_response, request

app = Flask(__name__)

@app.route("/login")

def login():

  """登录成功之后借助cookie保存用户登录信息"""

  # 创建响应对象

  response = make_response("login_success")

  # 借助响应对象的set_cookie方法设置键值对

  # 参数1:ke, 参数2:value, 参数3:max_age表示过期时长(以秒为单位)

  # set_cookie("key",值) Cookie是存储在浏览器中的一段纯文本

  response.set_cookie("user_name", "kangkang", max_age=3600)

  response.set_cookie("age", "18", max_age= 3600)

  return response

# 获取cookie

@app.route("/index")

def index():

"""再次请求首页的时候,提起cookie中的用户信息"""

  user_name = request.cookies.get("user_name", "")

  age = request.cookies.get("age", "")

  return "index %s --- %s" %(user_name, age)

 

# 删除cookie

@app.route("/login_out")

def login_out():

  response = make_response("login_out success")

  response.delete_cookie("user_name")

  response.delete_cookie("age")

  #将响应对象返回

  return response

 

if __name__== "__main__":

  app.run(debug=True)

 

对session进行操作,session依赖于cookie,服务器会返回一个session_id即为cookie,session里面包含用户信息

from flask import Flask, session

app = Flask(__name__)

# session需要设置秘钥,可以写一个任意的字符串,两种写法,app.config是个字典

app.config="2323242423"

app.config["SECREY_KEY"] = "3213232"

 

@app.route("/login")

def login():

  # session将用户数据存储在服务器的内存中--redis数据库

  session["user_name"]= "kangkang"

  session["user_id"] = "12"

  return "login success"

 

@app.route("/index")

def index():

  user_name = session.get("user_name", "")

  user_id = session.get("user_id", "")

  return "index:%s ---%s" %(user_name, user_id)

 

@app.route("/login_out")

def login_out():

  session.pop("user_name", "")

  session.pop("age", "")

  return "login_out success"

 

if __name__ == "__main__":

  app.run(debug=True)

 

 

捕获异常:

from flask import Flask, redirect, abort

 

app = Flask(__name__)

 

@app.route("/")

def hello():

  a = 1/0

  abort(404)  # 主动产生一个404异常,abort需要先导入该库,abort传入的必须是http存在的错误状态码

  return "hello world"

 

# 通过errorhandler捕获错误状态码

@app.errorhandler(404)

def handler(e):

  print(e)

  # 重定向到百度的错误页面链接

  return redirect("https://www.baidu.com/search/error.html")

# 通过errorhandler捕获异常

@app.errorhandler(ZeroDivisionError)

def err(err):

  return "不能除以0"

 

if __name__ == "__main__":

  app.run(debug=True)

 

 

上下文:

请求上下文: request和session

应用上下文:current_app, g变量(flask程序全局的一个临时变量)

from flask import Flask, request, session, current_app, g

 

app =Flask(__name__)

app.config["SECRECT_KEY"] = "avdvdvd"

# print(request.method)  Working outside of request context.请求上下文超出范围

# print(g.user) Working outside of request context.应用上下文超出范围

# 只能在视图函数里面进行操作,在外部进行操作就会超出范围

@app.route("/")

def hello():

# 请求上下文

  print(request.method)

  print(request.url)

  session["user_name"] = "curry"

  print(session.get("user_name", ""))

  # 应用上下文(current_app, g)

  print(current_app.config.get("DEBUG"))

  g.user = "james"

  print(g.user)

  return "hello world"

 

if __name__ == "__main__":

  app.run(debug=True)

 

  • 请求上下文:保存了客户端和服务器交互的数据
  • 应用上下文:flask 应用程序运行过程中,保存的一些配置信息,比如程序名、数据库连接、应用信息等

 

Flask-Script拓展

需要安装Flask-Script拓展

pip install flask-script

from flask import Flask

from flask_script import Manager

app = Flask(__name__)

manager= Manager(app)

@app.route("/")

def hello():

  return "hello world"

 

if __name__ == "__main__":

  manager.run()

通过终端命令: python XX.py runserver  -h ip地址 -p 端口号  -d

同样也可以配置该文件的环境变量进行右键运行.

 

 

Jinja2模板引擎简介

视图函数的主要作用是生成请求的响应,这是最简单的请求。实际上,视图函数有两个作用:处理业务逻辑和返回响应内容。在大型应用中,把业务逻辑和表现内容放在一起,会增加代码的复杂度和维护成本。本节学到的模板,它的作用即是承担视图函数的另一个作用,即返回响应内容。

  • 模板其实是一个包含响应文本的文件,其中用占位符(变量)表示动态部分,告诉模板引擎其具体的值需要从使用的数据中获取
  • 使用真实值替换变量,再返回最终得到的字符串,这个过程称为“渲染”
  • Flask是使用 Jinja2 这个模板引擎来渲染模板

使用模板的好处:

视图函数只负责业务逻辑和数据处理(业务逻辑方面)

而模板则取到视图函数的数据结果进行展示(视图展示方面)

代码结构清晰,耦合度低

Jinja2:是 Python 下一个被广泛应用的模板引擎,是由Python实现的模板语言,他的设计思想来源于 Django 的模板引擎,并扩展了其语法和一系列强大的功能,其是Flask内置的模板语言。

模板语言:是一种被设计来自动生成文档的简单文本格式,在模板语言中,一般都会把一些变量传给模板,替换模板的特定位置上预先定义好的占位变量名

Flask提供的 render_template 函数封装了该模板引擎

render_template 函数的第一个参数是模板的文件名,后面的参数都是键值对,表示模板中变量对应的真实值

{

{}}来表示变量名,这种{
{}}语法叫做代码块变量, {
{
{position.title}}

Jinja2模板中的变量代码块可以是任意Python类型或者对象,只要它能够Python的Str()方法转换为一个字符串就可以,

{

{your_dict['key']}}

{

{your_list[0]}}

用{% %}定义的控制代码块,可以实现一些语言层次的功能,比如循环或if语句

{% if user %}

  {

{user}}

{% else %}

  hello!

<ul>

  {% for index in indexs %}

    <li>{

{index}}</li>

    {% endfor %}

</ul>

使用{# #}进行注释,注释的内容不会再html中被渲染出来

 

 

模板的基本使用:

在项目下创建templates文件夹,用于存放所有的模板文件,并在目录下创建一个模板html文件

 

from flask import Flask, render_template

app = Flask(__name__)

 

@app.route("/")

def index():

  myint = 18

  mystr = "curry"

  my_list =[1, 23,4,6,5]

  my_dict = {

  "name":"duan",

  "age":28

  }

  return render_template("dem01.html",

             myint = myint, mystr = mystr, my_dict=my_dict, my_list = my_liust)

 

if __name == "__main__":

  app.run()

 

对应的demo01.html:

<!DOCTYPE html>

<html lang="en">

<head>

Title 我的模板html内容
{ { my_str }}
{ { my_int }}
{ { my_array }}
{ { my_dict }}

 

链式调用: {

{"hello world" | reverse | upper}}

常见内建过滤器:

字符串操作

safe:禁止转义 {

{"<em>hello</em>"| safe}}

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

{'hello" | capitalize}}

lower:把值转成小写, {

{"HELLO" | lower}}

upper:把值转成大写,{

{"hello" | upper}}

title:把每个单词的首字母都转成大写, {

{'he is girl" | title}}

reverse:字符串反转,

format:格式化输出 {

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

striptags:把html中的tag去掉, {

{'<h1>hello</h1>" | striptags}}

truncate:字符串截断 {

{'hello every one" | truncate(9) }}

列表操作

list=[1,2,3,1,2,3,6,8,4]

first :取第一个元素 {

{list | first}}

last:取最后一个元素{

{list | last}}

length:获取列表长度{

{list | length}}

sum:求列表的和{

{list | sum}}

sort:列表排序 {

{list | sort}}

语句块过滤:

{% filter upper %}

 # 一大堆文字#

{% endfilter %}

 

 

自定义过滤函器

from flask import render_template, Flask

app = Flask(__name__)

# 方法一:自定义列表反函数

@app.template_filter("list_reverse")

def list_rever(list):

  list.reverse()

  return list

# 方式二:将自定义的函数添加到flask过滤器中,add_template_filter(函数名, "创建过滤器名称") 函数名不需要打引号

app.add_template_filter(list_rever, "list_reverse")

@app.route("/")

def index():

  list = [1,2,3,4,6,5]

  return render_template("demo02.html", list = list)

 

if __name__ == "__main__":

   app.run(debug=True)

 

 

demo02.html内容:

   
Title 自定义过滤器

{ { list }}
{ { list | list_reverse }}

 

 控制代码:

from flask import Flask, render_template

app = Flask(__name__)

 

@app.route("/")

def index():

  # 只显示四行数据, 并设置颜色

  my_list = [

    

{
"id":1, "value":"我爱代码" }, { "id": 2, "value": "代码使人快乐" }, { "id": 3, "value": "沉迷于代码无法自拔" }, { "id": 4, "value": "日渐消瘦" }, { "id": 5, "value": "以梦为马,越骑越傻" }

]

return render_template("demo03.html", my_list = my_list)

 

if __name__ == "__main__":

  app.run(debug=True)

 

demo03.html:

   
Title 控制代码块

{% for item in my_list%} {# {% if item.id != 5 %}#} {% if loop.index == 1 %}
  • { { item.value }}
  • {% elif loop.index == 2%}
  • { { item.value }}
  • {% elif loop.index == 3 %}
  • { { item.value }}
  • {% elif loop.index == 4 %}
  • { { item.value }}
  • {% elif loop.index == 5 %}
  • { { item.value }}
  • {% endif %} {# {% endif %}#} {% endfor %}

    loop.index: 当前循环迭次的次数(从1开始)

    loop.index0:当前循环迭代的次数(从0开始)

    loop.revindex: 到循环结束需要迭的次数(从1开始)

    loop.revindex0:到循环结束需要迭代的次数(从0开始)

    loop.first 第一迭代,为True

    loop.last 最后一次迭代,为True

    loop.length  序列中的项目数

    loop.cycle:在一串序列期间取值的辅助函数.

    模板继承:

    在模板中,可能会遇到以下情况:

    • 多个模板具有完全相同的顶部和底部内容
    • 多个模板中具有相同的模板代码内容,但是内容中部分值不一样
    • 多个模板中具有完全相同的 html 代码块内容

    像遇到这种情况,可以使用 JinJa2 模板中的 继承 来进行实现

    from flask import Flask, render_template

    app = Flask(__name__)

     

    @app.route("/parent")

    def parent():

      return render_template("base.html")

     

    @app.route("/child")

    def child():

      return render_template("child.html")

     

    if __name__ == "__main__":

      app.run(debug=True)

     

    base.html:

       
    Title {# 把要重写的父类的内容用{% block 名称x %} XXX {% endblock %}#} {% block testA %}

    父类模板

    {% endblock %}

    父类内容

    父类底部

    child.html内容:

    {# 子类继承父类使用extends关键字 {% extends  '父类.html'  %}#}

    {% extends "base.html'' %}

    {# 重写父类中的部分内容#}

    {# 不丢失父类原有的内容使用super()#}

    {% block testA % }

    {

    {super()}}

    <h2>我是子类模板</h2>

    {% endblock %}

     

     

    怎样设置templates的html文件在使用render_template方法时自动弹出里面的html文件进行选择

    选择Jinja2,apply之后点击ok即可

     

    可以设置自己设置状态码及状态码解释

    from flask import Flask

    app = Flask(__name__)

    @app.route("/")

    def index():

      # 666代表状态码, 解释为状态码的解释信息

      return "hello world", "666 解释"

    if __name__ == "__main__":

      app.run(debug=True)

     

    转载于:https://www.cnblogs.com/zhouzetian/p/9683550.html

    你可能感兴趣的文章
    list 容器 排序函数.xml
    查看>>
    《Genesis-3D开源游戏引擎完整实例教程-跑酷游戏篇03:暂停游戏》
    查看>>
    CPU,寄存器,一缓二缓.... RAM ROM 外部存储器等简介
    查看>>
    git .gitignore 文件不起作用
    查看>>
    Alan Turing的纪录片观后感
    查看>>
    c#自定义控件中的事件处理
    查看>>
    IOS--沙盒机制
    查看>>
    使用 JointCode.Shuttle 访问任意 AppDomain 的服务
    查看>>
    sqlite的坑
    查看>>
    digitalocean --- How To Install Apache Tomcat 8 on Ubuntu 16.04
    查看>>
    【题解】[P4178 Tree]
    查看>>
    Mongo自动备份
    查看>>
    cer证书签名验证
    查看>>
    synchronized
    查看>>
    【深度学习】caffe 中的一些参数介绍
    查看>>
    Python-Web框架的本质
    查看>>
    QML学习笔记之一
    查看>>
    Window 的引导过程
    查看>>
    App右上角数字
    查看>>
    从.NET中委托写法的演变谈开去(上):委托与匿名方法
    查看>>