Django中Elasticsearch多对多字段索引报错求助
解决Django多对多字段的Elasticsearch索引问题
咱们先拆解下你遇到的两个错误的根源:
- 第一个错误:
self.product是多对多字段的管理器对象(ManyRelatedManager),它代表的是一组关联的Product实例,不是单个对象,所以直接访问.product_name肯定会报错——管理器本身没有这个属性。 - 第二个错误:你误用了
product_set,这个属性是Django在未指定related_name时,为反向关联自动生成的。但你在ProductKeyword的product字段里已经设置了related_name="products",而且这里我们是正向获取关联的Product,根本不需要用product_set,直接调用self.product.all()就能拿到所有关联的Product对象。
正确的实现方式
我们需要把多对多关联的所有Product的名称提取成一个列表,存入Elasticsearch索引,具体修改后的代码如下:
def search_indexing(self): # 用列表推导式提取所有关联产品的名称 product_names = [p.product_name for p in self.product.all()] obj = ProductKeyWordIndex( meta={'id': self.id}, name=self.name, product=product_names, # 传入产品名称列表 date_created=self.date_created, date_updated=self.date_updated, ) obj.save() return obj.to_dict(include_meta=True)
额外注意事项
还要确保你的ProductKeyWordIndex类中,product字段的类型支持数组存储(对应Elasticsearch的多值字段)。如果你使用的是django-elasticsearch-dsl,可以这样定义索引类:
from django_elasticsearch_dsl import Document, fields from django_elasticsearch_dsl.registries import registry from .models import ProductKeyword @registry.register_document class ProductKeyWordIndex(Document): # 定义product为支持多值的文本字段 product = fields.TextField(multi=True) class Index: name = 'product_keywords' settings = { 'number_of_shards': 1, 'number_of_replicas': 0 } class Django: model = ProductKeyword fields = [ 'name', 'date_created', 'date_updated', ]
这样修改后,创建ProductKeyword对象时,就能把所有关联的产品名称正确存入Elasticsearch索引,不会再抛出AttributeError。
内容的提问来源于stack exchange,提问作者Md. Tanvir Raihan
相关产品推荐
相关产品推荐

