Using defaults with app.add_url_rule in Flask
Solution 1
It turns out I need to register two endpoints when using defaults
.
Because {'instid': None}
is passed into get()
in my ContactAPI view as a kwarg, I need to tell Flask to set instid
to None when the URL /contact
is hit.
When I hit /contact/1
, I need to use <int:instid>
. To do this, I need to remove the defaults
kwarg in my call to add_url_rule()
.
manager.py
from xxx import ContactAPI
from xxx.models import Contact
# self.app is my Flask app
# self.session is SQLAlchemy Session
api_name = 'contact'
instance_endpoint = '/%s/<int:instid>' % api_name
collection_endpoint = '/%s' % api_name
methods = ['GET']
api_view = ContactAPI.as_view(api_name, self.session,
Contact, app)
self.app.add_url_rule(instance_endpoint, methods=methods,
view_func=api_view)
self.app.add_url_rule(collection_endpoint, methods=methods,
defaults={'instid': None},
view_func=api_view)
Relevant Werkzeug docs: http://werkzeug.pocoo.org/docs/routing/#werkzeug.routing.Rule
Thanks to asdf
in the #flask IRC channel for pointing this out.
Solution 2
A complete example of a similar thing is there in the flask docs - https://flask.palletsprojects.com/en/1.1.x/views/
Related videos on Youtube
Chris McKinnel
Bridging the gap between business and tech humans.
Updated on June 04, 2022Comments
-
Chris McKinnel over 1 year
I am setting a url endpoint with the following:
manager.py
from xxx import ContactAPI from xxx.models import Contact # self.app is my Flask app # self.session is SQLAlchemy Session api_name = 'contact' instance_endpoint = '/%s/<int:instid>' % api_name methods = ['GET'] api_view = ContactAPI.as_view(api_name, self.session, Contact, app) self.app.add_url_rule(instance_endpoint, methods=methods, defaults={'instid': None}, view_func=api_view)
And overriding
get()
in my ContactAPI class:views.py
from flask.views import MethodView class ContactAPI(MethodView): def __init__(self, session, model, app, *args, **kwargs): super(ContactAPI, self).__init__(*args, **kwargs) def get(self, instid): print instid
When I hit the URL
/contact/1
I getinstid
printed asNone
.When I remove the
defaults={'instid': None},
line from manager.py, I getinstid
printed as 1.Why is having the defaults line in my call to
add_url_rule
overriding what I'm putting in my URL?