2016-04-26 49 views
0

我有一個單一的集合,可以表示多種類型的數據:如何使用多個模型指向相同的集合?

class Taxes(db.Document): 
    meta = {'collection': 'taxes'} 

    type = db.StringField() # State, local, federal 
    owner = db.ReferenceField(User, unique=True) 
    name = db.StringField() 
    fiscal_year = db.IntField() 

我所想要做的是有一張DynamicEmbeddedDocument或使這個DynamicDocument持有不同的模型。

例如:

class Taxes(db.Document): 
    ... 
    # This is made up syntax 
    data = db.EmbeddedDocumentField(StateTaxes, LocalTaxes, FederalTaxes) 

或者:

class Taxes(db.DynamicDocument): 
    ... 

class StateTaxes(Taxes): 
    state_name = db.StringField() 

class LocalTaxes(Taxes): 
    locality_name = db.StringField() 

的目標是要做到這一點:

# Embedded Dynamic Document example 
taxes = Taxes.objects(owner=current_user).all() 
state_taxes = [tax.data for tax in taxes if tax.type == 'state'] 
state_names = [tax_data.state_name for tax_data in state_taxes] 

# Dynamic Document example 
taxes = Taxes.objects(owner=current_user).all() 
state_taxes = [tax for tax in taxes if tax.type == 'state'] 
state_names = [tax.state_name for tax in state_taxes] 

注:

  • 我必須能夠執行1個查詢來取回所有類型**。
  • 模型應該分開以便允許清晰的定義。
  • 這個例子非常小,將會有越來越多的定義非常不同的模型**。
  • 所有型號將有4或5個相同的字段。
  • 動態數據應該相對容易查詢。

**這些都是我沒有使用獨立的集合

這是可能的主要原因是什麼?

+0

爲什麼機型:

results = BaseTaxes.objects().all() 

,然後通過子類拆分結果必須完全分開?我知道你有'稅收'偶爾需要存儲額外的屬性。爲什麼不只是聲明一個名爲'type'的簡單額外字段來存儲它是一個州或地方稅的事實呢?事實上,這是你想要的代碼似乎相信的思路。 –

+0

如果你走這條路線,那麼你可以在你的類定義中去掉EmbeddedDocumentField,而只需動態地設置屬性。 [文檔中的示例](http://docs.mongoengine.org/guide/defining-documents.html#dynamic-document-schemas)就足以滿足這種插入。 –

+0

從OOP的角度來看,Taxes是所有這些模型的基類,所以即使我使用了多個集合,它仍然會通過多重繼承作爲基礎。模型需要分開,因爲它們會有多大。每個模型都會說10個不同的領域。如果我有10個模型,在單個對象/類上有100個字段。 – Realistic

回答

1

您可以創建一個涵蓋所有基本屬性(字段)和您需要的方法的基類。例如:

class BaseTaxes(db.Document): 
    name = db.StringField() 
    value = db.IntegerField() 

    meta = {'allow_inheritance': True} 

    def apply_tax(self, value): 
     return value*(1+self.value) 

有了這個基類,你可以創建不同的版本:

class StateTaxes(BaseTaxes): 
    state = db.StringField() 

這樣的StateTaxes類繼承BaseTaxes及其方法(詳情here)的兩種屬性。因爲它繼承了BaseTaxes類,都將在同一集合中保存(BaseTaxes)和查詢能達到所有的子類:

state_taxes = [item for item in results if isinstance(item,StateTaxes)] 
+0

這正是我一直在尋找的和我所做的! – Realistic

相關問題