1

私が実装しようとしている次のユースケースを考えてみましょう。私はFlask、Flask-SQLAlchemyを使用してユーザーデータをSQLite dbに保存し、Flask-Adminをそのファイル管理機能に使用しています。

フローは次のようになります。ユーザーがログインすると、管理モジュールのインデックス ビューに移動します。しかし、彼がログインすると、FileAdmin クラスが初期化されるときに使用されるパスに彼のユーザー名が追加されます。これは、ユーザーが登録するときに単純なシェル コマンドによって作成されるユーザー ディレクトリを持つことを目的としています。したがって、Flask で定義されたルート パスが「/files/」で、ユーザー名が「rudimk」の場合、ファイル管理者を初期化するときに使用するパスは「/files/rudimk」にする必要があります。

問題は、アプリの起動時に、セッションがなく、ユーザーがログインしていないことです。ただし、ファイル admin はデフォルト パス (この場合は "/files/") で初期化されます。ユーザーがログインした場合、ファイル管理クラスは要求コンテキストの外にあるため、再初期化する方法はありません。フラスコ管理ドキュメントから get_base_path() を見ましたが、ここでどのように役立つかわかりませんでした。

とても有難い。ありがとう!

編集 - 私が作業していたいくつかのコードを追加しました。ここでは、認証を削除し、セッションにユーザー名を追加して認証済みセッションをシミュレートしたことに注意してください。

import os
import os.path as op

from flask import Flask, session

from flask.ext import admin
from flask.ext.admin.contrib import fileadmin


# Create flask app
app = Flask(__name__, template_folder='templates', static_folder='files')

# Create dummy secrey key so we can use flash
app.config['SECRET_KEY'] = '123456790'


# Flask views
@app.route('/')
def index():
    # Simulating a logged-in user by storing his/her username in the session.
    session["username"]
    return '<a href="/admin/">Click me to get to Admin!</a>'


if __name__ == '__main__':
    # Create directory
    username = session["username"]
    path = op.join(op.dirname(__file__), 'files/%s' %username)
    try:
        os.mkdir(path)
    except OSError:
        pass

    # Create admin interface
    admin = admin.Admin(app)
    admin.add_view(fileadmin.FileAdmin(path, '/files/%s' %username, name='Files'))

    # Start app
    app.run(debug=True)
4

1 に答える 1

4

get_base_pathメソッドは、何をする必要があるかを明確に示しています

動作をカスタマイズするためのオーバーライド (ユーザーごとのディレクトリなど)

だから、それがあなたがする必要があることです。get_base_path()FileAdmin から継承し、メソッドをオーバーライドし、基本 FileAdmin ではなくそのクラスを使用するクラスを作成する必要があります。メソッドの「オーバーライド」に慣れていない場合は、Python オブジェクト指向のチュートリアルを探す必要があります。

作成するこの新しいクラスは、get_base_path()ユーザーごとになるようにメソッドをオーバーライドする必要があります。だから、何か...

class MyFileAdmin(FileAdmin):
    def get_base_path(self):
        path = FileAdmin.get_base_path(self)

        if not current_user.is_anonymous():
            return os.path.join(path, current_user.custom_path)
        else:
            return path

MyFileAdminの代わりに使用するようになりましたFileAdmin。私はこのコードをテストしていませんが、うまくいけば、これで正しい軌道に乗ることができます。

実際の FileAdmin インスタンスのパスを変更するという当初の計画は機能しないことに注意してください。FileAdmin のインスタンスを 1 つ作成すると、すべてのユーザーの要求が同じビューを使用してルーティングされます。これを行おうとすると、マルチスレッドの問題が発生する可能性があります。

于 2013-10-15T20:42:31.693 に答える