Correct way to handle pagination with form submission?

折月煮酒 提交于 2021-02-08 11:21:51

问题


I have a form for doing a search on a search page:

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

The form is a SearchForm, where

class SearchForm(Form):
    page = HiddenField()
    categories = SelectMultipleField(u'Text', validators=[Optional()])
    # some other stuff...

The view for searchresults handles the form:

@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)

The results in render_template will be the first 10 results of my query. In searchresults.html I display the results, along with a next and previous link for the other results. This page also contains the same search form which I re-instate as per the initial submission. Currently I'm handling the next and previous links using

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

So the next link re-submits the same initial form, but with the page value increased. I'm not really happy with this approach because when I hover over the next link I don't see the actual page I will be directed to. It also is starting to feel like a bit of a hack. Is there a more natural way to do this? When the form is initially submitted I could use it to create a long string of the desired parameters and use that string in the rendered page as href=" {{ url_for('searchresults') }}?mystring", but this also seems unnatural. How should I handle this?


回答1:


You have your form configured to submit as a GET request, so you don't really need to force a re-submission through Javascript, you can achieve the same result by setting the next and prev links to URLs that include all the parameters in your form with the page modified to the correct next and previous page numbers.

This is really easy to do with url_for(). Any argument you add that do not match route components will be added to the query string, so you can do something like this:

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

One thing to keep in mind is CSRF. If you have it enabled in your form, then your next/prev URLs will also need to have a valid token. Or you can disable CSRF, which for a search form might be okay.




回答2:


Take advantage of the fact that your form arguments are already present in the URL and use request.args to pass the URL parameters into your form:

form = SearchForm(request.args)

Then, if you make your page field an IntegerField with a HiddenInput widget instead of a string field:

from wtforms.widgets import HiddenInput

class SearchForm(Form):
    page = HiddenField(widget=HiddenInput, default=1)

you can increment page before you pass the form off to your search results page:

form.page.data += 1

And then, in your page, you simply create the link to the next page:

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


来源:https://stackoverflow.com/questions/28132465/correct-way-to-handle-pagination-with-form-submission

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!