草庐IT

python/Flask:带有动态第一个组件的路由

codeneng 2023-03-28 原文

python/Flask: Route with dynamic first component

我正在编写一个 Flask 站点,我希望有这样的路由:

1
2
3
4
5
@app.route('/')
@app.route('/<page_id>')
@app.route('/<page_id>/<subpage_id>')
def page(page_id=None, subpage_id=None):
    ...

虽然这看起来理论上应该可行,但看起来这实际上破坏了位于根 static/ 目录中的静态资源。我认为这样做的原因是我的动态路由实际上匹配 \\'static/style.css\\' 并因此覆盖了静态文件的正常处理程序。

有什么办法可以解决这个问题吗?如果我检测到 page_id==\\'static\\',是否有可以将请求转发到的 \\'static\\' 处理程序?

编辑:这是一个工作示例

1
2
3
@app.route('/<page_id>/<subpage_id>/<subsubpage_id>')
def xxx(page_id=None, subpage_id=None, subsubpage_id=None):
    return 'hello'

如果你现在打开 http://127.0.0.1:5000/static/css/style.css,你应该得到一个 \\'hello\\' 而不是文件。

  • 如果保证这些变量是整数,您可以在路由中指定它,这应该对您有所帮助。否则,我不确定为什么会发生这种情况。
  • 不幸的是,它们不是整数。我刚刚添加了一个示例,如果您将其插入到通常的 Flask Backbone中,那么指向 CSS 的 URL 将不再起作用。
  • 你真的在捕捉 /<page>/<subpage>/<subsubpage> 吗?如果您有一个功能可以做所有事情,那么使用路由有什么意义?
  • 是的。我的数据库中有 Page 对象,当调用该方法时,我会根据 page_id/subpage_id/subsubpage_id 加载和显示这些对象。有一个更好的方法吗?我正在考虑在应用程序初始化时为每个页面添加单独的路由,但我找不到与 url_for 结合使用的好方法。


关于问题的根源:

Yes. I have Page objects in my database, which I load and display based on the page_id/subpage_id/subsubpage_id when the method is called. Is there a better way to do this? I was thinking of adding separate routes for each of the pages when the app is initialized, but I could not find a good way of making that work in conjunction with url_for.

您可以使用 app.add_url_rule 直接注册路由处理程序。默认情况下,它会为 url_for 使用函数的名称,是的,但是您可以通过传递 endpoint 参数来覆盖它。

所以也许你会有这样的东西:

1
2
3
4
5
6
7
8
9
10
11
12
from functools import partial

def actual_handler(page):
    return u'hello'

for page in session.query(Page):
    route = u'/{0}/{1}/{2}'.format(page.id1, page.id2, page.id3)
    app.add_url_rule(
        route,
        page.name,  # this is the name used for url_for
        partial(actual_handler, page=page),
    )

获取会话可能会或可能不会很棘手,并且可能会或可能不会涉及手动调用 session.remove() 之类的工作;我之前没有尝试在 Flask 处理程序之外使用 SQLAlchemy。假设您首先使用的是 SQLA。

另请参阅有关路由处理的文档。

至于原来路由优先于静态文件的问题,我真的不知道;根据我对 Flask 和 Werkzeug 文档的阅读,这不应该发生。如果您仍希望通过手动提供静态文件来解决此问题,也许 send_from_directory 会有所帮助。无论如何,您的 Web 服务器可能会直接在生产环境中提供静态文件,因此上面的元编程垃圾可能不值得。

PS:事后诸葛亮;如果您的整个站点都位于数据库中,那么 Pyramid 的遍历可能更合适。它一次动态地检查一个路径组件,而不是拥有一个固定的静态路由列表。

  • 我想我得到了这个工作,谢谢!我不明白为什么我需要参加会议。为什么我不能只执行 db = SQLAlchemy(app) 然后执行 for page in Page.query.all(): ...
  • 你没有,真的; Page.querysession.query(Page) 的快捷方式。我只是喜欢尽可能多地使用普通 SQLA 方法;对我来说,表可以查询自己没有意义:)


这是一个可怕的 hack,但你可能只是做一些类似于:

1
2
3
4
5
@app.route('/<page_id>/<subpage_id>/<subsubpage_id>')
def xxx(page_id=None, subpage_id=None, subsubpage_id=None):
    if page_id == 'static':  # or whatever the path is to your assets
       # make a response where you've filled the request yourself
    return 'hello'

  • 是的,正如我在原始帖子中提到的,如果我知道静态资源请求的默认处理程序是什么,我可以这样做,这样我就可以正确地转发请求。你知道吗?

有关python/Flask:带有动态第一个组件的路由的更多相关文章

  1. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  2. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  3. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  4. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  5. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  6. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  7. ruby - 为什么 SecureRandom.uuid 创建一个唯一的字符串? - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?

  8. ruby-on-rails - Rails - 从另一个模型中创建一个模型的实例 - 2

    我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案

  9. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  10. ruby - 一个 YAML 对象可以引用另一个吗? - 2

    我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的ruby​​yaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir

随机推荐