Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problem with endpoints which have multiple routes #20

Open
hieu-n opened this issue Mar 29, 2017 · 0 comments
Open

Problem with endpoints which have multiple routes #20

hieu-n opened this issue Mar 29, 2017 · 0 comments

Comments

@hieu-n
Copy link

hieu-n commented Mar 29, 2017

My packages' version:

Flask (0.12)
Flask-Bootstrap (3.3.7.1)
flask-nav (0.6)

I have a function with multiple routes as below:

from flask_nav.elements import Navbar, View
from flask import Flask
from flask_nav import Nav

nav = Nav()
app = Flask(__name__)
nav.init_app(app)


@app.route('/<profile>/trang-<int:page>/order-<order>-<order_dir>/', )
@app.route('/<profile>/', defaults={'page': 1, 'order': 'sequence', 'order_dir': 'asc'}, )
def index(profile, page, order, order_dir):
    ...


@nav.navigation()
def mk_navbar():
    ...

    return Navbar(
        ...
        View(u'Home', 'index', profile=pf),
        ...
    )

When I tried to access http://localhost:5000/kkm/trang-1/order-list_price-asc/, I got the exception as below:

Traceback (most recent call last):
...
  File "/miniconda2/envs/flecom/lib/python2.7/site-packages/flask_nav/elements.py", line 24, in render
    self))
  File "/miniconda2/envs/flecom/lib/python2.7/site-packages/visitor/__init__.py", line 48, in visit
    return meth(node)
  File "/miniconda2/envs/flecom/lib/python2.7/site-packages/flask_bootstrap/nav.py", line 53, in visit_Navbar
    bar_list.add(self.visit(item))
  File "/miniconda2/envs/flecom/lib/python2.7/site-packages/visitor/__init__.py", line 48, in visit
    return meth(node)
  File "/miniconda2/envs/flecom/lib/python2.7/site-packages/flask_bootstrap/nav.py", line 99, in visit_View
    if node.active:
  File "/miniconda2/envs/flecom/lib/python2.7/site-packages/flask_nav/elements.py", line 89, in active
    append_unknown=not self.ignore_query)
  File "/miniconda2/envs/flecom/lib/python2.7/site-packages/werkzeug/routing.py", line 806, in build
    add(self._converters[data].to_url(values[data]))
KeyError: 'page'

As I tried to debug, I find the problem may lie in active method in flask_nav/elements.py (line 89):

    @property
    def active(self):
        if not request.endpoint == self.endpoint:
            return False

        # rebuild the url and compare results. we can't rely on using get_url()
        # because whether or not an external url is created depends on factors
        # outside our control

        _, url = request.url_rule.build(self.url_for_kwargs,
                                        append_unknown=not self.ignore_query)

        if self.ignore_query:
            return url == request.path

        # take query string into account.
        # FIXME: ensure that the order of query parameters is consistent
        return url == request.full_path

I set a breakpoint at _, url = request.url_rule.build(self.url_for_kwargs, and inspected some variables:

>>>  request.endpoint
'index'
>>> self.endpoint
'index'
>>> request.url_rule
'<Rule \\'/<profile>/trang-<page>/order-<order>-<order_dir>/\\' (HEAD, OPTIONS, GET) -> index>'       
>>> self.url_for_kwargs
{'profile': u'kkm'}

So the rule requires profile, page, order and order_dir. But url_for_kwargs only has profile.
If I change:

        _, url = request.url_rule.build(self.url_for_kwargs,
                                        append_unknown=not self.ignore_query)

to:

       url = url_for(request.endpoint, **self.url_for_kwargs, )

It would work:

>>> url = url_for(request.endpoint, **self.url_for_kwargs)
>>> url
'/kkm/'

That resolved the issue for me. However, I do not know if that would break something else.

Regards,
Hieu

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant