Python 分面的继承或额外属性
Python inheritance or extra properties for faceting
首先,我对 Python/Django 非常陌生,但多年来我一直在使用其他技术。
在一个用户可以创建出版物的网站中(让我们以亚马逊为例),我有一个 Publication
object 包含基本内容,例如标题、详细信息、价格等.
但是,我想包括特定于 object 类型的某些属性(布料会有尺寸、颜色,适合 men/for 女性;汽车会有品牌、型号、发动机、变速箱, ETC)。这个想法是使用 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...
问题是,我应该在哪里存储这些其他属性?
一个选择是让另一个 class/model 包含详细信息和出版物的 FK。如果是这样,我应该如何建立索引呢?另一种选择是将所有出版物的所有属性放在 Publication
模型中,这将是最简单但可能并不优雅。
另一种选择是继承 CarPublication
、ClothPublication
等。如果是这样,问题是,我如何处理基本内容以避免重复所有屏幕对于每种出版物类型。
我将只有 3 种发布类型,我不认为我会添加更多,所以做继承,例如,是一个可行的选择(亚马逊有数百种类别,所以它是不同的)。
最好的方法是什么?
仅供参考,使用 Python 3、Django 1.9、Haystack 2.5-dev、Elasticsearch。
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"> ]
好的。即使@IanPrice 的回答真的很好而且很有帮助,这就是我最终做的 abstract base 类 (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
原因是:
- 在我的例子中,我不需要同时查询这两件事。这是可能的,但更复杂,因为它们存储在不同的表中。
- 性能,使用继承添加内部连接或额外的选择。这可能对我拥有的信息量并不重要,但我对性能很着迷,所以我不喜欢那样。
- 简单,在我的例子中,使用继承增加了它解决的问题,所以使用抽象 类 更简单。
首先,我对 Python/Django 非常陌生,但多年来我一直在使用其他技术。
在一个用户可以创建出版物的网站中(让我们以亚马逊为例),我有一个 Publication
object 包含基本内容,例如标题、详细信息、价格等.
但是,我想包括特定于 object 类型的某些属性(布料会有尺寸、颜色,适合 men/for 女性;汽车会有品牌、型号、发动机、变速箱, ETC)。这个想法是使用 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...
问题是,我应该在哪里存储这些其他属性?
一个选择是让另一个 class/model 包含详细信息和出版物的 FK。如果是这样,我应该如何建立索引呢?另一种选择是将所有出版物的所有属性放在 Publication
模型中,这将是最简单但可能并不优雅。
另一种选择是继承 CarPublication
、ClothPublication
等。如果是这样,问题是,我如何处理基本内容以避免重复所有屏幕对于每种出版物类型。
我将只有 3 种发布类型,我不认为我会添加更多,所以做继承,例如,是一个可行的选择(亚马逊有数百种类别,所以它是不同的)。
最好的方法是什么?
仅供参考,使用 Python 3、Django 1.9、Haystack 2.5-dev、Elasticsearch。
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"> ]
好的。即使@IanPrice 的回答真的很好而且很有帮助,这就是我最终做的 abstract base 类 (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
原因是:
- 在我的例子中,我不需要同时查询这两件事。这是可能的,但更复杂,因为它们存储在不同的表中。
- 性能,使用继承添加内部连接或额外的选择。这可能对我拥有的信息量并不重要,但我对性能很着迷,所以我不喜欢那样。
- 简单,在我的例子中,使用继承增加了它解决的问题,所以使用抽象 类 更简单。