下面的代码给出了错误:
Traceback (most recent call last): File "pdf.py", line 14, in <module> create_pdf(render_template('templates.htm')) File "/usr/local/lib/python2.7/dist-packages/flask/templating.py", line 123, in render_template ctx.app.update_template_context(context) AttributeError: 'NoneType' object has no attribute 'app'
码:
from xhtml2pdf import pisa from StringIO import StringIO from flask import render_template,Flask app=Flask(__name__) app.debug=True @app.route("/") def create_pdf(pdf_data): filename= "file.pdf" pdf=pisa.CreatePDF( StringIO(pdf_data),file(filename, "wb")) if __name__ == "__main__": create_pdf(render_template('templates.htm'))
从代码中,我可以看到你希望允许用户下载pdf。
from xhtml2pdf import pisa from StringIO import StringIO from flask import render_template,Flask, Response app=Flask(__name__) app.debug=True @app.route("/") def create_pdf(pdf_data): filename= "file.pdf" pdf=pisa.CreatePDF( StringIO(pdf_data),file(filename, "wb")) return Response(pdf, mimetype='application/octet-stream', headers={"Content-Disposition": "attachment;filename=%s" % filename}) if __name__ == "__main__": app.run()
现在开始 python aboveprogram.py
python aboveprogram.py
去 http://localhost:5000
import threading from flask import Flask, render_template app = Flask("myapp") app.route('/') def get_thing(thing_id): thing = cache.get(thing_id) if thing is None: # Handle cache miss... elif is_old(thing): # We'll serve the stale content but let's # update the cache in a background thread t = threading.Thread( target=get_thing_from_datastore_render_and_cache_it, args=(thing_id,) ) t.start() return thing def get_thing_from_datastore_render_and_cache_it(thing_id): thing = datastore.get(thing_id) cache.set(render_template(thing))
但是,当get_thing_from_datastore_render_and_cache_it在Flask请求周期之外的后台线程中运行时,我得到了上面显示的错误,因为该线程无法访问请求上下文。
get_thing_from_datastore_render_and_cache_it
发生该错误是因为Flask提供了开发人员快捷方式以允许自动访问模板中的请求变量-换句话说,这是由Flask决定如何包装Jinja2的功能而不是Jinja2本身引起的。解决这个问题的方法是直接使用Jinja2的渲染:
import jinja2 def render_without_request(template_name, **template_vars): """ Usage is the same as flask.render_template: render_without_request('my_template.html', var1='foo', var2='bar') """ env = jinja2.Environment( loader=jinja2.PackageLoader('name.ofmy.package','templates') ) template = env.get_template(template_name) return template.render(**template_vars)
该功能假定你的Flask应用程序具有传统的模板子文件夹。具体来说,这里的项目结构为
. └── name/ ├── ofmy/ | ├── package/ | | ├── __init__.py <--- Where your Flask application object is defined | | └── templates/ | | └── my_template.html | └── __init__.py └── __init__.py
如果你在下面有一个子目录结构templates/,则只需从模板文件夹的根目录传递相对路径,就像使用Flask的路径一样render_template。