UndefinedError:' url_for_other_page'未定义

时间:2015-07-08 04:45:23

标签: python flask pagination sqlalchemy

我遇到了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 &raquo;</a>
      {% endif %}
      </div>
</div>

1 个答案:

答案 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