SQLAlchemy / WTForms - QuerySelectField

SQLAlchemy / WTForms - QuerySelectField

我在 Pyramid 应用程序上使用带有 SQLAlchemy 扩展的 WTForms。

我的会话是:

from zope.sqlalchemy import ZopeTransactionExtension

DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
Base = declarative_base()

我的模型是:

class Client(Base):
    __tablename__ = 'client'
    id = Column(Integer, primary_key=True, nullable=False)
    name = Column(Unicode(48))
    street = Column(Unicode(48))
    city = Column(Unicode(32))
    task = relationship("Task", backref="client")

    @classmethod
    def active(cls):
         return DBSession.query(Client).options(load_only("id", "name")).order_by(sa.desc(Client.name)).filter(Client.status == True)


class Task(Base):
    __tablename__ = 'task'
    id = Column(Integer, primary_key=True, nullable=False)
    name = Column(String(48))
    status = Column(Boolean)
    client_id = Column(Integer, ForeignKey('client.id'))

我的表格是:

def enabled_client():
     return Client.active()

class TaskCreateForm(ModelForm):
    name = TextField('Task name', [validators.Length(min=1, max=48)], filters=[strip_filter])
    status = BooleanField('Status')
    client_id = QuerySelectField('Client', query_factory=enabled_client, get_label='name', allow_blank=False)

我的观点是:

@view_config(route_name='task_action', match_param='action=create', renderer='arx:templates/task_edit.mako', permission='edit')
def task_create(request):
    task = Task()
    form = TaskCreateForm(request.POST)
    if request.method == 'POST' and form.validate():
        form.populate_obj(task)
        DBSession.add(task)
        return HTTPFound(location=request.route_url('home'))
    return {'form':form, 'action':request.matchdict.get('action')}

表单显示带有正确客户名称的 select 框,但是当我尝试提交表单时出现问题。 WTForm 应该使用客户端的真实 ID,但它传递了 SQLAlchemy 对象,例如:

   <arx.models.Client object at 0x7fdfb139ddd0>

我做错了什么?

我的表单太具体了(应该是客户端而不是 client_id),所以我的工作代码是这样的:

会话:

from zope.sqlalchemy import ZopeTransactionExtension

DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
Base = declarative_base()

型号:

class Client(Base):
     __tablename__ = 'client'
     id = Column(Integer, primary_key=True, nullable=False)
     name = Column(Unicode(48))
     street = Column(Unicode(48))
     city = Column(Unicode(32))
     task = relationship("Task", backref="client")

    @classmethod
    def active(cls):
        return DBSession.query(Client).options(load_only("id", "name")).order_by(sa.desc(Client.name)).filter(Client.status == True)


class Task(Base):
    __tablename__ = 'task'
    id = Column(Integer, primary_key=True, nullable=False)
    name = Column(String(48))
    status = Column(Boolean)
    client_id = Column(Integer, ForeignKey('client.id'))

表格:

def enabled_client():
    return Client.active()

class TaskCreateForm(ModelForm):
    name = TextField('Task name', [validators.Length(min=1, max=48)], filters=[strip_filter])
    status = BooleanField('Status')
    client = QuerySelectField('Client', query_factory=enabled_client, get_label='name', allow_blank=False)

查看:

@view_config(route_name='task_action', match_param='action=create', renderer='arx:templates/task_edit.mako', permission='edit')
def task_create(request):
    task = Task()
    form = TaskCreateForm(request.POST)
    if request.method == 'POST' and form.validate():
        form.populate_obj(task)
        DBSession.add(task)
        return HTTPFound(location=request.route_url('home'))
    return {'form':form, 'action':request.matchdict.get('action')}