是否可以在Djangos SearchVectorField中保留连接字段?

时间:2017-08-24 14:06:51

标签: django postgresql full-text-search

是否可以使用Djangos SearchVectorField保持连接字段以进行全文搜索?

例如:

class P(models.Model):
    brand = models.ForeignKey(Brand, on_delete=models.CASCADE)
    search_vector = SearchVectorField(null=True, blank=True)

代码:

p = P.objects.get(id=1)
p.search_vector = SearchVector('brand__name')
p.save()

提出了这个例外:

FieldError: Joined field references are not permitted in this query

如果不可能,您如何提高已加入注释查询的性能?

1 个答案:

答案 0 :(得分:2)

我找到了解决问题的方法:

p = P.objects.annotate(brand_name=SearchVector('brand__name')).get(id=1)
p.search_vector = p.brand_name
p.save()

更新2018-06-29

官方documentation报道:

  

如果您只是更新记录而不需要对模型对象执行任何操作,最有效的方法是调用update(),而不是将模型对象加载到内存中。

     

使用update()还可以防止在加载对象和调用save()之间的短时间内数据库中可能发生某些变化的竞争条件。

     

最后,意识到update()在SQL级别进行更新,因此不会在模型上调用任何save()方法,也不会发出pre_save或post_save信号(这是调用Model的结果) .save())。

因此,在这种情况下,您可以使用此查询在数据库上执行单个SQL查询:

from django.contrib.postgres.search import SearchVector
from django.db.models import F

P.objects.annotate(
    brand_name=SearchVector('brand__name')
).filter(
    id=1
).update(
    search_vector=F('brand_name')
)