2

我在 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 。

谁能教我应该如何处理这种情况?我应该考虑对我的模型进行非规范化吗?如果您告诉我您是如何使用它的,我们将不胜感激。

谢谢,哟

4

2 回答 2

1

这是因为引用属性中发生的 RPC 调用的数量。您应该预取引用属性以克服 RPC 开销。我不确定如何在 django-nonrel 中预取引用属性。看看尼克的这个博客。这解释了如何克服 appengine 中的引用属性 RPC 开销。在 django-nonrel 你应该自己弄清楚。

于 2011-05-24T12:11:43.163 回答
1

正如 Abdul 所说,我一直在努力在 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, prop, ref_entities[ref_id])
    return entities   

#Usage
books = Book.objects.filter(...)
prefetch_refprop(books, 'author_id', 'author', getattr(Author.objects, 'filter'))

谢谢大家。

于 2011-05-30T10:04:23.707 回答