2

pyramid_formalchemy でのカスタム フォームの作成に問題があります。パッケージにバグがあると思われるので、何も不足していないことを確認したかったのです。私のセットアップは次のようになります。

def includeme(config):
    config.include('pyramid_formalchemy')
    # Adding the jquery libraries
    config.include('fa.jquery')
    # Adding the package specific routes
    config.include('myapp.web.formalchemy.faroutes')

    config.formalchemy_admin('admin',
                             models=[User],
                             forms=faforms,
                             session_factory=session,
                             view='fa.jquery.pyramid.ModelView',
                             factory='myapp.model.RootFactory')

    config.formalchemy_model('user',
                             model='myapp.model.user.User',
                             session_factory=session,
                             view='fa.jquery.pyramid.ModelView',
                             factory='myapp.model.RootFactory')

faforms は、カスタム フォームを含むモジュールです。

from myapp.model.user import User

from formalchemy import FieldSet
from formalchemy import Grid

class UserFieldSet(FieldSet):
    def __init__(self):
        FieldSet.__init__(self, User)
        self.configure()

class UserGrid(Grid):
    def __init__(self):
        Grid.__init__(self, User)
        self.configure()

上記の 2 つのクラスをコメントアウトすると、formalchemy は正常に機能します。ユーザーを表示して編集できます。

2 つのクラスを入れると、問題が発生します。問題は、pyramid_formalchemy がモジュールの名前空間から UserGrid と UserFieldSet を取得し、それらをインスタンス化されたクラスであるかのように使用しようとすることです。これは物事を壊します。一方、pyramid_formalchemy がクラスを見つけられない場合、動的にクラスを作成し、それらをインスタンス化します。問題のコードは、pyramid_formalchemy/views.py の get_grid() 関数で始まる 236 行目にあると思います。

def get_grid(self):
    """return a Grid object"""
    request = self.request
    model_name = request.model_name
    form_name = '%sGrid' % model_name
    if hasattr(request.forms, form_name):
        g = getattr(request.forms, form_name)  <-- g is a class type not an
        g.engine = g.engine or self.engine     <-- instance!
        g.readonly = True                      <-- why is it not instantiated?
        g._request = self.request
        self.update_grid(g)
        return g
    model = self.context.get_model()           <-- UserGrid not found in faforms 
    grid = self.grid_class(model)              <-- module.
    grid.engine = self.engine                  <-- so a Grid is instantiated
    if not isinstance(request.forms, list):
        # add default grid to form module eg: caching
        setattr(request.forms, form_name, grid)
    grid = grid.copy()
    grid._request = self.request
    self.update_grid(grid)
    return grid

ここで、一致するグリッド (またはフィールドセット) が見つからない場合はインスタンス化されますが、見つかった場合はクラス タイプが直接使用されますが、実際にはインスタンス化されません。

ここで何か考えはありますか?何か間違った設定をしていますか?

基本的には CSRF トークンを使用しているため、フォームをカスタマイズしてセッションからトークンを取得する必要があります。

ありがとう。

4

1 に答える 1

5

pyramid_formalchemy は、フォーム ファイルのセットアップ方法について、ほとんど文書化されていない特定の仮定を行います。これが私がヒットして回避した落とし穴です...

  1. たとえば、モデル User がある場合、UserFieldSet という FieldSet が必要になります。

  2. UserFieldSet は、クラスではなくインスタンスである必要があります。

  3. インポートには注意してください。そうしないと、pyramid_formalchemy が作成している仮定が破られます。モデル クラス User がある場合は、User のパッケージをインポートしますが、User クラス自体はインポートしません。次に、参照の前にパッケージ名を付けて、クラスを参照します。

以下は、上記の 3 つのポイントを使用した実際の例です。

from myapp.model import user

from formalchemy import Field
from formalchemy import FieldSet
from formalchemy import Grid

UserFieldSet = FieldSet(user.User)
UserFieldSet.configure()

UserGrid = Grid(user.User)
UserGrid.configure()

詳細については、 formalchemy グループに投稿することもできます。

于 2011-11-03T03:08:12.287 に答える