【问题标题】:Django elasticsearch DSL with custom model fields (hashid field)带有自定义模型字段(hashid 字段)的 Django elasticsearch DSL
【发布时间】:2021-10-19 14:59:33
【问题描述】:

我有一个模型使用django hashid 字段作为id

class Artwork(Model):

    id = HashidAutoField(primary_key=True, min_length=8, alphabet="0123456789abcdefghijklmnopqrstuvwxyz")

    title = ....

这是另一个模型的相关项

class ArtworkFeedItem(FeedItem):
    artwork = models.OneToOneField('artwork.Artwork', related_name='artwork_feeditem', on_delete=models.CASCADE)

现在我正在尝试设置 [django elasticsearch dsl] (https://github.com/django-es/django-elasticsearch-dsl) 并为此设置 Document

@registry.register_document
class ArtworkFeedItemDocument(Document):
    class Index:
        name = 'feed'
        settings = {
            'number_of_shards': 1,
            'number_of_replicas': 0
        }

    artwork = fields.ObjectField(
        properties={
            'id': fields.TextField(),
            'title': fields.TextField(
                attr='title',
                fields={
                    'suggest': fields.Completion(),
                }
            )
        }

    )

    class Django:
        model = ArtworkFeedItem
        fields = []
        related_models = [Artwork]

但是,当我尝试使用 python manage.py search_index --rebuild 索引 rebuild 时,出现以下异常

elasticsearch.exceptions.SerializationError: ({'index': {'_id': Hashid(135): l2vylzm9, '_index': 'feed'}}, TypeError("Unable to serialize Hashid(135): l2vylzm9 (type: <class 'hashid_field.hashid.Hashid'>)",))

Django elasticsearch dsl 显然不知道如何处理这样的 hashid 字段。

我想也许我可以自己制作HashIdField 喜欢

from elasticsearch_dsl import Field
class HashIdField(Field):
    """
    Custom DSL field to support HashIds
    """

    name = "hashid"

    def _serialize(self, data):
        return data.hashid

然后在'id': HashIdField 中使用它,但这又给了我一个例外

elasticsearch.exceptions.RequestError: RequestError(400, 'mapper_parsing_exception', 'No handler for type [hashid] declared on field [id]')

有人知道我怎样才能让它工作吗?

【问题讨论】:

    标签: python django elasticsearch elasticsearch-dsl hashids


    【解决方案1】:

    对于任何感兴趣的人,我设法通过覆盖 Documentgenerate_id 方法来解决这个问题,以便使用的 _id 只是一个普通字符串:

    
        @classmethod
        def generate_id(cls, object_instance):
            return object_instance.id.hashid
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-30
      • 1970-01-01
      • 1970-01-01
      • 2012-12-11
      • 2015-04-16
      相关资源
      最近更新 更多