2016-01-20 67 views
3

首先,额外的属性,我非常非常新到Python/Django的,但我已经使用其他技术多年。Python的继承或小面

在一个网站,用户可以创建出版物(我们认为亚马逊的举例),我有一个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,2.5草堆-dev的,Elasticsearch。

+0

[django-polymorphic](https://github.com/chrisglass/django_polymorphic)处理这个美丽 –

+1

谢谢@IanPrice。看起来不错。随意发布它作为答案。 –

回答

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"> ] 
+0

因为我的帮助,我已经将你的标记标记为解决方案,但是我最终做了我在答案中解释的内容。我已经试过了,它像魅力一样工作!谢谢! –

+1

非常好。以防万一任何人在将来考虑这一点,django-polymorphic允许按照模型类型进行过滤 - “Project.objects.instance_of(ArtProject)'>>>'[]'(你也可以使用'not_instance_of') –

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 

的原因是:

  • 在我来说,我并不需要在同一时间查询这两件事情。这是可能的,但更复杂的是,它们存储在不同的表中。
  • 使用继承的性能会添加一个内部联接或其他选择。虽然我拥有的信息量可能并不重要,但我对表现很疯狂,所以我不喜欢那样。
  • 简单,在我的情况下使用继承增加了更多的问题,它解决了,所以使用抽象类比较简单。