在w index中编入自定义Django模型字段

问题描述:

我们使用Django MarkupField来存储Markdown文本,它工作得很好。在w index中编入自定义Django模型字段

然而,当我们试图指数鹡鸰这些领域,我们从Elasticsearch系列化的错误,像这样:

File "/usr/local/lib/python3.5/dist-packages/wagtail/wagtailsearch/management/commands/update_index.py", line 120, in handle 
    self.update_backend(backend_name, schema_only=options.get('schema_only', False)) 
File "/usr/local/lib/python3.5/dist-packages/wagtail/wagtailsearch/management/commands/update_index.py", line 87, in update_backend 
    index.add_items(model, chunk) 
File "/usr/local/lib/python3.5/dist-packages/wagtail/wagtailsearch/backends/elasticsearch.py", line 579, in add_items 
    bulk(self.es, actions) 
File "/usr/local/lib/python3.5/dist-packages/elasticsearch/helpers/__init__.py", line 195, in bulk 
    for ok, item in streaming_bulk(client, actions, **kwargs): 
File "/usr/local/lib/python3.5/dist-packages/elasticsearch/helpers/__init__.py", line 162, in streaming_bulk 
    for bulk_actions in _chunk_actions(actions, chunk_size, max_chunk_bytes, client.transport.serializer): 
File "/usr/local/lib/python3.5/dist-packages/elasticsearch/helpers/__init__.py", line 61, in _chunk_actions 
    data = serializer.dumps(data) 
File "/usr/local/lib/python3.5/dist-packages/elasticsearch/serializer.py", line 50, in dumps 
    raise SerializationError(data, e) 
elasticsearch.exceptions.SerializationError: ({'_partials': [<markupfield.fields.Markup object at 0x7faa6e238e80>, <markupfield.fields.Markup object at 0x7faa6dbc4da0>], 'pk': '1', 'research_interests': <markupfield.fields.Markup object at 0x7faa6e238e80>, 'bio': <markupfield.fields.Markup object at 0x7faa6dbc4da0>}, TypeError("Unable to serialize <markupfield.fields.Markup object at 0x7faa6e238e80> (type: <class 'markupfield.fields.Markup'>)",)) 

一种解决方法是可调用索引返回field.raw但后来我们不得不写一个这样可以为我们模型中的每个Markdown字段属性调用。我认为我们可以通过扩展字段属性(即,替换MarkupField的django-markupfield Markup类)以get_searchable_content(value)方法解决此问题,但序列化错误仍然存​​在。

有没有人有任何提示在Wagtail + elasticsearch中为自定义Django字段建立索引?

我把get_searchable_content在错误的地方,我认为这是需要在Markup类,而是它需要被放置在Django的模型Field类本身。然后W will将拉出适当的值在elasticsearch(或任何其他搜索后端)中进行索引。

最直接的解决方案是使用自定义Field类扩展MarkupField,并添加一个get_searchable_content(self, value),将其实现委托给MarkupField.get_prep_value

有几种方法可以做到这一点。最好的做法是在elasticsearch-dsl中创建自己的字段,例如参见(0),并将其用于(反)序列化。其他选项是创建自己的JSONSerializer(1)子类,并将其作为serializer=MyJSONSerializer()Elasticsearch的构造函数中传递,即可以处理markupfield.fields.Markup对象。

0 - https://github.com/elastic/elasticsearch-dsl-py/blob/master/test_elasticsearch_dsl/test_document.py#L49-L58 1 - https://github.com/elastic/elasticsearch-py/blob/master/elasticsearch/serializer.py#L24