在Django中检索与OneToOne相关的QuerySet

时间:2013-07-29 21:07:39

标签: django postgresql full-text-search django-queryset

背景:

我正在使用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。

我的问题:

什么是可能的“最佳实践”方法来检索与返回的书签的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".

1 个答案:

答案 0 :(得分:2)

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

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

但是当在djorm-ext-pgfulltext中使用此查询时,它会生成“对表的FROM子句条目的无效引用...”错误。根据{{​​3}},这很可能是由djorm-ext-pgfulltext不支持别名重新标记引起的 - 特别是在djorm-ext-pgfulltext中定义的搜索方法中使用extra()。以下语句将强制执行两个单独的查询以避免错误:

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