我在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。
有人能教我如何处理这种情况吗?我应该考虑对模型进行非规范化吗?如果你告诉我你如何使用它,将不胜感激。
谢谢, 柳
答案 0 :(得分:1)
这是因为引用属性中发生的RPC调用次数。您应该预取引用属性以克服RPC开销。我不知道如何在django-nonrel中预取引用属性。尼克看看这个blog。这解释了如何克服appengine中的引用属性RPC开销。在django-nonrel你应该自己想一想。
答案 1 :(得分:1)
我很难在Django-Nonrel中找到get_value_from_datastore的方法,因为Abdul说了几天。但没有运气。所以我终于在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'))
谢谢大家 柳