我遇到了Flask中继承代码的(可能)新手错误。我的模板中的辅助函数url_for_other_page()
在相关页面加载时未被初始化。返回自描述性错误:
UndefinedError: 'url_for_other_page' is undefined
我知道造成这种情况的原因 - 帮助方法没有得到轮询,因为它没有暴露在相关网址或其他内容中。如果没有暴露超出相关URL路径所必需的方法,最好的方法是什么?辅助函数应该在应用程序逻辑的其他位置(例如 init ?)
下面是导致违规错误的模板片段,以及应用程序逻辑所在的整个core.py。对/ images进行请求,将entries_index()
的结果返回给模板调用。这个分页代码几乎是从Flask's own examples中选择的。如果您需要其他上下文,则完整来源可以是viewed on Github。
core.py
import hashlib, os
from flask import request, session, render_template, flash, url_for, \
redirect, send_from_directory
from werkzeug import secure_filename
from kremlin import app, db, dbmodel, forms, imgutils, uploaded_images
from pagination import Pagination
@app.route('/')
def home_index():
""" Display the glasnost logo, attempt to replicate old behavior """
return render_template('home.html')
@app.route('/images', defaults={'page': 1})
@app.route('/images/page/<int:page>')
def entries_index(page):
""" Show an index of image thumbnails """
posts = dbmodel.Post.query.all()
pagination = Pagination(page, 2, len(posts))
#import pdb; pdb.set_trace()
return render_template('board.html', form=forms.NewPostForm(),
posts=posts, pagination=pagination)
# The offending helper method
def url_for_other_page(page):
args = request.view_args.copy()
args['page'] = page
return url_for(request.endpoint, **args)
app.jinja_env.globals['url_for_other_page'] = url_for_other_page
@app.route('/images/<int:post_id>')
def view_post(post_id):
""" Show post identified by post_id """
post = dbmodel.Post.query.get_or_404(post_id)
comments = dbmodel.Comment.query.filter_by(parent_post_id=post_id)
return render_template('post.html', post=post, comments=comments)
@app.route('/images/get/<filename>')
def send_file(filename):
"""Send image file to browser"""
return send_from_directory(app.config['UPLOADED_IMAGES_DEST'],
filename)
@app.route('/images/add/', methods=['POST'])
def add_image():
""" Add a new image """
form = forms.NewPostForm()
if form.validate_on_submit():
filename = secure_filename(form.upload.file.filename)
fileext = os.path.splitext(filename)[1]
filedata = form.upload.file.stream.read()
# Calculate SHA1 checksum
h = hashlib.new('sha1')
h.update(filedata)
filehash = h.hexdigest()
# Validate file uniqueness
dupe = dbmodel.Image.query.filter_by(sha1sum=filehash).first()
if dupe:
flash("Image already exists: %s" % (dupe))
return redirect(url_for('entries_index'))
else:
# File is unique, proceed to create post and image.
# Save file to filesystem
# Rewind file, it was read() by the SHA1 checksum
# routine
form.upload.file.seek(0)
# Proceed with storage
try:
uploaded_images.save(storage=form.upload.file,
name=''.join([filehash, '.']),
)
# FIXME: generate thumbnail in a safer way.
# This is fairly horrible and I'm sorry.
imagepath = uploaded_images.path(''.join([filehash, fileext]))
imgutils.mkthumb(imagepath)
except IOError:
flash("Oh god a terrible error occured while saving %s" %
(filename))
else:
dbimage = dbmodel.Image(filename, filehash)
db.session.add(dbimage)
user = None
if "uid" in session:
user = dbmodel.User.query.filter_by(
id=session['uid']
).first()
note = form.note.data
#TODO: Implement tags.
# Create a new post with the image
post = dbmodel.Post(image=dbimage, title=filename,\
note=note, user=user)
db.session.add(post)
# Commit database transaction
db.session.commit()
flash("Image successfully posted!")
return redirect(url_for('entries_index'))
else:
flash("Your form has terrible errors in it.")
return(redirect(url_for("entries_index")))
模板调用(摘自board.html)
<div id='ImageboardPageTop'>
<div class=pagination>
{% for page in pagination.iter_pages() %}
{% if page %}
{% if page != pagination.page %}
<a href="{{ url_for_other_page(page) }}">{{ page }}</a>
{% else %}
<strong>{{ page }}</strong>
{% endif %}
{% else %}
<span class=ellipsis>…</span>
{% endif %}
{% endfor %}
{% if pagination.has_next %}
<a href="{{ url_for_other_page(pagination.page + 1)
}}">Next »</a>
{% endif %}
</div>
</div>
答案 0 :(得分:1)
这一行需要进入你的core.py,而不是函数内部 - url_for_other_page
-
app.jinja_env.globals['url_for_other_page'] = url_for_other_page
代码 -
def url_for_other_page(page):
args = request.view_args.copy()
args['page'] = page
return url_for(request.endpoint, **args)
app.jinja_env.globals['url_for_other_page'] = url_for_other_page