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