Skip to content

Instantly share code, notes, and snippets.

@anddam
Last active June 19, 2016 14:09
Show Gist options
  • Save anddam/35d723650b32e39714d5a3672756f616 to your computer and use it in GitHub Desktop.
Save anddam/35d723650b32e39714d5a3672756f616 to your computer and use it in GitHub Desktop.
Pagination issue while using Flask-WTF in Flask with Flask-Bootstrap and Flask-SQLAlchemy
from flask import Flask, render_template_string, request
from flask_bootstrap import Bootstrap
from jinja2 import Template
from flask_wtf import Form
from wtforms import StringField
from wtforms.validators import DataRequired
from flask_sqlalchemy import SQLAlchemy
# Build the app along with its extensions and the route
app = Flask(__name__)
app.config['SECRET_KEY'] = 'foobarbaz'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'
bs = Bootstrap(app)
db = SQLAlchemy(app)
# Define some module constants and the search form
search_template = """
{% extends 'bootstrap/base.html' %}
{% from 'bootstrap/wtf.html' import form_errors, form_field %}
{% from "bootstrap/pagination.html" import render_pagination %}
{% block content %}
<div style="padding:2em">
<p>Form:</p>
{% if form %}
<form class="form form-horizontal" method="get" role="form">
{{ form_errors(form, hiddens="only") }}
{{ form_field(form.search) }}
</form>
{% endif %}
<p>Data:</p>
{% if query_results %}
{{ render_pagination(query_results) }}
<ul>
{% for item in query_results.items %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{% endif %}
</div>
{% endblock %}
"""
class SearchForm(Form):
search = StringField('search', validators=[DataRequired()])
class Example(db.Model):
__tablename__ = 'examples'
id = db.Column(db.Integer, primary_key=True)
def __repr__(self):
return "%03d" % self.id
db.create_all()
for i in range(50):
db.session.add(Example())
db.session.commit()
@app.route('/')
def index():
form = SearchForm()
search = request.args.get('search')
if search:
match = '%' + str(search) + '%'
query_results = Example.query.filter(Example.id.like(match))
else:
query_results = Example.query
query_results = query_results.paginate(per_page=10)
return render_template_string(search_template, form=form, query_results=query_results)
@wgwz
Copy link

wgwz commented Jun 16, 2016

from flask import Flask, render_template_string, request
from flask_bootstrap import Bootstrap
from jinja2 import Template
from flask_wtf import Form
from wtforms import StringField
from wtforms.validators import DataRequired
from flask_sqlalchemy import SQLAlchemy
from flask_wtf.csrf import CsrfProtect

# Build the app along with its extensions and the route
app = Flask(__name__)
app.config['SECRET_KEY'] = 'foobarbaz'
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://'

Bootstrap(app)
db = SQLAlchemy(app)
CsrfProtect(app)

# Define some module constants and the search form
search_template = """
{% extends 'bootstrap/base.html' %}
{% from 'bootstrap/wtf.html' import form_errors, form_field %}
{% from "bootstrap/pagination.html" import render_pagination %}
{% block content %}
    <div style="padding:2em">
    <p>Form:</p>
    {% if form %}
        <form class="form form-horizontal" method="get" role="form">
          {{ form.csrf_token }}
          {{ form_errors(form, hiddens="only") }}
          {{ form_field(form.search) }}
        </form>
    {% endif %}
    <p>Data:</p>
    {% if query_results %}
    {{ render_pagination(query_results) }}
    <ul>
        {% for item in query_results.items %}
        <li>{{ item.id }}</li>
        {% endfor %}
    </ul>
    {% endif %}
    </div>
{% endblock %}
"""

class SearchForm(Form):
        search = StringField('search', validators=[DataRequired()])

class Example(db.Model):
    __tablename__ = 'examples'

    id = db.Column(db.Integer, primary_key=True)

    def __repr__(self):
        return "%03d" % self.id

db.create_all()
for i in range(50):
    db.session.add(Example())
db.session.commit()


@app.route('/', methods=['GET'])
def index():
    form = SearchForm(request.args)

    if request.method == 'GET' and form.validate():
        search = form.search.data
        match = '%' + str(search) + '%'
        query_results = Example.query.filter(Example.id.like(match))
    else:
        query_results = Example.query

    query_results = query_results.paginate(per_page=10)
    return render_template_string(search_template, form=form, query_results=query_results)

if __name__ == "__main__":
    app.run(debug=True)

@anddam
Copy link
Author

anddam commented Jun 19, 2016

I don't get the logic of that edit, the

request.method == 'GET'

in the if condition is unnecessary since the view is only registered for GET method, also the validation will fail at first loading.

This example doesn't need CSRF anyway, why going through the hassle of rendering it in the form?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment