g对象

### 保存全局变量的g属性:
g:global
1. g对象是专门用来保存用户的数据的。
2. g对象在一次请求中的所有的代码的地方,都是可以使用的。

项目结构:

g_demo.py文件代码:

from flask import Flask,g,render_template,request
from utils import login_log
app = Flask(__name__) @app.route('/',methods=['GET','POST'])
def hello_world():
return 'index' @app.route('/login/',methods=['GET','POST'])
def login():
if request.method == 'GET':
return render_template('login.html')
else:
username = request.form.get('username')
password = request.form.get('password')
if username == 'hyq' and password == '':
#就认为当前这个用户的用户名和密码正确
g.username = 'hyq'
g.ip= 'xx'
login_log(username)
return '恭喜!登录成功'
else:
return '您的用户名或密码错误' if __name__ == '__main__':
app.run(debug=True)

utils.py文件代码:

from flask import g

def login_log(username):
print ('当前登录用户是:%s' % g.username) def login_ip_log(ip):
pass

login.html文件代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="{{ url_for('login') }}" method="post">
<table>
<tbody>
<tr>
<td>用户名:</td>
<td><input type="text" placeholder="请输入用户名" name="username"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="text" placeholder="请输入密码" name="password"></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="登录"></td>
</tr>
</tbody>
</table>
</form>
</body>
</html>

钩子函数before_request

主app文件代码:

from flask import Flask,render_template,request,session,url_for,redirect,g
import os app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(24) @app.route('/')
def hello_world():
print('index')
return 'index' @app.route('/login/',methods=['GET','POST'])
def login():
print('login')
if request.method =='GET':
return render_template('login.html')
else:
username = request.form.get('username')
password = request.form.get('password')
if username == 'hyq'and password =='yunqing141':
session['username'] = 'hyq'
return '登录成功'
else:
return '用户名或密码错误!' @app.route('/edit/')
def edit():
if hasattr(g,'username'):
return '修改成功'
else:
return redirect(url_for('login')) # before_request:在请求之前执行的
# before_request是在视图函数执行之前执行的
# before_request这个函数只是一个装饰器,他可以把需要设置为钩子函数的代码放到视图函数执行之前来执行 @app.before_request
def my_before_request():
if session.get('username'):
g.username = session.get('username')
print('hello world') if __name__ == '__main__':
app.run(debug=True)

login.html文件代码:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="登录"></td>
</tr>
</table>
</form>
</body>
</html>

1. before_request:
* 在请求之前执行的
* 是在视图函数执行之前执行的
* 这个函数只是一个装饰器,他可以把需要设置为钩子函数的代码放到视图函数执行之前来执行

在以上代码中,my_before_request()函数在视图函数请求执行之前就执行了,因此会把session中的username信息保存到g中,但是需要注意的是,对应前一篇博客对g函数的说明,只要重启服务器,

session.get('username')便得不到'username'的信息了。使用这个钩子函数的好处就在于,可以在视图函数执行之前,就把用户资料在数据库查询的工作完成,减少视图函数中对数据库的访问操作

钩子函数context_processor:

问题:当用户登录以后,不同的页面都需要显示用户信息,例如用户名,这个时候不同的模板,index(登陆前的主页),登录后的页面等等在用户名那个地方就要传入相同的参数,

@app.route('/')
def index():
print('index')
return render_template('index.html',username="hyq") @app.route('/edit/')
def edit(): return render_template('edit.html',username='hyq')

注意,此相应的Html文件已经插入username这个变量,但是这样太麻烦,于是用到了context_processs函数

主app文件代码:

 from flask import Flask,render_template,request,session,url_for,redirect,g
import os app = Flask(__name__)
app.config['SECRET_KEY'] = os.urandom(24) @app.route('/')
def index():
print('index')
return render_template('index.html') @app.route('/login/',methods=['GET','POST'])
def login():
print('login')
if request.method =='GET':
return render_template('login.html')
else:
username = request.form.get('username')
password = request.form.get('password')
if username == 'hyq'and password =='yunqing141':
session['username'] = 'hyq'
return '登录成功'
else:
return '用户名或密码错误!' @app.route('/edit/')
def edit():
# if hasattr(g,'username'):
# return '修改成功'
# else:
# return redirect(url_for('login'))
return render_template('edit.html')
# before_request:在请求之前执行的
# before_request是在视图函数执行之前执行的
# before_request这个函数只是一个装饰器,他可以把需要设置为钩子函数的代码放到视图函数执行之前来执行 @app.before_request
def my_before_request():
#if session.get('username'):
if session.get('username'):
g.username = session.get('username',username="hyq")
print('有的有的')
print('hello world') @app.context_processor
def my_context_processor():
#username = session.get('username')
#if username:
return {'username':'hyq'} if __name__ == '__main__':
app.run(debug=True)

注意,此时index和edit函数的返回渲染模板里面,已经不用加上username='hyq'这个变量了,直接由my_context_processor返回值传参,但是这里要小心的是,47行执行的时候并不能得到username,从而return {'username':username}会报错,因为还没有登录,所以47-49行代码可以考虑在数据库中查找username的值

* 上下文处理器应该返回一个字典。字典中的`key`会被模板中当成变量来渲染。
* 上下文处理器中返回的字典,在所有页面中都是可用的。
* 被这个装饰器修饰的钩子函数,必须要返回一个字典,即使为空也要返回。

 

Flask web开发之路十三的更多相关文章

  1. Flask web开发之路九

    flask_scripts介绍 项目结构如下: flask_script_demo.py文件: from flask import Flask app = Flask(__name__) @app.r ...

  2. Flask web开发之路一

    之前学过一段时间的flask,感觉还是挺好用的,自己的专利挖掘项目也想这个web框架来搭建,于是重新开始基础学习 环境:win10,python3.6,pycharm2017,虚拟环境virtuale ...

  3. Flask web开发之路十四

    今天开始Flask的实战,创建一个项目,实现包括用户登录.注册.注销.发表博客.评论以及检索等功能 首先给出项目结构: 1.config.py文件: 存放各种配置信息 import os # dial ...

  4. Flask web开发之路十二

    ge请求和post请求 ### get请求和post请求:1. get请求: * 使用场景:如果只对服务器获取数据,并没有对服务器产生任何影响,那么这时候使用get请求. * 传参:get请求传参是放 ...

  5. Flask web开发之路十一

    首先写一下cookie和session的概念,然后是Flask中session的工作机制以及操作session ### cookie: 1. `cookie`出现的原因:在网站中,http请求是无状态 ...

  6. Flask web开发之路十

    首先介绍循环引用的问题: 当一个模块需要引用另一个模块的类,而另一个模块又需要引用这个模块的类时,就出现了循环引用,而没法导入类,这时候可以切断其中一条引用路径,增加一个模块 项目结构: models ...

  7. Flask web开发之路八

    今天写Flask_SQLAlchemy的外键及其关系 ### Flask-SQLAlchemy外键及其关系: 主app文件代码: from flask import Flask from flask_ ...

  8. Flask web开发之路七

    今天写SQLAlchemy数据库 首先介绍ORM的概念: ORM,Object类,Relationship:关系,Mapping:映射,也就是模型关系映射 flask-sqlalchemy是一套ORM ...

  9. Flask web开发之路六

    紧接着上篇文档,写模板继承和block,URL链接和加载静态文件 模板继承和block 项目结构 主app文件代码: from flask import Flask,render_template a ...

随机推荐

  1. ThinkPhp 使用PhpExcel导出导入多语言文件

    在ThinkPHP 里已经实现了多语言功能,只要在指定的目录下创建对应的语言文件并填充内容,即可实现多语言功能 而多语言的翻译却是一个很麻烦的事情,因为客户特定的行业问题导致我们翻译可能是不准确的 于 ...

  2. windows多线程同步--互斥量

    关于互斥量的基本概念:百度百科互斥量 推荐参考博客:秒杀多线程第七篇 经典线程同步 互斥量Mutex 注意:互斥量也是一个内核对象,它用来确保一个线程独占一个资源的访问.互斥量与关键段的行为非常相似, ...

  3. Linux内核编译与安装

    2013-04-16    Linux内核介绍  Linux内核是一个用C语言写成的,符合POSIX标准的类Unix操作系统.内核是操作系统中最基本的一部分,提供了众多应用程序访问计算机硬件的机制.L ...

  4. tmux的复制粘贴

    tmux有面板的概念,这导致普通终端下的ctrl+shift+C的模式复制出来的文本会串行.如果面板只有一列当然没有问题,但当面板有多列时,复制就会出问题.于是tmux提出了类似vim的复制模式.因此 ...

  5. Rocket Typist for Mac(增强型文本快速输入工具)破解版安装

    1.软件简介    Rocket Typist 是 macOS 系统上一款增强型文本快速输入工具,我们可以利用这款工具预先设置保存好很多日常生活学习或是工作中常用的文本片段,还能设定部分内容为变量,当 ...

  6. 跟我学SharePoint2013视频培训课程——版本控制示例(15)

    课程简介 第15天,SharePoint 2013版本控制示例 视频 SharePoint 2013 交流群 41032413

  7. [svc]二三层数据格式&&三层数据如何匹配路由

    网络知识拾遗 tcpip的4&7层模型 PDU数据包在不同层的不同称呼 物理层(一层)PDU指数据位(Bit). 数据链路层(二层)PDU指数据帧(Frame). 网络层(三层)PDU指数据包 ...

  8. DIOCP-DIOCPv5的处理能力

    今天和BB讨论了下DiocpV5的单连接处理能力.一直没有做过这方面的测试,稍微试了一下. 把开始的时候客户端Sleep(10),为了测试处理能力,把Sleep(10)去掉了,20秒(实际应该算17秒 ...

  9. 【iCore1S 双核心板_FPGA】例程十六:基于SPI的ARM与FPGA通信实验

    实验现象: 核心代码: int main(void) { int i,n; ]; ]; HAL_Init(); system_clock.initialize(); led.initialize(); ...

  10. Entity Framework定义外键,限制通过migration命令自动更改字段名称

    1.问题 在定义一个表的外键时,通过add-migration命令生成,并通过update-database更新到数据库,发现外键名称发生了重命名.举例说明: 人员表[User](Id,Name,Pa ...