flask框架

flask框架,第1张

flask框架
  • 一、flask简介
  • 二、初体验
  • 三、flask配置
    • 1、开启debug模式
    • 2、如何正确显示中文
      • 2.1、 配置文件的优化
  • 四、URL与视图
    • 1、构造URL(url-for)
  • 五、指定HTTP方法
  • 六、页面跳转和重定向
  • 七、模板
    • 1、Falsk渲染Jinja模板
    • 2、如何将python的变量传入到前端模板中
    • 3、Jinja2模板过滤器
    • 4、Jinja2中的控制语句
    • 5、模板继承
  • 八、蓝图和子域名

一、flask简介

flask是一款非常流行的python web框架,它能流行的原因有以下几点:

1、微框架,简洁
2、flask和相应的插件写的很好
3、开发效率非常高,比如使用sqlalchemy *** 作的数据库可以节省开发者大量书写sql语句的时间

相较于django的优点:

django内置了非常完善和丰富的功能,如果想替换成自己想要的,要么不支持,要么非常麻烦。而flask的灵活度非常高,可以按照自己的意愿进行修改。

二、初体验
#从flask包中导入Flask对象
from flask import Flask
#使用Flask创建一个app对象,并且传递__name__参数
app = Flask(__name__)
#@app.route:设置访问的url,这里设置成一个根路径,用户访问了url的根路径就会执行hello_world函数,hello_world函数会执行hello world代码
@app.route('/')
def hello_world():
     return 'hello world'

if __name__ == "__main__":
    app.run()
三、flask配置 1、开启debug模式

场景:

如果我们对代码进行了修改,就得重新启动程序,重新加载url,比较麻烦,如果启用了debug模式,直接做代码的修改,不用在pycharm再重启代码,只需重新加载url即可

打开debug的方法:
在专业版只需要edit,勾选flask-debug按钮即可,社区版没有按钮,可以通过代码解决此问题,在调用时加上debug=True即可

......
if __name__ == "__main__":
    app.run(debug=True)
2、如何正确显示中文

以下代码为显示乱码的情况

from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
    return {"username":"李煜"}
if __name__ == "__main__":
    app.run(debug=True)


如何让其显示为正确的中文呢?需要修改配置文件,flask项目的配置都是通过app.config对象来进行配置的,显示中文乱码与JSON_AS_ASCII有关,默认为True,这里我们修改为False即可。

from flask import Flask
app = Flask(__name__)
app.config['JSON_AS_ASCII']=False
@app.route('/')
def index():
    return {"username":"李煜"}
if __name__ == "__main__":
    app.run(debug=True)

访问效果如下,在flask中,如果返回的数据是一个字典,则会自动变为json格式进行返回

2.1、 配置文件的优化

如果我们需要写的app.config配置过多,可以将所有的配置项都放在一个模块里,然后通过加载模块的方法进行配置。
我们将配置全部写在config文件里,config.py文件内容如下:

JSON_AS_ASCII=False

在程序文件里,我们进行加载模块

from flask import Flask
import config
app = Flask(__name__)
#以后所有的配置项,全部放在config.py中
app.config.from_object(config) #表示从哪个对象中加载配置,我们把配置写到了config文件里,这里写config即可
@app.route('/')
def index():
    return {"username":"李煜"}
if __name__ == "__main__":
    app.run(debug=True)
四、URL与视图

我们已经学到,一个url要与执行函数进行映射,使用的是@app.route装饰器。@app.route装饰器中,可以指定url的规则来进行更加详细的映射,比如现在要映射一个文章详情的url,文章详情的url是/book/id,id有可能为1,2,3

from flask import Flask
app = Flask(__name__)
import config
app.config.from_object(config)
books=[
    {"id":1,"name":"三国演义"},
    {"id":2,"name":"水浒传"},
    {"id":3,"name":"红楼梦"},
    {"id":4,"name":"西游记"},
]
@app.route("/book/")
def book_list(book_id):
    for book in books:
        if book_id==book["id"]:
            return book
    return "id为{}的图书没有找到".format(book_id)

if __name__ == '__main__':
    app.run(debug=True)

效果图如下:

1、构造URL(url-for)

一般我们通过一个URL可以执行到某一个函数,如果反过来,我们知道一个函数,怎么去获得这个url呢?url_for函数就可以帮助我们实现这个功能。
url_for函数的用法

url_for()函数接收两个及以上参数,接收函数名作为第一个参数,接收对应URL规则的命名参数,如果还出现其他的参数,则会添加到url的后面作为查询参数。

学习这个的目的是什么?

1、如果代码中涉及到了访问的url,但是url会根据需求经常变化,当代码中出现的Url过多,那我们去修改url是很麻烦的。
所以我们直接通过函数去反转得到url,这样不管url怎样变化,都会找到它
2、 url_for()函数会转义一些特殊字符和unicode字符串,这些事情url_for会自动的帮助我们搞定

from flask import Flask,url_for,jsonify
app = Flask(__name__)
import config
app.config.from_object(config)
books=[
    {"id":1,"name":"三国演义"},
    {"id":2,"name":"水浒传"},
    {"id":3,"name":"红楼梦"},
    {"id":4,"name":"西游记"},
]
@app.route("/book/")
def book_detail(book_id):
    for book in books:
        if book_id==book["id"]:
            return book
    return "id为{}的图书没有找到".format(book_id)
@app.route("/book/list")
def book_list():
    for book in books:
        book["url"]=url_for("book_detail",book_id=book["id"])
    return jsonify(books)
if __name__ == '__main__':
    app.run(debug=True)

效果图如下:

五、指定HTTP方法

在@app.route()中可以传入一个关键字参数methods来指定本方法支持的HTTP方法。默认情况下,只能使用GET请求。

@app.route("/book/",methods=["GET"])

GET请求和POST请求的区别:

如果只是从服务器上获取数据,一般都是GET请求
如果前端需要把数据发送给服务器,一般用POST请求

六、页面跳转和重定向

之前京东的网站为www.360buy.com这个网站,后面又新买了www.jd.com这个域名,如果老域名上还有客户访问,则需将老域名重定向在新域名上,访问的内容都是一样的。
重定向的分类:

永久性重定向的状态码是301,应用场景就是上述的京东实例;
临时性重定向的状态码是302,如果访问一个需要权限的网址,当前用户没有登录,应该重定向到登录页面。这种情况下,使用的是暂时性重定向。

from flask import Flask,redirect,url_for,request
app=Flask(__name__)
import config  #解决中文乱码问题
app.config.from_object(config)
@app.route("/profile")
def profile():
    user_id=request.args.get("id")
    if user_id:
        return "用户个人中心"
    else:
        return redirect(url_for("index"))
@app.route("/")
def index():
    return {"username":"李煜"}
if __name__ == '__main__':
    app.run(debug=True)

效果如下:

七、模板

模板是一个web开发必备的模块,因为在渲染一个网页的时候,并不是只渲染一个纯文本字符串,而是渲染一个富有文本标签的页面,这时候就需要使用模板了。
在Falsk中,配套的模板是Jinja2。

1、Falsk渲染Jinja模板

要渲染一个模板,通过render_template方法即可。

from flask import Flask,render_template
import config
app=Flask(__name__)
app.config.from_object(config)  #此为配置防止中文乱码的代码
@app.route('/about')
def about():
    return render_template("about.html")

if __name__ == '__main__':
    app.run(debug=True)

about.html的内容如下:

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>关于我们title>
head>
<body>
    <h1>我们是最棒的h1>
body>
html>

访问效果图为:

访问流程:当访问/about的时候,about函数会在当前目录下的template文件夹下查找about.html模板文件

2、如何将python的变量传入到前端模板中

如果想要传递变量到模板中,可以把变量定义成字典,然后在render_template中,通过关键字参数的方式传递过去,render_template(“模板名称”,**context)

from flask import Flask,render_template
import config
app=Flask(__name__)
app.config.from_object(config)
@app.route('/about')
def about():
    context={
        "username":"李四"
    }
    return render_template("about.html",**context)

if __name__ == '__main__':
    app.run(debug=True)

我们可以查看render_template的代码,我们看到图片这一块传入的参数为关键字参数,所以我们也应该写为关键字参数

在html页面中,我们应该如何修改呢?给要传的参数加上两个花括号即可,要传入的参数名就是python代码里的变量名

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>关于我们title>
head>
<body>
    <h1>我们是最棒的。{{username}}h1>
body>
html>

效果图如下:

3、Jinja2模板过滤器

过滤器就是通过管道符( | )进行使用的,例如{{name|length}}就会返回name的长度,过滤器相当于是一个函数,把当前的变量传入到过滤器中,然后过滤器根据自己的功能,再返回相应的值,之后再将结果渲染到页面中。
例子:
不想让books以列表的形式展现,想要books以字符串的形式显示,每个项用逗号进行分割,可以使用join过滤器去处理

from flask import Flask,render_template
import config
app=Flask(__name__)
app.config.from_object(config)
@app.route('/about')
def about():
    context={
        "username":"lisi",
        "books":["红楼梦","西游记"]
    }
    return render_template("about.html",**context)

if __name__ == '__main__':
    app.run(debug=True)

about.html页面的内容修改为下:

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>关于我们title>
head>
<body>
    <h1>我们是最棒的。{{username|length}}h1>
    <h1>{{books}}h1>
    <h1>{{books|join(",")}}h1>
body>
html>

效果如下:

4、Jinja2中的控制语句

所有的控制语句都是放在{%…%}中,并且由{% endxx %}来进行结束,Jinja中常用的控制语句有if和for…in…
if举例:

from flask import Flask,render_template
import config
app=Flask(__name__)
app.config.from_object(config)
@app.route("/control")
def control():
    context={
        "age":17,
    }
    return render_template("control.html",**context)
if __name__ == '__main__':
    app.run(debug=True)

control.html页面的代码内容如下:

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>控制语句title>
head>
<body>
{% if age > 18%}
    <div>您已成年!div>
{% elif age < 18%}
    <div>您未成年!div>
{% else %}
    <div>您刚成年!div>
{% endif %}
body>
html>

效果如图:

for…in…举例

from flask import Flask,render_template
import config
app=Flask(__name__)
app.config.from_object(config)
@app.route("/control")
def control():
    context={
        "books":["红楼梦","西游记","水浒传","三国演义"]
    }
    return render_template("control.html",**context)
if __name__ == '__main__':
    app.run(debug=True)

control.html的代码内容如下:

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>控制语句title>
head>
<body>
<ul>
{% for book in books %}
    <li>{{book}}li>
{% endfor %}
ul>
body>
html>

代码执行效果如下:

如果想要循环字典该怎么办?

...
def control():
    context={
        "person":{"name":"liyu","age":18}
    }
    return render_template("control.html",**context)
...

control.html的代码内容如下:

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>控制语句title>
head>
<body>
{% for key,value in person.items() %}
    <div>{{key}}:{{value}}div>
{% endfor %}
body>
html>

效果显示如下:

5、模板继承

Flask中的模板可以继承,通过继承可以把模板中许多重复出现的元素抽取出来,放在父模板中,并且父模板通过定义block给子模板开一个口,子模板根据需要,再实现这个block。
首先将各视图函数写好

from flask import Flask,render_template
import config
app=Flask(__name__)
app.config.from_object(config)
@app.route('/about')
def about():
    context={
        "username":"lisi",
        "books":["红楼梦","西游记"]
    }
    return render_template("about.html",**context)
    
@app.route("/control")
def control():
    context={
        "age":18
    }
    return render_template("control.html",**context)

@app.route("/")
def index():
    return render_template("index.html")
    
if __name__ == '__main__':
    app.run(debug=True)

代码中牵扯到3个子模板,我们将父模板规定为base.html,父模板的代码如下:

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>{% block title%}{% endblock %}title>
head>
<body>
<ul>
    <li>
        <a href="/">首页a>
    li>
    <li>
        <a href="/control">控制页面a>
    li>
    <li>
        <a href="/about">关于我a>
    li>
ul>
{% block body%}{% endblock %}
<footer style="background-color:#ccc">我是底部footer>
body>
html>

其余的三个子模板代码如下:
index.html

{% extends "base.html" %}
{% block title %}
    知了传课首页
{% endblock %}

{% block body %}
    <h1>我是首页h1>
{% endblock %}

control.html

{% extends "base.html" %}
{% block title %}
    控制
{% endblock %}

{% block body %}
{% if age > 18%}
    <div>您已成年!div>
{% elif age < 18%}
    <div>您未成年!div>
{% else %}
    <h1>您刚成年!h1>
{% endif %}
{% endblock %}

about.html

{% extends "base.html" %}
{% block title %}
    关于我
{% endblock %}

{% block body %}
<h1>我们是知了。h1>
{% endblock %}

访问效果如下:


八、蓝图和子域名

之前我们写的url和视图函数都是处在同一个文件,如果项目比较大的话,这显然不是一个合理的结构,而蓝图可以帮助我们实现这种需求。功能是将项目模块划分

先写三个子模块,这三个文件全放在apps这个python packages里,结构如下:

book.py

from flask import Blueprint
#url_prefix就是设置url前缀
bp=Blueprint("book",__name__,url_prefix="/book")
@bp.route("/list")
def book_list():
    return "图书列表"

course.py

from flask import Blueprint
#url_prefix就是设置url前缀
bp=Blueprint("course",__name__,url_prefix="/course")
@bp.route("/list")
def course_list():
    return "课程列表"

user.py

from flask import Blueprint
#url_prefix就是设置url前缀
bp=Blueprint("user",__name__,url_prefix="/user")
@bp.route("/list")
def user_list():
    return "用户列表"

最后再写主代码

from flask import Flask
from apps.book import bp as book_bp
from apps.course import bp as course_bp
from apps.user import bp as user_bp
app=Flask(__name__)
app.register_blueprint(book_bp)
app.register_blueprint(course_bp)
app.register_blueprint(user_bp)

if __name__ == '__main__':
    app.run(debug=True)

效果图如下,其余两个url访问也没有问题

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/921924.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存