django - 序列化错误重建 Elasticsearch Django 应用程序

标签 django elasticsearch django-haystack

我在 Haystack 上使用 Whoosh 并且一切正常,我想更改为 ElasticSearch 但是当我运行rebuild_index 时出现以下错误。我不确定为什么会发生错误,它似乎在提示我的模型和数据,但是如果我切换回 Wh​​oosh 搜索/索引一切正常。

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/

相关文章:

windows - 升级到 Django 1.4 后,Eclipse 中的 Django 应用程序无法运行

elasticsearch - FilteredQueryBuilder 已弃用

python - 从 Django Haystack 中的外键搜索

c# - Elasticsearch有重复的记录

python - django haystack/whoosh : find records with umlauts/diaeresis, 带有简单的 ascii 查询

Django haystack 奇怪的错误?

django - 将 Django 应用程序部署到 Amazon AWS Elastic Beanstalk 时出现问题

python - 如何从 Django URL 更改语言?

python - 未找到 generate_presigned_post 的 BotoCore/Boto3 Stubber 操作

elasticsearch - Flume 1.6与ElasticSearch 2.3.1的兼容性