1

背景:

我正在使用 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 实例进行搜索:

Bookmark.objects.search(query)

它返回一个书签的查询集。

我的问题:

检索与返回的书签的 QuerySet 相关的 OneToOne 的 SharedBookmarks 的一种可能的“最佳实践”方法是什么?我觉得我错过了一些基本的东西......我试着做

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

除了看起来可能令人费解之外,我还收到了一个数据库错误,对表“bookmarks_bookmark”的 FROM 子句条目的引用无效

更新了完整的堆栈跟踪和错误:

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".
4

1 回答 1

2

正如 kathikr 所述,以下嵌套查询可用于检索与返回的书签的 QuerySet 相关的 OneToOne 共享书签。

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

但是当将此查询与 djorm-ext-pgfulltext 一起使用时,它会产生“对表的 FROM 子句条目的无效引用...”错误。根据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)))   
于 2013-07-30T11:57:56.830 回答