Reputation: 105
I am stumped regarding what is causing an error I am experiencing while trying to get pagination to work properly using Flask-SQLAlchemy. Here is the view for the relevant page:
@main.route('/collections/<int:page>', defaults={"page": 1})
def all_collections(page):
users = User.users_with_bottles().paginate(page=page, per_page=1, error_out=False)
if users is None:
return redirect(url_for('main.collection',
name=current_user.username))
total_collections = Bottle.total_collections()
return render_template('gallery.html',
users=users,
total_num=total_collections,
title='Browse Collections')
And here is the part of gallery.html
which seems to cause the issue:
{% for page in users.iter_pages() %}
{% if page %}
# the below line seems to be the issue
<a href="{{ url_for('main.all_collections', page=page) }}">{{ page }}</a>
{% else %}
...
{% endif %}
{% endfor %}
As far as I can tell, there are pages which should work for linking, as if I do:
{% if page %}
{{ page }}
{% endif %}
It prints 1 2 3
. Removing the url_for
part in gallery.html
causes http://127.0.0.1:5000/collections/1
to load normally. I'm unsure about the cause of this issue because I have a number of other main.
views with dynamic URLs which work fine, so I don't know what I am doing wrong in this instance.
Below is the traceback for this issue:
Traceback (most recent call last):
File "C:\Users\Me\PycharmProjects\flask-sake-project\venv\Lib\site-packages\flask\app.py", line 2464, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Users\Me\PycharmProjects\flask-sake-project\venv\Lib\site-packages\flask\app.py", line 2450, in wsgi_app
response = self.handle_exception(e)
File "C:\Users\Me\PycharmProjects\flask-sake-project\venv\Lib\site-packages\flask\app.py", line 1867, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\Me\PycharmProjects\flask-sake-project\venv\Lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Users\Me\PycharmProjects\flask-sake-project\venv\Lib\site-packages\flask\app.py", line 2447, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\Me\PycharmProjects\flask-sake-project\venv\Lib\site-packages\flask\app.py", line 1952, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\Me\PycharmProjects\flask-sake-project\venv\Lib\site-packages\flask\app.py", line 1821, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\Me\PycharmProjects\flask-sake-project\venv\Lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Users\Me\PycharmProjects\flask-sake-project\venv\Lib\site-packages\flask\app.py", line 1950, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\Me\PycharmProjects\flask-sake-project\venv\Lib\site-packages\flask\app.py", line 1936, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\Me\PycharmProjects\flask-sake-project\app\main\views.py", line 46, in all_collections
return render_template('gallery.html',
File "C:\Users\Me\PycharmProjects\flask-sake-project\venv\Lib\site-packages\flask\templating.py", line 137, in render_template
return _render(
File "C:\Users\Me\PycharmProjects\flask-sake-project\venv\Lib\site-packages\flask\templating.py", line 120, in _render
rv = template.render(context)
File "C:\Users\Me\PycharmProjects\flask-sake-project\venv\Lib\site-packages\jinja2\environment.py", line 1090, in render
self.environment.handle_exception()
File "C:\Users\Me\PycharmProjects\flask-sake-project\venv\Lib\site-packages\jinja2\environment.py", line 832, in handle_exception
reraise(*rewrite_traceback_stack(source=source))
File "C:\Users\Me\PycharmProjects\flask-sake-project\venv\Lib\site-packages\jinja2\_compat.py", line 28, in reraise
raise value.with_traceback(tb)
File "C:\Users\Me\PycharmProjects\flask-sake-project\app\templates\gallery.html", line 1, in top-level template code
{% extends 'base.html' %}
File "C:\Users\Me\PycharmProjects\flask-sake-project\app\templates\base.html", line 6, in top-level template code
{% block content %}{% endblock %}
File "C:\Users\Me\PycharmProjects\flask-sake-project\app\templates\gallery.html", line 39, in block "content"
<a href="{{ url_for('main.all_collections', page=page) }}">{{ page }}</a>
File "C:\Users\Me\PycharmProjects\flask-sake-project\venv\Lib\site-packages\flask\helpers.py", line 370, in url_for
return appctx.app.handle_url_build_error(error, endpoint, values)
File "C:\Users\Me\PycharmProjects\flask-sake-project\venv\Lib\site-packages\flask\app.py", line 2216, in handle_url_build_error
reraise(exc_type, exc_value, tb)
File "C:\Users\Me\PycharmProjects\flask-sake-project\venv\Lib\site-packages\flask\_compat.py", line 39, in reraise
raise value
File "C:\Users\Me\PycharmProjects\flask-sake-project\venv\Lib\site-packages\flask\helpers.py", line 357, in url_for
rv = url_adapter.build(
File "C:\Users\Me\PycharmProjects\flask-sake-project\venv\Lib\site-packages\werkzeug\routing.py", line 2179, in build
raise BuildError(endpoint, values, method, self)
werkzeug.routing.BuildError: Could not build url for endpoint 'main.all_collections' with values ['page'].
Edit: I will also note that all my searches for a solution to this error have not really helped, hence why I asked this question. I only found one other Stack Overflow post with someone experiencing the same issue as me and it did not have an accepted answer (and few replies generally).
Upvotes: 0
Views: 455
Reputation: 9440
I think what's going wrong how you're handling the default values, you've currently got:
@main.route('/collections/<int:page>', defaults={"page": 1})
def all_collections(page):
...
Then you are passing in a page integer as well url_for('...', page=x)
so flask is ending up with two values, and getting grumpy. What you want to do is something like:
@main.route('/collections/<int:page>')
@main.route('/collections/', defaults={'page': 1} # if no page is asked for-- return page 1.
def all_collections(page):
...
So now /collections/
will use the default value of 1
but if you specify a page
you trigger the other route option, and nothing gets confused.
Upvotes: 1