【问题标题】:App Engine db.model reference questionApp Engine db.model 参考问题
【发布时间】:2009-07-06 18:57:05
【问题描述】:

如何从我的任务模型中获取标签数据?

class Task(db.Model):
  title = db.StringProperty()

class Label(db.Model):
  name = db.StringProperty()

class Tasklabel(db.Model):
  task = db.ReferenceProperty(Task)
  label = db.ReferenceProperty(Label)

创建关联没有问题,但我怎样才能获得与以下任务关联的标签:

task = Task.get('...')
for label in task.labels

【问题讨论】:

    标签: python google-app-engine


    【解决方案1】:

    这适用于您当前的数据模型:

    taskObject = db.Query(Task).get()
    for item in taskObject.tasklabel_set:
            item.label.name
    

    或者您可以删除 Label 类并在 Task 和 TaskLabel 之间建立一对多的关系:

    class Task(db.Model):
            title = db.StringProperty()
    
    class TaskLabel(db.Model):
            task = db.ReferenceProperty(Task)
            label = db.StringProperty()
    

    然后

    taskObject = db.Query(Task).get()
    for item in taskObject.tasklabel_set:
            item.label
    

    这是 Google 文章中关于在数据存储中建模关系的提示

    通过将其定义为 ReferenceProperty,您创建了一个只能分配“任务”类型值的属性。每次定义引用属性时,它都会在引用的类上创建一个隐式集合属性。默认情况下,此集合称为 _set。在这种情况下,它将创建一个属性 Task.tasklabel_set。

    文章可以在here找到。

    我还建议在开发应用服务器的交互式控制台中使用此代码。

    【讨论】:

    • 我怎样才能“在开发应用服务器的交互式控制台中玩弄这段代码”? Django 有一个,但我还没有为 GAE 找到一个。
    • 当您在本地机器上运行 dev_appserver 时,您可以转到localhost:8080/_ah/admin/interactive 并在那里测试代码的 sn-ps。您必须提供通常的导入语句才能使您的代码正常工作。输入您的代码并点击底部的“运行程序”。
    • 这回答了你的问题吗?
    【解决方案2】:

    您不想在这样的任务上使用ListProperty 来执行多对多吗?

    class Label(db.Model)
       name = db.StringProperty()
    
       @property
       def members(self):
          return Task.gql("WHERE labels = :1", self.key())
    
    class Task(db.Model)
       title = db.StringProperty();
       labels = db.ListProperty(db.Key)
    

    那你就可以了

    foo_label = Label.gql("WHERE name = 'foo'").get()
    task1 = Task.gql("WHERE title = 'task 1'").get()
    if foo_label.key() not in task1.labels:
      task1.labels.append(foo_label.key())
    task1.put()
    

    Google code 上有一篇关于建模实体关系的详尽文章。我从这篇文章中窃取了上面的代码。

    【讨论】:

    • 这可能是解决方案,我想我可以不用
    • 介意我问为什么吗? appengine 数据存储区似乎可以很容易地取消在 RDBMS 中常见的连接表(如 TaskLabel)。
    • 我看到使用 listproperty 可能是正确的解决方案
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-08
    • 2011-05-06
    • 1970-01-01
    相关资源
    最近更新 更多