Что является хорошим способом получения ссылочного объекта для каждого элемента списка из хранилища данных в Django в Google App Engine - PullRequest
2 голосов
/ 24 мая 2011

Я использую Django-nonrel в Google App Engine и имею следующие модели (они упрощены).

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>

Я вижу кучу datastore.get в AppStats из-за book.author.name.Я думал, что должен использовать select_related (), когда я запрашиваю книги, но, очевидно, django nonrel не поддерживает, так как в Google App Engine нет JOIN.

Может ли кто-нибудь научить меня, как мне поступать с таким сценарием?Должен ли я рассмотреть вопрос о денормализации моих моделей?Буду признателен, если вы скажете мне, как вы работаете с ним.

Спасибо, Ю

Ответы [ 2 ]

1 голос
/ 30 мая 2011

Я изо всех сил пытался найти способ get_value_from_datastore в Джанго-Нонрел, как сказал Абдул в течение нескольких дней. Но не повезло. Поэтому я наконец спросил @wkornewald в Твиттере, а потом он указал мне использовать model.<foreignkey>_id.

Теперь я перенес решение Ника на Джанго-нонреля. Я относительно новичок в 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'))

Спасибо всем.
Yoo

1 голос
/ 24 мая 2011

Это происходит из-за количества вызовов RPC, происходящих в ссылочном свойстве.Вы должны предварительно выбрать эталонное свойство, чтобы преодолеть издержки RPC.Я не уверен, как сделать предварительную выборку ссылочного свойства в django-nonrel.Взгляните на этот блог от Ника.Это объясняет, как преодолеть издержки RPC ссылочного свойства в appengine.В django-nonrel вы должны понять это сами.

...