SerializationError重建弹性搜索Django应用程序

时间:2016-06-16 13:52:31

标签: django elasticsearch django-haystack

我在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)

1 个答案:

答案 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]