首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Deform/Colander HTML Select中处理多到多个关系

在Deform/Colander HTML Select中处理多到多个关系
EN

Stack Overflow用户
提问于 2014-08-19 05:21:56
回答 1查看 857关注 0票数 4

我正在金字塔框架中工作,并使用变形包来呈现给定冒号方案的HTML。我正努力思考如何处理一个包含很多到多个关系的模式。例如,我的sqlalchemy模型如下所示:

代码语言:javascript
复制
class Product(Base):
    """ The SQLAlchemy declarative model class for a Product object. """
    __tablename__ = 'products'

    id = Column(Integer, primary_key=True)
    name = Column(String(80), nullable=False)
    description = Column(String(2000), nullable=False)
    categories = relationship('Category', secondary=product_categories,
                               backref=backref('categories', lazy='dynamic'))


class Category(Base):                                                                                
    """ The SQLAlchemy declarative model class for a Category object. """                            
    __tablename__ = 'categories'

    id = Column(Integer, primary_key=True)                                                                                            
    name = Column(String(80), nullable=False)                                                                                                                                 
    products = relationship('Product', secondary=product_categories,                                 
                               backref=backref('products', lazy='dynamic'))


product_categories = Table('product_categories', Base.metadata,
    Column('products_id', Integer, ForeignKey('products.id')),
    Column('categories_id', Integer, ForeignKey('categories.id'))
)

正如您所看到的,它是一个非常简单的模型,表示一个在线商店,其中一个产品可以属于一个或多个类别。在我呈现的表单中,我希望有一个选择多个字段,在其中我可以选择几个不同的类别来放置产品。下面是一个简单的冒号模式:

代码语言:javascript
复制
def get_category_choices():

    all_categories = DBSession.query(Category).all()

    choices = []
    for category in all_categories:
        choices.append((category.id, category.name))

    return choices


class ProductForm(colander.Schema):
    """ The class which constructs a PropertyForm form for add/edit pages. """

    name = colander.SchemaNode(colander.String(), title = "Name",
                               validator=colander.Length(max=80),
                              )

    description = colander.SchemaNode(colander.String(), title="Description",
                                  validator=colander.Length(max=2000),
                                  widget=deform.widget.TextAreaWidget(rows=10, cols=60),
                                 )

    categories = colander.SchemaNode(
                colander.Set(),
                widget=deform.widget.SelectWidget(values=get_category_choices(), multiple=True),
                validator=colander.Length(min=1),
                )

而且,可以肯定的是,我确实得到了所有字段的正确呈现,然而,类别字段似乎并没有与任何东西“绑定”。如果我编辑一个我知道属于两个类别的产品,我希望select字段已经突出显示了这两个类别。进行更改(选择第三项)应该会导致DB更改,其中product_categories对于给定的product_id有三行,每个行都有一个不同的category_id。它可能是TMI,但我也使用类似于的方法来读取/写入appstruct。

现在,我已经看到了提及 (和再一次)使用映射来处理许多关系字段,如这样的关系字段,但是没有一个关于如何使用它的实例。

事先感谢任何能伸出援手的人。我会很感激的。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-08-21 14:58:30

这一次我在左路,甚至没有问正确的问题。我真正想要的是在一个多选择的冒号SchemaNode中选择一些默认值。我把我的问题带到了塔-讨论谷歌集团,他们能够帮我解决问题。当我在Product中构造appstruct时,它可以归结为使用'set()‘,如下所示:

代码语言:javascript
复制
def appstruct(self):
    """ Returns the appstruct model for use with deform. """

    appstruct = {}
    for k in sorted(self.__dict__):
        if k[:4] == "_sa_":
            continue

        appstruct[k] = self.__dict__[k]

    # Special case for the categories
    appstruct['categories'] = set([str(c.id) for c in self.categories])

    return appstruct

然后,我将它(以及appstruct中的其他项)传递给表单,它正确地呈现了HTML,并选择了所有类别。若要在提交后应用appstruct,代码最后如下所示:

代码语言:javascript
复制
def apply_appstruct(self, appstruct):
    """ Set the product with appstruct from the submitted form. """

    for kw, arg in appstruct.items():

        if kw == "categories":
            categories = []
            for id in arg:
                categories.append(DBSession.query(Category).filter(Category.id == id).first())
            arg = categories

        setattr(self, kw, arg)

冒号模式最后看起来类似于:

代码语言:javascript
复制
def get_category_choices():
    all_categories = DBSession.query(Category).all()
    return [(str(c.id), c.name) for c in all_categories]

categories = get_category_choices()

class ProductForm(colander.Schema):
    """ The class which constructs a ProductForm form for add/edit pages. """

    name = colander.SchemaNode(colander.String(), title = "Name",
                               validator=colander.Length(max=80),
                              )

    description = colander.SchemaNode(colander.String(), title="Description",
                                  validator=colander.Length(max=2000),
                                  widget=deform.widget.TextAreaWidget(rows=10, cols=60),
                                 )

    categories = colander.SchemaNode(
                colander.Set(),
                widget=deform.widget.SelectWidget(
                    values=categories,
                    multiple=True,
                ),
                validator=colander.Length(min=1),
                )

感谢所有寻找的人。对不起,我问错了问题,没有简单地回答。:-)

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25376145

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档