我有一个像这样的烧瓶路线:
@app.route('/product/<string:slug>')
def product(slug):
# some codes...
return render_template('product.html', product=product)
不同的客户使用该项目(不同的网站,相同的基础架构)。每个客户都希望产品 URL 不同。喜欢;
asite.com/product-nike-shoe-323
bsite.com/nike-shoe
csite.com/product/nike-shoue
对比对比
如何设置来自数据库的 URL 结构?
喜欢:
url_config = "product-{product_name}-{product_id}"
或
url_config = "product-{product_id}"
注意:请不要重定向。
答案 0 :(得分:2)
当您在这里说“数据库”时,我不是 100% 清楚您指的是什么。根据上下文,我推断您可能在谈论 Flask Config object。如果是这种情况,您只需在 setting up the app configuration 之后立即注册您的视图函数。只需调用 app.add_url_rule()
即可注册配置中的 URL 模式以指向您选择的视图函数。
但是,如果您正在谈论 SQL 或 NoSQL 数据库,并且您已经构建了一个 Web UI 来注册路由,那么不要失望。 Flask 路由可以在任何时候注册到应用程序对象。在 Flask 应用程序生命周期中,您将无法再注册路由!
注册路由所做的只是在 URL 模板和端点名称(一个不透明的字符串)之间创建映射。大多数情况下,您还会注册一个要调用的函数来处理特定端点,而大多数情况下,Flask 会从该函数中推断出端点名称。一旦在映射中注册,任何下一个传入请求都可以路由到给定端点的函数。
因此,Flask 保留了两张地图:
Flask.url_map
Flask.view_functions
也就是说,有用于删除或更改 url注册的API(当然,除了重新启动服务器)。您无法更改 url 路由、给定路由的端点名称或哪个端点映射到哪个函数。该框架的意图是您在第一次启动服务器时尽早注册您的路由,通过在导入或绑定到应用程序时直接运行的代码(蓝图和 Flask 扩展执行后者)。大多数 Flask 应用程序将创建他们的 Flask 实例,注册他们所有的路由和扩展,然后将实例传递给 WSGI 服务器以进行请求调度,就是这样。但是在此之后,实现中没有任何内容阻止您注册更多路由。
如果你想从数据库信息中注册 URL 路由,你至少要注意以下两点:
首先:如果我要实现这样的东西,我会使用一个视图函数。通过分别查看 request.url_rule
和 request.endpoint
,您始终可以找出匹配的 url 规则以及它映射到的端点名称。
接下来,我将从数据库中为每个 url 规则显式生成端点名称。在名称中使用主键;您希望能够从端点名称中找到数据库行,反之亦然。你如何做到这一点取决于你;假设您知道如何执行此操作,并且您有两个名为 pk_from_endpoint()
和 endpoint_from_pk()
的函数。
你的视图函数看起来像这样:
from flask import request
def product_request(**kwargs):
key = pk_from_endpoint(request.endpoint)
row = database_query(key)
# … process request
您为给定的数据库行注册一个路由:
app.add_url_route(row.url_config, endpoint_from_pk(row.id), product_request)
如前所述,您不能更改 URL 注册。但是,只要不经常更改这些 URL,您就可以随时添加新注册,对于任何旧条目,请使用 abort(404)
返回 404 Not Found 响应。
答案 1 :(得分:0)
这在 Flask 的路由系统中是不可能的。网址映射应该在启动时定义,之后不会更改。
但是,如果您有一些需要动态部分的特定路径(例如 /product/WHATEVER
),那么您可以为 /product/<slug>
注册一个路径并在您的视图函数中查询数据库。
也就是说,如果您真的希望在数据库中使用 URL 规则,并且不介意在启动期间连接到您的数据库(通常这很丑陋),那么没有什么可以阻止您在启动时查询数据库并根据以下内容定义 URL 规则来自数据库的数据。相当丑陋,但可行。
示例:
with app.app_context():
url_map = {u.endpoint: u.rule for u in URLRules.query}
@app.route(url_map['foo'])
def foo():
...
当然,除非您在一个地方为所有端点使用 app.add_url_rule()
而不是 @app.route()
装饰器,否则这样做会更难很好地构建您的应用程序。
当然蓝图也是如此。