2016-01-20 65 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 

的原因是:

  • 在我來說,我並不需要在同一時間查詢這兩件事情。這是可能的,但更復雜的是,它們存儲在不同的表中。
  • 使用繼承的性能會添加一個內部聯接或其他選擇。雖然我擁有的信息量可能並不重要,但我對錶現很瘋狂,所以我不喜歡那樣。
  • 簡單,在我的情況下使用繼承增加了更多的問題,它解決了,所以使用抽象類比較簡單。