关于如何使用上下文全局变量的问题


#1

最近需要用flask为系统做一个界面,现在只是需要内部用,所以目前没有用户登录的设置。
我的问题是,当通过浏览器传入一个 cropname_id 以后,我需要通过这个id查询数据库,再显示之后的种种信息。从书中我觉得应该用上下文全局变量g,但是我试了几种都不知道该怎么把通过id查询到的信息定义到变量中。

@app.route('/crop_<int:cropname_id>')
def cropzone(cropname_id):
    crop = TCropmodule.query.filter_by(id=cropname_id).first() #我希望传入这个变量为全局变量
    return render_template('cropzone.html', crop=crop)

@app.before_request
def get_crop():
    g.crop = request.args.get('crop') #这样写结果是None

@app.route('/ctrlinfo')
def ctrlinfo():

    return render_template('ctrlinfo.html', crop=g.crop)

#2

可以看看flask官方文档的tutorial,我记得其中的登录就是用 gsession 实现的。


#3

基础问题。Flask接收浏览器的传参有几种方式:

@app.route('/crop_<int:cropname_id>')
def cropzone(cropname_id):
    ...

这个是放在url path里的,顺便说最好是'/crop_/<int:cropname_id>'这样。

query string参数和formdata参数,可以直接使用flask.request.values;json body参数可以使用flask.request.json

最后你的需求其实并不需要用到flask.request.g


#5

确实,原来他的问题是传参:joy:


#6

不好意思,我没有表述清楚。我的意思是当我获取了<cropname_id>以后,后面很多页面都需要用到。
比如说我想在 @app.route('/ctrlinfo')里也通过<cropname_id>查询,或许应该把此处url path改成
/<int:cropname_id>/ctrlinfo更好


#7

好的 谢谢你


#8

你搞混了 request.args 的用法。这个属性包含请求数据里的查询字符串,而你的 URL 中 cropname_id 是作为 URL 的一部分传入的,比如:

/crop/2

这种情况下,你只能通过视图函数参数来获取 URL 变量的值。

如果你想在 request.args 里获取它,传递的方式应该是查询字符串,比如:

/crop?cropname_id=3

这时视图函数不需要定义 URL 变量:

@app.route('/cropinfo')
def cropzone():
    crop_id = request.args.get('cropname_id')
    ...

#9

嘿嘿,要认真审题。


#10

总算明白你的意思了——跨请求(跨页面)获取参数值?


#11

是的:joy:


#12

使用query string或者cookie等等都行。总之就是前端(jinja2)需要有一个地方是存放该变量,需要前端代码的配合而不仅仅是后端。

如果是使用query string就如前面李辉老师说的,设置成这样。

/crop?cropname_id=3

然后,点击/ctrlinfo链接时候就在jinja2模板代码里,从query string取出那个参数再传递过去。


#13

好的 非常感谢~


#14

谢谢老师,我再多理解学习一下教程