Flask+jinja如何根据条件引用jinja变量

2024-03-19 02:12:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个sqlalchemy查询在服务器端执行它。然后将变量传递回客户端,如下所示:

frames      = db.session.query(Frame).filter_by(task_id = task.id)

return render_template('annotate.html', attributes = attributes, \
                frames = frames, task_name = task.task_name, start_frame = start_frame)

其中帧包含许多帧信息I现在需要在客户端,我需要像这样引用框架。在

^{2}$

但是我想在单击next(start_frame+1)和previous(start_frame-1)按钮时更新img。 enter image description here

这意味着我必须更新frames"{{frames[start_frame]}}"数组(jinja变量)的引用,但我在javascript函数中却做不到。我有什么办法可以应付这种情况吗?在


Tags: nameid客户端taskdbframessqlalchemysession
1条回答
网友
1楼 · 发布于 2024-03-19 02:12:13

有很多方法可以实现你所需要的。在

我试图解释其中的两个,其中一个使用AJAX和一个单独的图像路径视图,另一个在客户端处理所有数据。在

这两种选择各有利弊。所以,你可以根据自己的喜好来决定。在

选项一

在服务器端创建一个视图,该视图为给定的frame_number参数返回<img>,并带有正确的src。 然后,在客户端,您可以通过当前帧编号请求该视图,并在

  • 第一次加载的页面
  • 按下下一步/上一步按钮

AJAX请求的这个新视图的一个例子是

@app.route('/image')
def image():
    task_name = request.args.get('task_name')

    try:
        frame_number = int(request.args.get('frame_number'))
    except (ValueError, TypeError):
        frame_number = 1

    # this line is just for example
    # run your query to get frame_name
    frame_name = str(frame_number) + '.png'

    return render_template('image.html', task_name=task_name, frame_name=frame_name)

这就是你的image.html。它只包含您在annotate.html中使用的img标记

^{pr2}$

最后,在您的annotate.html中,有一个加载图像的函数

function loadImage() {
    $.ajax({
        url: "{{ url_for('image') }}",
        type: "get",
        data: { 
            task_name: "{{ task_name }}",
            frame_number: $("image").attr("frame-number")
        },
        success: function(response) {
            $("#image").html(response);
        },
        error: function(xhr) {
            $("#image").html("an error occured");
        }
    });
}

可能,最棘手的部分是存储当前的frame_number。我建议将它存储为一个html属性在一个html元素中(最好是显示图像的地方)

<div id="image" frame-number="{{ frame_number }}"></div>

因此,在prev/next按钮的click action中,您可以更新相同的属性并再次调用loadImage()。在

我为一个完整的例子创建了一个gist。在

选项二

在这个选项中,您不需要创建额外的视图来提供当前图像。相反,我们将所有数据存储在客户机上(同样是在html属性中,但是这种存储也可以采用其他方式)。并且,通过选项I中类似的分页实现,我们将能够选择正确的frame_名称来构造图像路径。在

我把这个实现的重要部分放在这里,您可以查看这个gist。在

<!  here, you can store all the frame names on the client side  >
<!  notice that 'frames' parameter from view function is no longer available on the client side on you render it  >
<!  so, this way is kind of a transformation of that information to make it possible to store on the client side  >
{% for frame in frames %}
    <div id="frame-name-{{ loop.index }}" name="{{ frame.frame_name }}" hidden="hidden"></div>
{% endfor %}

function getFrameName() {
    return $("#frame-name-" + getFrameNumber()).attr("name");
}

function loadImage() {
    $("#image").attr("src", "/static/data/" + getTaskName() + "/" + getFrameName());
    $("#current").html(getFrameNumber());
}

相关问题 更多 >