我在Haystack上使用Whoosh并且一切正常,我想更改为ElasticSearch但是当我运行rebuild_index时出现以下错误。我不确定为什么会发生错误,它似乎在抱怨我的模型和数据,但是如果我切换回Whoosh搜索/索引所有工作正常。
Django==1.8.4
elasticsearch==2.3.0
django-haystack==2.4.1
文件 " C:\用户\ user.virtualenvs \ pguider \ lib中\站点包\ elasticsearch \ serializer.py&#34 ;, 第50行,在转储中 提出SerializationError(data,e)elasticsearch.exceptions.SerializationError:({u' django_id':u' 1', '创建':' 2016-02-13T22:19:28.037000 + 00:00',' supplier_code': 你' BL32291',' related_supplier_parts':[],你' django_ct': u' products.supplierpart',' supplier&#39 ;: u' Parts Town',' text': u' BL32291 \ n32291 \ nBlodgett \ n \ nPart Town \ n \ n \ n',' part_code': u' 32291',u' id':u' products.supplierpart.1'},输入错误("无法 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)
答案 0 :(得分:1)
问题出现在你的财产related_supplier_parts
中。弹性搜索无法将其序列化。此属性返回queryset。
>>> 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职业生涯中使用任何财产。在我目前的项目中,我有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]