使用Flask访问对象属性

时间:2016-11-01 20:22:12

标签: python flask jinja2

我是Flask和模板的新手;我试图传递一个对象并在我的HTML页面上显示它的数据。

我有一个像

这样的分遣班
class Detachment:
    def __init__(self, name, ...):
        self.name = name
        self.... = ... # lots of data, mostly lists that I'd like to index

我尝试过这样的事情:

import Detachment as dt
from flask import Flask, request, redirect, url_for

@app.route('/')
def go():
    # stuff
    testDetachment = dt.Detachment('name')
    return redirect(url_for('cooliofunction', detachment=testDetachment)

@app.route('/templates')
def cooliofunction():
    return render_template('data.html', obj=request.args.get('detachment'))

我的data.html尝试:

{{obj}} <br />
{{obj.name}} <br />

虽然{{obj}}将显示对象地址,但我无法访问我的分离中设置的变量 - 它显示为空白。我是否接近整个问题,或者是否有一种简单的方法来访问对象的属性?

编辑:我使用的是重定向,因为testDetachment的创建实际上取决于文件上传,但我省略了它以专注于对象属性。

EDIT2: 所以我一直在使用重定向,因为我正在关注一个显示上传内容的文件上传教程,但我不需要这样做。直接渲染模板,我可以直接访问对象的属性。谢谢大家!

3 个答案:

答案 0 :(得分:2)

如果url_for获取的参数不是它正在构建的规则的一部分,它会将它们作为查询字符串附加,方法是将值转换为字符串。对象的字符串表示形式是其地址,而不是对象本身。在另一个视图中检索它时,您将检索对象的字符串表示形式,而不是实际对象。

如上所述,您应该省略重定向并直接在go视图中呈现模板。

如果您的实际代码具有该重定向的特定原因,那么您应该为该对象发送唯一标识符,并在另一个视图中重新加载它。例如,如果您正在使用数据库,请将对象提交到数据库,在URL中传递id,然后在另一个视图中通过id加载它。

答案 1 :(得分:1)

当你的路线获得obj时,它只是一个字符串,因为你如何传递它。 redirect(url_for('cooliofunction', detachment=testDetachment)实际上可能会隐式地将str(testDetachment)作为查询字符串传递。

即使name不是字符串的有效属性,Jinja也会忽略这一点:

from flask import Flask, render_template_string
app = Flask(__name__)
@app.route("/")
def test():
    obj = "Foo"
    return render_template_string("{{ obj }} {{ obj.name }}", obj=obj)
#Foo

如果要传递任意Python对象,请使用session或其他形式的存储(如数据库),这些存储将从一个请求持续存储到下一个请求。

答案 2 :(得分:0)

这不是url_for的用途。或者重定向,就此而言。

重定向适用于:

  1. 当页面不存在或无法访问时
  2. 你已经完成了一些事情(比如登录),现在他们可以继续前进,你希望他们去一个新的页面。
  3. 通常你会做这样的事情:

    @app.route('/login')
    def login():
         if request.method == 'POST' and request.form['username'] == 'the_user' \
            and request.form['password'] == 'super secret!':
             ... # log the user in here
             return redirect(url_for('main'))
    

    或者,如果您确实需要传递一些信息,可以使用url_for这样做:

    return redirect(url_for('page', extra='values', go='here', and_='will be added', to_the='query string', like='http://foo.bar?extra=values&go=here'))
    

    但是,不要这样做。