从Google App Engine的Django中的数据存储区中检索列表中每个项目上的引用对象的好方法是什么

问题描述

| 我在Google App Engine上使用Django-nonrel,并具有以下模型(已简化)。
class Author(models.Model):
    name = models.CharField()

class Book(models.Model):
    author = models.ForeignKey(Author)
    title = models.CharField()
所以,如果我这样查询
books = Book.objects.all()
并将这些书传递到模板中,并按以下方式显示它们,
<ul>
{% for book in books %}
   <li>{{ book.title }}{{ book.author.name }}</li>
{% endfor %}
</ul>
由于book.author.name,我在AppStats看到一堆datastore.get。我以为我在查询图书时应该使用select_related(),但是显然django nonrel不支持,因为Google App Engine上没有JOIN。 谁能教我该如何应对这种情况?我应该考虑对模型进行非规范化吗?如果您告诉我如何使用它,将不胜感激。 谢谢, 柳     

解决方法

发生这种情况是因为引用属性中发生了RPC调用。您应该预取引用属性,以克服RPC开销。我不确定如何在django-nonrel中预取引用属性。看看尼克的这个博客。这说明了如何克服Appengine中的参考属性RPC开销。在django-nonrel中,您应该自己弄清楚它。     ,正如阿卜杜勒说的那样,我努力地在Django-Nonrel中找到一种get_value_from_datastore的方法。但是没有运气。所以我终于在Twitter上问@wkornewald,然后他指出我要使用
model.<foreignkey>_id
。 现在,我将Nick的解决方案移植到Django-nonrel。我对Python来说相对较新,因此这可能不是很好的编码,但是可以按我期望的那样工作。
def prefetch_refprop(entities,prop_id,prop,filter):
    ref_ids = [getattr(x,prop_id) for x in entities]
    ref_entities = dict((x.id,x) for x in filter(id__in=ref_ids))
    for entity,ref_id in zip(entities,ref_ids):
        setattr(entity,ref_entities[ref_id])
    return entities   

#Usage
books = Book.objects.filter(...)
prefetch_refprop(books,\'author_id\',\'author\',getattr(Author.objects,\'filter\'))
感谢大家。 柳     

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...