我對Django相當陌生,我試圖在Django模型中實現多態,但我看不到如何去做。在繼續之前,我不得不說我已經嘗試過django-model-utils和django-polymorphism,但它們並不完全符合我的要求。Django模型多態沒有多表繼承和額外的JOIN
我有一個叫播放器模式,每個玩家都有一個角色,每個角色都有不同的行爲(即他們的方法返回不同的值):
class Player(models.Model):
username=models.TextField()
role=models.ForeignKey(Role) #Role is another model with a field called ’name'
def allow_action(self)
#some stuff
class RoleA():
def allow_action(self):
#some specific stuff
class RoleB():
pass
我想我每次檢索播放器的任何實例(在例子中通過Player.objects.filter(...)),每個實例都有由特定類(RoleA,RoleB等)內定義的自定義方法覆蓋的allow_action()方法,或者使用Player中提供的默認方法(如果相關的子類沒有使用相同名稱調用的方法(RoleA,RoleB等...是存儲在Player.role.name中的相同角色名稱)。
約束:
由於子類(RolaA,RoleB,等...),不增加新的領域,但只覆蓋方法,所有的數據必須存儲播放器的表裏面,所以我不希望使用Django多表繼承,但更類似於代理。
我不想執行額外的JOIN來確定特定的子類型,因爲所有需要的信息都存儲在播放器的表中。
我認爲這是一個標準的多態性模式,但我不明白如何使用同一個表的所有玩家(我已經實現了這個多態性,但沒有鏈接到一個Django模型來實現它在Django )。我見過Django有一種名爲「Proxy」的繼承,但它不允許像Player.objects.filter(...)那樣查詢,並且得到的方法被自定義方法覆蓋的實例(或者至少這是我所理解的)。
在此先感謝。
爲什麼[django-polymorphic](https://django-polymorphic.readthedocs.org/en/latest/index.html)不符合您的需求?除非我錯過了某些東西,否則你可以完全按照你的意思去做。 – ptr
@PeteTinkler根據這個[示例](https://django-polymorphic.readthedocs.org/en/latest/quickstart.html#making-your-models-polymorphic)它違反了我的第一個約束,即使用多表繼承會爲每個子類創建一個新表,但我不想要這些表,因爲我的數據庫會被未使用的表污染(我將擁有許多RoleA,RoleB,RoleC等)。我認爲這同樣適用於下面的代碼段。 – Sirion
這些數據庫表將不會被使用。您將創建'RoleA ... RoleX'實例並使用'Role'基類中的'name'屬性。 – ptr