我在 Haystack 上使用 Whoosh 并且一切正常,我想更改为 ElasticSearch 但是当我运行rebuild_index 时出现以下错误。我不确定为什么会发生错误,它似乎在提示我的模型和数据,但是如果我切换回 Whoosh 搜索/索引一切正常。
Django==1.8.4
elasticsearch==2.3.0
django-haystack==2.4.1
File "C:\Users\user.virtualenvs\pguider\lib\site-packages\elasticsearch\serializer.py", line 50, in dumps raise SerializationError(data, e) elasticsearch.exceptions.SerializationError: ({u'django_id': u'1', 'created': '2016-02-13T22:19:28.037000+00:00', 'suppl ier_code': u'BL32291', 'related_supplier_parts': [], u'django_ct': u'products.supplierpart', 'supplier': u'Parts Town', 'text': u'BL32291\n32291\nBlodgett\n\nParts Town\n\n\n', 'part_code': u'32291', u'id': u'products.supplierpart.1'}, Type Error("Unable to serialize [] (type: )",))
这是我的模型:
from django.db import models
class Supplier(models.Model):
name = models.CharField(max_length=50)
def __unicode__(self):
return u'%s' % self.name
class Part(models.Model):
name = models.CharField(max_length=200, null=True)
code = models.CharField(max_length=30, null=True)
def __unicode__(self):
return u'%s %s' % (self.code, self.name)
class SupplierPart(models.Model):
part = models.ForeignKey(Part)
supplier = models.ForeignKey(Supplier)
supplier_code = models.CharField(max_length=30)
description = models.CharField(max_length=200)
price = models.CharField(max_length=6, null=True)
sale_price = models.CharField(max_length=6, null=True)
quantity = models.IntegerField(null=True)
photo = models.ImageField(upload_to='products', null=True)
url = models.URLField()
created = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
return self.supplier_code
@property
def related_supplier_parts(self):
return self.part.supplierpart_set.all().exclude(pk=self.pk)
最佳答案
问题在于您的属性(property)related_supplier_parts
. Elasticsearch 无法序列化它。此属性返回查询集。
>>> parts = Part.objects.all()
>>> import json
>>> json.dumps({'related_supplier_parts': parts})
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/usr/lib/python2.7/json/__init__.py", line 243, in dumps
return _default_encoder.encode(obj)
File "/usr/lib/python2.7/json/encoder.py", line 207, in encode
chunks = self.iterencode(o, _one_shot=True)
File "/usr/lib/python2.7/json/encoder.py", line 270, in iterencode
return _iterencode(o, 0)
File "/usr/lib/python2.7/json/encoder.py", line 184, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: [] is not JSON serializable
如何解决?
对于任何项目来说,最好的办法是不要让模型的属性复杂化。尽管我们知道它们被广泛使用且易于编写。在我的 Django 职业生涯中,我从未使用过任何属性(property)。在我目前的项目中,我有 153 个模型而不是一个属性。在 99% 的情况下,您不需要它们,因为简单的方法
get_related_supplier_parts
应该做同样的工作。class SupplierPart(models.Model):
[...]
created = models.DateTimeField(auto_now_add=True)
def __unicode__(self):
return self.supplier_code
def get_related_supplier_parts(self):
return self.part.supplierpart_set.all().exclude(pk=self.pk)
@property 的另一个缺点是,每当您尝试序列化对象时,都会执行额外的查询并考虑序列化数百万个对象。您无需担心方法。
如果您出于某种原因拒绝此操作,您将需要找到一种方法将此查询转换为列表。可能在您的索引类中定义新字段:
class MyIndex(indexes.SearchIndex, indexes.Indexable):
[...]
related_supplier_parts = indexes.MultiValueField()
def prepare_related_supplier_parts(self, obj):
return [part.id for part in obj.related_supplier_parts]
关于django - 序列化错误重建 Elasticsearch Django 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37861283/