面向

时间:2016-01-20 14:53:26

标签: python django django-haystack

首先,我对Python / Django非常陌生,但我已经使用其他技术多年了。

在用户可以创建出版物的网站中(例如我们想到亚马逊),我有一个Publication对象,其中包含基本内容,例如标题,详细信息,价格等。

但是,我希望包含特定于对象类型的某些属性(布料具有尺寸,颜色,男性/女性;汽车将具有品牌,型号,引擎,传输等)。我们的想法是使用Haystack / Elasticsearch对这些属性进行分面,具体取决于用户搜索的内容。

所以,这是基本模型:

# main publication class
class Publication(models.Model):
    OBJECT_TYPE = (
        ('cloth', 'Cloth'),
        ('electronics', 'Electronics'),
        ('car', 'Cars'),
    )
    object_type = models.CharField(max_length=30,
                                    choices=OBJECT_TYPE,
                                    default='electronics')
    title = models.CharField()
    details = models.CharField()
    # other fields...

# Haystack index
class PublicationIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    object_type = indexes.CharField(faceted=True, model_attr='object_type')
    # other fields...

问题是,我应该在哪里存储其他属性?

一种选择是让另一个具有详细信息的类/模型和出版物的FK。如果是这样,我应该如何构建索引呢?另一种选择是将所有出版物的所有属性放在Publication模型中,这将是最简单但可能不优雅。

另一个选择是继承CarPublicationClothPublication等。如果是这样,问题是,如何处理基本内容以避免重复所有屏幕出版类型。

我将只有3种发布类型,我认为我不会添加更多,所以进行继承,例如,是一个可行的选项(亚马逊有数百个类别,所以它是不同的。)

最好的方法是什么?

仅供参考,使用Python 3,Django 1.9,Haystack 2.5-dev,Elasticsearch。

2 个答案:

答案 0 :(得分:2)

django-polymorphic处理得很漂亮。

来自文档:

from polymorphic.models import PolymorphicModel

class Project(PolymorphicModel):
    topic = models.CharField(max_length=30)

class ArtProject(Project):
    artist = models.CharField(max_length=30)

class ResearchProject(Project):
    supervisor = models.CharField(max_length=30)


>>> Project.objects.create(topic="Department Party")
>>> ArtProject.objects.create(topic="Painting with Tim", artist="T. Turner")
>>> ResearchProject.objects.create(topic="Swallow Aerodynamics", supervisor="Dr. Winter")
# Get polymorphic query results:

>>> Project.objects.all()
[ <Project:         id 1, topic "Department Party">,
  <ArtProject:      id 2, topic "Painting with Tim", artist "T. Turner">,
  <ResearchProject: id 3, topic "Swallow Aerodynamics", supervisor "Dr. Winter"> ]

答案 1 :(得分:1)

行。即使@IanPrice的答案真的很好而且很有帮助,这就是我最终做的抽象基类(see the documentation):

class BasePublication(models.Model):
    class Meta:
        abstract = True
    # base properties

class CarPublication(BasePublication):
    # car-specific properties

class ClothPublication(BasePublication):
    # cloth-specific properties

原因是:

  • 就我而言,我不需要同时查询这两件事。这是可能的,但更复杂,因为它们存储在不同的表中。
  • 性能,使用继承添加内部联接或其他选择。它对我所掌握的信息量可能并不重要,但我对性能很着迷,所以我不喜欢这样。
  • 简单,在我的情况下使用继承添加了更多的问题,它解决了什么,所以使用抽象类更简单。