自定义金字塔FormAlchemy表单
我在使用pyramid_formalchemy创建自定义表单时遇到了一些问题。我怀疑这个包可能有bug,想确认一下我是不是哪里搞错了。我的设置大致是这样的:
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()
如果我把上面那两个类注释掉,formalchemy就能正常工作。我可以查看用户信息,也可以编辑它们。
但是一旦我把这两个类放进去,就会出现问题。问题在于pyramid_formalchemy会从模块的命名空间中抓取UserGrid和UserFieldSet,然后试图把它们当作已经实例化的类来使用。这就导致了错误。另一方面,如果pyramid_formalchemy找不到这些类,它会动态创建这些类并实例化它们。我认为出问题的代码在pyramid_formalchemy/views.py的第236行,从get_grid()函数开始:
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令牌,所以我需要自定义我的表单,以便从会话中获取这些令牌。
谢谢。
1 个回答
pyramid_formalchemy 对你如何设置表单文件有一些基本的假设,这些假设大多没有详细说明。以下是我遇到的一些问题和解决方法……
比如说,如果你有一个叫 User 的模型,那么你需要有一个叫 UserFieldSet 的字段集。
UserFieldSet 必须是一个实例,而不是一个类。
在导入时要小心,否则会破坏 pyramid_formalchemy 的一些假设。如果你有一个模型类 User,应该导入 User 的包,而不是直接导入 User 类本身。然后在引用这个类时,要在前面加上包的名字。
下面是一个使用以上三点的工作示例。
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 组 发帖获取更多信息。