Pagination 处理表单提交分页的正确方法?

Pagination 处理表单提交分页的正确方法?,pagination,flask,wtforms,Pagination,Flask,Wtforms,我有一个在搜索页面上进行搜索的表单: <form action="{{ url_for('searchresults') }}" method="get" name="noname" id="theform"> {{ form2.page(id="hiddenpage") }} ... some form inputs <button id = "mybutton" type = "submit" >Apply</button> <

我有一个在搜索页面上进行搜索的表单:

<form action="{{ url_for('searchresults') }}" method="get" name="noname" id="theform">
    {{ form2.page(id="hiddenpage") }}
    ... some form inputs
    <button id = "mybutton" type = "submit" >Apply</button>
</form>
searchresults视图处理以下表单:

@app.route('/searchresults', methods=['GET'])
def searchresults():
    form = SearchForm()
    # handle the form and get the search results using pagination
    page = int(request.args.getlist('page')[0])
    results = models.Product.query....paginate(page, 10, False)
    return render_template('searchresults.html', form=form, results=results, curpage=page)
render_模板中的结果将是我查询的前10个结果。在searchresults.html中,我显示结果,以及其他结果的下一个和上一个链接。本页还包含我在初次提交时重新安装的相同搜索表单。目前我正在使用

<a href="#" onclick="$('#hiddenpage').val( {{ curpage+1 }} ); $('#theform').submit();"> Next </a>

因此,下一个链接重新提交相同的初始表单,但页面值增加。我对这种方法不是很满意,因为当我将鼠标悬停在下一个链接上时,我看不到将指向的实际页面。它也开始感觉有点像黑客。有没有更自然的方法?当表单最初提交时,我可以使用它创建一个所需参数的长字符串,并在呈现页面中使用该字符串作为href={{url_for'searchresults'}}}?mystring,但这似乎也不自然。我应该如何处理这个问题?

您已经将表单配置为作为GET请求提交,因此您实际上不需要通过Javascript强制重新提交,通过将“下一页”和“上一页”链接设置为包含表单中所有参数的URL,并将页面修改为正确的“下一页”和“上一页”页码,可以获得相同的结果

这是非常容易做到的url_为。您添加的任何与路由组件不匹配的参数都将添加到查询字符串中,因此您可以执行以下操作:

<a href="{{ url_for('searchresults', categories=form.categories.data, page=form.page.data+1) }}"> Next </a>

需要记住的一件事是CSRF。如果您在表单中启用了它,那么您的下一个/上一个URL也需要有一个有效的令牌。或者,您可以禁用CSRF,这对于搜索表单可能没有问题。

利用URL中已经存在表单参数的事实,并使用request.args将URL参数传递到表单中:

form = SearchForm(request.args)
然后,如果使用小部件而不是字符串字段将页面字段设置为:

from wtforms.widgets import HiddenInput

class SearchForm(Form):
    page = HiddenField(widget=HiddenInput, default=1)
您可以在将表单传递到搜索结果页面之前增加页面:

form.page.data += 1
然后,在您的页面中,您只需创建指向下一页的链接:

<a href="{{ url_for('searchresults', **form.data) }}">Next</a>

嗨,米盖尔。谢谢你的回答。这似乎是一个更好的方法。这让我想到了两个我一直在思考的问题,但这将它们带到了最前沿。1单击下一个链接是否等同于提交包含类别和页面数据的GET表单?我知道最终生成的URL看起来是一样的,但在技术上还有什么不同吗?2为什么CSRF在这里很重要?我一直在我的表单中插入{{form.hidden_tag}}},却没有真正理解它们是如何实现某种形式的安全性的。如何为下一个/上一个URL提供有效令牌?1作为GET请求提交的表单与包含该表单所有字段的常规链接相同。如果您在此表单中有隐藏链接字段,则您的请求包含一个CSRF令牌,如果您在提交搜索时查看设置到服务器的URL,您可以看到该令牌。2我认为CSRF在这种情况下并不重要,因为请求无法修改服务器中的任何内容。我只想为此表单禁用它。攻击者可能希望在未经您允许的情况下利用您的登录状态执行某些操作。如果此搜索表单所做的只是读取一些数据并返回,并且这些数据对用户不敏感,则不需要CSRF。如果数据是敏感的,那么也许你应该考虑切换到POST请求。在这种情况下,您可以在URL中保留页码,并且只在表单中提交搜索参数。
<a href="{{ url_for('searchresults', **form.data) }}">Next</a>