Получение QuerySet связанного с OneToOne в Django

Задний план:

Я использую расширение djorm-ext-pgfulltext для полнотекстового поиска с использованием Postgres в поле заголовка для одной из моих моделей (закладка).

class Bookmark(TimeStampModel):
 title = models.CharField(max_length = 100)
 # other fields

 search_index = VectorField()

 objects = SearchManager(
 fields = ('title'),
 config = 'pg_catalog.english',
 search_field = 'search_index',
 auto_update_search_field = True
 )

У меня есть еще одна модель под названием SharedBookmark, которая относится к OneToOne, связанной с закладкой.

class SharedBookmark(TimeStampedModel):
 bookmark = models.OneToOneField(Bookmark)
 # other fields

Я могу выполнить поиск через мои закладки, используя:

Bookmark.objects.search(query)

который возвращает QuerySet из закладок.

Мой вопрос:

Каким будет один из возможных "лучших практик" для извлечения SharedBookmarks, которые OneToOne, связанные с QuerySet из Bookmarks, возвращены? Я чувствую, что мне не хватает чего-то фундаментального... Я пытался сделать

bookmarks = Bookmark.objects.search(query).values_list('id', flat=True)
shared_bookmarks = SharedBookmark.objects.filter(bookmark__pk__in=bookmarks)

и, кроме кажущегося, возможно, запутанного, я получил ошибку базы данных, неверную ссылку на запись FROM-clause для таблицы "bookmarks_bookmark",

Обновлено с полной трассировкой стека и ошибкой:

Traceback:
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
 115. response = callback(request, *callback_args, **callback_kwargs)
File "/home/derek/Development/skillfare/skillfare/bookmarks/views.py" in search
 88. return render(request, 'main_page.html', variables)
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/shortcuts/__init__.py" in render
 53. return HttpResponse(loader.render_to_string(*args, **kwargs),
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/template/loader.py" in render_to_string
 177. return t.render(context_instance)
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/template/base.py" in render
 140. return self._render(context)
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/template/base.py" in _render
 134. return self.nodelist.render(context)
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/template/base.py" in render
 830. bit = self.render_node(node, context)
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/template/debug.py" in render_node
 74. return node.render(context)
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/template/loader_tags.py" in render
 124. return compiled_parent._render(context)
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/template/base.py" in _render
 134. return self.nodelist.render(context)
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/template/base.py" in render
 830. bit = self.render_node(node, context)
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/template/debug.py" in render_node
 74. return node.render(context)
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/template/loader_tags.py" in render
 63. result = block.nodelist.render(context)
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/template/base.py" in render
 830. bit = self.render_node(node, context)
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/template/debug.py" in render_node
 74. return node.render(context)
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/template/loader_tags.py" in render
 156. return self.render_template(self.template, context)
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/template/loader_tags.py" in render_template
 138. output = template.render(context)
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/template/base.py" in render
 140. return self._render(context)
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/template/base.py" in _render
 134. return self.nodelist.render(context)
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/template/base.py" in render
 830. bit = self.render_node(node, context)
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/template/debug.py" in render_node
 74. return node.render(context)
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/template/defaulttags.py" in render
 283. if match:
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/db/models/query.py" in __nonzero__
 141. return type(self).__bool__(self)
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/db/models/query.py" in __bool__
 135. next(iter(self))
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/db/models/query.py" in _result_iter
 123. self._fill_cache()
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/db/models/query.py" in _fill_cache
 939. self._result_cache.append(next(self._iter))
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/db/models/query.py" in _safe_iterator
 344. for item in iterator:
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/db/models/query.py" in iterator
 301. for row in compiler.results_iter():
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py" in results_iter
 775. for rows in self.execute_sql(MULTI):
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py" in execute_sql
 840. cursor.execute(sql, params)
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/db/backends/util.py" in execute
 41. return self.cursor.execute(sql, params)
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py" in execute
 58. six.reraise(utils.DatabaseError, utils.DatabaseError(*tuple(e.args)), sys.exc_info()[2])
File "/home/derek/.virtualenvs/skillfare/local/lib/python2.7/site-packages/django/db/backends/postgresql_psycopg2/base.py" in execute
 54. return self.cursor.execute(query, args)

Exception Type: DatabaseError at /search/
Exception Value: invalid reference to FROM-clause entry for table "bookmarks_bookmark"
LINE 1: ...ECT U0."id" FROM "bookmarks_bookmark" U0 WHERE ( ("bookmarks...
 ^
HINT: Perhaps you meant to reference the table alias "u0".
1 ответ

Как указано kathikr, следующий следующий вложенный запрос может быть использован для извлечения SharedBookmark, которые являются OneToOne, связанными с возвратом QuerySet из закладок.

SharedBookmark.objects.filter(bookmark__in=Bookmark.objects.search(query))

Но при использовании этого запроса с djorm-ext-pgfulltext он вызывает ошибку "неверная ссылка на запись FROM-clause для таблицы...". Согласно https://groups.google.com/d/topic/django-users/5PrcxbF38Ag/discussion, это скорее всего вызвано тем, что djorm-ext-pgfulltext не поддерживает повторное присвоение псевдонима - в частности, использование метода extra() в методе поиска определенный в djorm-ext-pgfulltext. Следующий оператор заставит два отдельных запроса избежать ошибки:

SharedBookmark.objects.filter(bookmark__in=list(Bookmark.objects.search(query)))

licensed under cc by-sa 3.0 with attribution.