9

私はFlaskにかなり慣れていません。ブループリントを使用してコードを分割し、Flask-Assets を使用してアセット リンクを提供しようとしています。しかし、何らかの理由で、Flask-Assets をブループリント内で動作させることができません。

コード構造:

/modules
    /base
        __init__.py
    __init__.py
/static
    # ... stuff
/templates
    /layout.html

/modules/base/__init__.py 内:

from flask import Blueprint, render_template, request
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.assets import Environment, Bundle
from flask import current_app as app

default = Blueprint('base', __name__)

assets = Environment(app)

css = Bundle('css/bootstrap.min.css')
assets.register('css_all', css)

js = Bundle('js/jquery-1.7.2.min.js', 'js/bootstrap.min.js')
assets.register('js_all', js)

@default.route('/')
def index():

    return render_template('index/index.html')

そして、基本レイアウトにはこれが含まれています:

{% assets "css_all" %}
    <link rel="stylesheet" href="{{ ASSET_URL }}" />
{% endassets %}
{% assets "js_all" %}
    <script type="text/javascript" src="{{ ASSET_URL }}"></script>
{% endassets %}

実際に /modules/base/__init__.py にあるものは、「RuntimeError: working outside of application context」をスローするため、機能しません。アセット コードをインデックス関数に移動すると機能しますが、アセットを追加するたびにそのコードを繰り返さなければならないのは奇妙に思えます。これを行うより良い方法はありますか?何か不足していますか?

編集: codecool のコメントごとに /modules/base/__init__.py を更新しましたが、「TemplateSyntaxError: 不明なタグ 'assets' に遭遇しました」というエラーがスローされるようになりました。これは、アセット オブジェクトがアプリに渡されていないためだと思います。

編集 2: SQLAlchemy がどのように動作するかからいくつかのアドバイスを受けて、次のように動作するようになりました。

私のメイン __init__.py では:

from flask import Flask
from modules.base import default, assets as base_assets
from flask.ext.assets import Environment, Bundle

app = Flask(__name__) 
app.register_blueprint(default)

base_assets.init_app(app)

base/__init__.py 内: フラスコからブループリントをインポート、render_template、flask.ext.assets からリクエストをインポート、環境をインポート、フラスコからバンドルを app として current_app をインポート

default = Blueprint('base', __name__)

assets = Environment(app)

css = Bundle('css/bootstrap2.min.css')
assets.register('css_all', css)

js = Bundle('js/jquery-1.7.2.min.js', 'js/bootstrap.min.js')
assets.register('js_all', js)

ここでのコツは、ブループリントでアセットを作成し、ベースの init にインポートしてから、そこで .init_app を呼び出すことです。ただし、これがうまくいかないのは、これを行う 2 つの設計図があることです。最後に呼び出されたものが常に勝ちます。たぶん、これをいくつかの共通モジュールまたは何かに引き出すことが可能になるでしょう..

4

2 に答える 2

7

_get_current_objectメソッドを呼び出す必要はありcurrent_appません。そのため、エラーが発生しています。current_app実際にはアプリのプロキシです。コードは次のようになります。

    app = current_app
    assets = Environment(app)

実際、変数として割り当てる必要はありません。これを行う:

     from flask import current_app as app

     assets = Environment(app)

_get_current_objectはリクエストが行われているときにのみ利用できるため、RuntimeError を取得しています。それ以外の場合は、 を使用する必要がありますcurrent_app。ビュー内のコードを初期化するアセットを移動するindexと、リクエスト内にあるように機能し始めました。

_get_current_objectの使用法は Flask のシグナル機能にあり、ここでそれについて読むことができますhttp://flask.pocoo.org/docs/signals/#sending-signals

編集:

これは、Flask アセットを初期化するのに適切な場所ではないために発生しています。modules/__init__.pyアプリの作成時にjinja環境を設定する場所で初期化する必要があります。blueprints コードは、アクセスされたときにのみ実行されることに注意してください。すべてのグローバル初期化は、アプリが定義されているモジュール、つまり次のコードが存在するモジュールで実行する必要があります。

    app = Flask(__name__)
    assets = Environment(app)
于 2012-07-09T05:36:21.110 に答える