在Flask中使用app.add_url_rule时的默认值

3 投票
2 回答
17745 浏览
提问于 2025-04-17 19:09

我正在设置一个网址接口,代码在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)

然后在我的ContactAPI类里,我重写了get()方法,代码在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

当我访问网址/contact/1时,instid的值显示为None

如果我把manager.py里的defaults={'instid': None},这一行去掉,instid的值就会显示为1。

为什么在我调用add_url_rule时,添加defaults这一行会覆盖我在网址里输入的内容呢?

2 个回答

1

在Flask的文档里,有一个完整的类似示例,可以参考一下 - https://flask.palletsprojects.com/en/1.1.x/views/

4

结果发现,当我使用 defaults 时,我需要注册两个端点。

因为在我的 ContactAPI 视图中,{'instid': None} 被作为一个关键字参数传递给 get(),所以我需要告诉 Flask,当访问 URL /contact 时,把 instid 设置为 None。

当我访问 /contact/1 时,我需要用 <int:instid>。为了做到这一点,我需要在调用 add_url_rule() 时去掉 defaults 这个关键字参数。

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)

相关的 Werkzeug 文档: http://werkzeug.pocoo.org/docs/routing/#werkzeug.routing.Rule

感谢 #flask IRC 频道的 asdf 指出这一点。

撰写回答