目录

  1. 1. 前言
  2. 2. 安装
  3. 3. 测试
  4. 4. 代码分析
    1. 4.1. 创建实例
    2. 4.2. route路由
    3. 4.3. HTTP方法
    4. 4.4. Redirect重定向
    5. 4.5. main入口
      1. 4.5.1. debug调试模式
  5. 5. 模板渲染
    1. 5.1. render_template
    2. 5.2. render_template_string
    3. 5.3. 基本语法
  6. 6. 后日谈

LOADING

第一次加载文章图片可能会花费较长时间

要不挂个梯子试试?(x

加载过慢请开启缓存 浏览器默认开启

flask基础

2023/7/4 Basic python flask
  |     |   总文章阅读量:

前言

突然意识到自己做了不少flask框架的题还没有好好学一下flask基础

而且ssti的题没学flask基础的话感觉学得不是特别明白

那就开个坑进行一个学

参考先知社区的文章

官方文档


安装

已有python环境,命令行输入

pip install flask

即可安装


测试

from flask import Flask
app = Flask(__name__)   # 创建一个flask实例
@app.route('/')         # 路由规则,即符合规则的url请求将会触发此函数
def flask_test():
    return '<h1>Hello World!</h1>'
if __name__ == '__main__':  # 如果是已主程序的方式启动(不是以导入模块的方式),则运行flask实例 
    app.run(port=8000)               # app.run(debug=True),即可开启debug模式
# 端口要选择没被占用的

运行py脚本,就开启了一个http://127.0.0.1:8000/服务器

浏览器访问该地址

image-20230705103312657

说明flask引入成功,并且能正常工作


代码分析

创建实例

from flask import Flask
app = Flask(__name__)   # 创建一个flask实例

第一个参数是应用模块或者包的名称。 __name__ 是一个适用于大多数情况的快捷方式。有了这个参数, Flask 才能知道在哪里可以找到模板和静态文件等东西


route路由

解析url地址和所携带的参数,对网络请求进行筛选

route中所带的参数是一个字符串类型,它的内容就对应它要响应的标示,即route()会告诉 Flask 触发函数的 URL

函数返回需要在用户浏览器中显示的信息。默认的内容类型是 HTML ,因此字符串中的HTML标签会被浏览器渲染。

@app.route('/')
def flask_test():
    return '<h1>Hello World!</h1>'

通过把 URL 的一部分标记为 <variable_name> 就可以在 URL 中添加变量,监听带参数的url

@app.route('/name/<name>')
def flask_test(name):
    return '<h1>Hello</h1>' + name

访问http://127.0.0.1:8000/name/admin,此时admin被当做参数name传入函数中

image-20230705104837982

再来一个例子看看

@app.route('/user/<username>')
def user(username):
    return 'username:{0}'.format(username)

image-20230705111832785

可以看到第二个route路由,其中加了/,这就是传入参数的接口,其中username相当于一个变量,将username放进def user()中,然后用format带入username


HTTP方法

缺省情况下,一个路由只回应 GET 请求。可以使用 route() 装饰器的 methods 参数来处理不同的 HTTP 方法。

from urllib import request
from flask import Flask,request
app = Flask(__name__)

@app.route('/method',methods = ['GET','POST'])
def method():
    if request.method == 'GET':
        return '现在的方法是GET'
    elif request.method == 'POST':
        return '现在的方法是POST'

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

可以看到请求方法要大写,路由中要用[]括起来

image-20230705112659609

image-20230705112720499

也可以把不同方法所对应的视图分别放在独立的函数中。 Flask 为每个常用 的 HTTP 方法提供了捷径,如get()post() 等等。

@app.get('/login')
def login_get():
    return 'get'

@app.post('/login')
def login_post():
    return 'post'

image-20230705113101376

image-20230705113129444


Redirect重定向

这个关键字在flask中用于重定向,需要配合url_for使用,url_for使用于构造url

比如常见的用法就是在登陆页面,输入正确的账号密码后,重定向到另外一个页面中

基础代码:

@app.route('/')
def index():
    return redirect(url_for('login'))

使用例:

from flask import Flask,request,redirect,url_for
app = Flask(__name__)

@app.route('/login',methods = ['GET','POST'])
def login():
    username = 'admin' # 定义username
    password =  '123456' # 定义password
    user = request.args.get('username') # 获取传入的用户名
    passwd = request.form['passwd']  # 获取传入的密码
    if user == username and passwd == password:  # 判断用户名和密码是否和预定义的一样
        return redirect(url_for('login_s'))  # 如果一样,则通过redirect和url_for重定向到login_s中
    else:
        return 'username or password error' # 错误则返回用户名或者密码错误

@app.route('/login_s',methods = ['GET']) # 定义一个新的页面login_s
def login_s():
        return '登录成功' # 返回登陆成功

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

没有传入参数的情况下访问/login会直接报错

image-20230705113857592

传入错误的值,不发生重定向跳转

image-20230705114122069

传入正确的值,此时重定向跳转到/login_s页面

image-20230705114051205


main入口

当.py文件被直接运行时,if __name__ == '__main__'之下的代码块将被运行;当.py文件以模块形式被导入时,if name == 'main'之下的代码块不被运行

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

debug调试模式

flask编写的程序和php不一样,每一次变动都需要重启服务器来执行变更,就显得很麻烦,为了应对这种问题,flask中的debug模式可以在不影响服务器运行下,执行更新每一次的变更

测试的时候,我们可以使用debug,方便调试

下面两种方法都可以启用debug

app.debug = True
app.run(debug=True)

注:debug模式启用后,访问/console路由可以打开交互调试器进行命令执行,前提是知道pin码

debug开启后,请求过程中发生错误时会产生报错页面

image-20230705112125751


模板渲染

在上面的路由部分我们知道可以在字符串中添加HTML标签来被浏览器渲染

但是这种办法过于笨拙,所以我们需要一个准备好的模板来帮我们完成这件事

模板渲染需要注意一点,py文件和外部文件要放在同一个文件夹下,并且放置外部文件的文件夹名,要重命名为templates

render_template

这个函数可以将py文件中的对应数据渲染至index.html,如果有多个参数,则使用形参的形式传出,如下面py文件代码所示,有三个参数,那么就用**contents传过去

index.html文件中,需要使用格式为 {{ 参数名 }}接受参数值

例:

test.py

from flask import Flask, render_template

app = Flask(__name__)


@app.route('/')
def index():
    contents = {'username': 'admin', 'password': '123456', 'system': 'Hacker!'}
    return render_template('index.html', **contents)


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

templates/index.html

<html>
<head>
<body>
<h1>Hello,{{username}}</h1>
<h2>{{password}}</h2>
<h3>{{system}}</h3>
</body>
</head>
</html>

image-20230705170942510

render_template_string

这个是渲染字符串的一个函数,此函数可以将html代码变成字符串, 然后使用render_template_string(xxx)将文件渲染输出

这个可以用于没有外部文件的情况,直接在同文件下,定义好html代码,然后直接就可以渲染

render_template_string和render_template都是渲染,但是前者是字符串,后者是外部文件

基本语法

{%%}:主要用来声明变量,也可以用于条件语句和循环语句

{% set c='ciallo' %}
{% if 81==9*9 %}ciallo{% endif %}
{% for i in ['1','2','3'] %}ciallo{%endfor%}

{{}}:用于将表达式打印到模板输出,比如我们一般在里面输入2-1,2*2,或者是字符串,调用对象的方法,都会渲染出结果

{{2-1}} #输出1
{{2*2}} #输出4

这也就是SSTI的来源

{ ## }:表示未包含在模板输出中的注释(使用时去掉里面的空格,博客渲染的时候也会被注释掉

##:有和{%%}相同的效果


后日谈

咦,怎么和博客模板渲染差不多(