1

好的,问题就在这里。我有这个代码

list_categories = [None,"mathematics","engineering","science","other"]
class Books(db.Model)
    title = db.StringProperty(required=True)
    author = db.StringProperty()
    isbn = db.StringProperty()
    categories = db.StringListProperty(default=None, choices = set(list_categories))

我在这里要做的是让我的 book.categories 成为列表类别的子集,例如我有一本书的类别应该是“工程”和“数学”,但是当我设置

book.categories = ['engineering','mathematics']

它 webapp2 给了我一个错误

BadValueError: Property categories is ['engineering','mathematics']; must be one of set([None,"mathematics","engineering","science","other"])

我最初的猜测是我必须将我的 list_choices 设置为 [None,"mathematics","engineering","science","other"] 的 POWERSET,但这太低效了。

有谁知道这个的解决方法?

4

2 回答 2

2

错误的原因(我相信你已经猜到了)是它StringListProperty没有对choices关键字参数进行任何特殊处理 - 它只是将它传递给ListProperty构造函数,然后将它传递给Property构造函数,它在哪里评价:

if self.empty(value):
    if self.required:
        raise BadValueError('Property %s is required' % self.name)
    else:
      if self.choices:
        match = False
        for choice in self.choices:
          if choice == value:
            match = True
        if not match:
          raise BadValueError('Property %s is %r; must be one of %r' %
                              (self.name, value, self.choices))

问题是它单独遍历每个choice,但它会将它与您的整个列表(value)进行比较,这永远不会导致匹配,因为字符串不等于列表(再次,您知道这一点:))。

我的建议是修改您将列表分配给属性的方式。例如,而不是:

book.categories = ['engineering','mathematics']

尝试这样的事情:

for category in ['engineering','mathematics']:
    book.categories.append(category)

由于ListProperty包含一个列表,您可以单独附加每个项目,以便它通过上述代码中的测试。请注意,为了让它在我的测试中工作,我必须以稍微不同的方式设置模型 - 但是,如果您可以解决上面提到的错误,那么该append方法应该可以正常工作。

我同意,这让它变得不那么简单了,但它应该绕过上面的问题并希望能奏效。

于 2012-11-28T03:33:00.093 回答
0

Create a many to many relationship using list of keys. Use the categories property in class Book as a list of keys of class Category.

class Book(db.Model)
    title = db.StringProperty(required=True)
    author = db.StringProperty()
    isbn = db.StringProperty()

    # List Of Keys
    categories = db.ListProperty(db.Key)

class Category(db.Model)
    name = db.StringProperty(choices = ('science', 'engineering', 'math'))

For more info and code samples about modeling check out: https://developers.google.com/appengine/articles/modeling

于 2012-11-28T04:07:30.257 回答