在模板中将外键反向到 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|pprintfoo.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 可搜索模型的主要内容,如果未能解决你的问题,请参考以下文章

模板中的 Django 外键

如何在sequelize中将外键引用到另一个外键?

Python:如何在我的 Django 模板中传递外键的值?

在 SQLite 中将 SQL 数据插入到链接(外键)表中

在 laravel 中将数据从外键添加到数据库中

对于所有外键,如何在 SQL 中将数据类型从 32 位整数升级到 64 位整数?