在模板中将外键反向到 django-fts 可搜索模型
Posted
技术标签:
【中文标题】在模板中将外键反向到 django-fts 可搜索模型【英文标题】:Reverse foreign key to django-fts searchable model in template 【发布时间】:2010-11-11 15:51:44 【问题描述】:我有一对带有外键的 Django 模型,其中一个可以用 django-fts 搜索,比如:
class Foo(models.Model):
...
class Bar(fts.SearchableModel):
foo = models.ForeignKey(Foo)
当我有一个 Foo 实例时,我可以在视图中插入 print foo.bar_set.all()
并看到一组结果。但是,如果我尝试通过以下任何方式在视图中使用它:
foo.bar_set|pprint
foo.bar_set.all|ppring
foo.bar_set.count
foo.bar_set.all|length
% for bar in foo.bar_set.all % bar % endfor %
我能想到的 any 结构的行为就像 foo
实例没有 bar_set
属性一样。
编辑:我确定我在模板中有一个 Foo
实例,我测试了以下内容按预期工作:
foo|pprint
foo.id (and any other simple attributes of Foo)
我确信存在相关的 Bar 对象,因为我从视图 (print foo.bar_set.all()
) 中检查了这一点。如果 QuerySet 为空,foo.bar_set.all|pprint
将产生 []
,而不是 ''
(它在 foo.bar_set.all|pprint
、foo.bar_set|pprint
和任何 foo.nonexistent_attribute|pprint
上执行)。
当我使用 psycopg2 驱动程序将开发从 SQLite 数据库转移到 PostgreSQL 以使用 django-fts 全文搜索时,这种行为就开始了。
我找不到任何其他答案,因为谷歌搜索非常困难:“反向关系”或“反向外键”到处都是不相关的 django.core.urlresolvers.reverse
引用,我不知道如何命名“*_set”谷歌的事情。关于如何用谷歌搜索这个的提示也会有所帮助。
【问题讨论】:
【参考方案1】:感谢Marcin Kaszyński 的帮助,我设法将错误追溯到django-fts BaseManager。 Django-fts 是一个全文搜索引擎,它为可搜索类的管理器添加了.search(query)
方法,我可以写Foo.objects.search("bar")
。 为了方便,它在管理器中增加了__call__
方法,该方法被RelatedManager
(例如bar_set
)继承。
@987654323@
方法中的模板代码看到 bar_set
是可调用的(第 717 行),尝试不带参数调用它(第 722 行),并将变量视为空,因为需要参数(第 724 行-726)。
Removing the __call__ method from django-fts' BaseManager 有帮助。
【讨论】:
【参考方案2】: foo.bar_set.all
绝对可以。你确定你真的有一个 Foo 的实例吗?
【讨论】:
我有一个 Foo 实例(foo|pprint 有效,我仔细检查过),所有简单属性(如 foo.id)都有效。有一个关系,也有相关的 Bar 对象,我通过在渲染模板之前从视图中运行 print foo.bar_set.all() 来测试它们。 我发现了这个,这是与 django-fts 的交互(我知道我没有在问题文本的第一个版本中提到这一点,我不怀疑这是原因)。有关详细说明,请参阅我的答案。【参考方案3】:我建议在渲染页面之前尝试将 foo.bar_set.all 作为字典元素传递给视图函数,看看是否得到相同的结果。
【讨论】:
没有参数的方法由模板语言调用(它也适用于其他方法,如果问题出在方法调用上,foo.bar_set|pprint 将呈现 一些东西)。这记录在docs.djangoproject.com/en/1.0/topics/templates/#variables,并在与此相关的第一个问题中描述,***.com/questions/1014591/… 是的,我已经使用它作为解决方法,直到找到问题的解决方案(因为准备好的结果集只是另一个模板参数)。我对您的回答投了反对票,因为这是一个错误信息(关于无法调用方法),但我看到您对其进行了编辑,所以我收回了反对票。 谢谢你,我正试图弄清楚为什么这对你自己不起作用。事实是我从来没有让 .object_set.all 在模板中工作。同样的问题。 你确定 foo 不是从 bar 传递过来的吗?例如,您确定 foo 来自: foo = Foo.objects.get() 与您的 bar 模型中的 foo 吗?这可能会导致问题。 不,这不是原因。我找到了原因,在我编写完代码后,我将发布完整的答案,因为它并不明显(它实际上来自 django-fts,这是将开发切换到 Postgres 的主要原因)。以上是关于在模板中将外键反向到 django-fts 可搜索模型的主要内容,如果未能解决你的问题,请参考以下文章