[英]When using Generics types, how can I call an Attribute of an inherited class on the Base class instance with Python / Django?
假設我有一個名為 person 的基本通用 class 來對擴展它的所有其他人進行分組:
class Person(models.Model):
name = models.CharField(...)
以及擴展 Person 的 class Worker:
class Worker(Person):
card_id = models.CharField(...)
當我訪問所有 Person 對象時,我也看到了 Workers,但可以說從那里我想這樣做:
worker = Worker(name='Example', card_id='1234')
person = Person.objects.all().first()
假設由於某種原因我想使用 Person class 並調用 Attribute o Worker:
[in] person.card_id
# Somehow expecting this result:
[out] '1234
是否可能,是否可行,我該怎么做?
恐怕這是不可能的,即使您可以保證您檢索到的Person
object (即Person.objects.all().first()
)也是Worker
。
Django 中可能有 inheritance 的三個 styles: 抽象基類、 代理模型和多表 ZE58BB489C13E702
在這種情況下,您使用的是多表 Inheritance 。 顧名思義,每個 model 都會在數據庫中收到自己的表,因此也可以進行查詢。
在查詢Person
對象時,您最終會得到Person
實例,而不是Worker
實例或任何其他子 class 實例。 由於card_id
字段未在Person
model 中定義,而是在其子模型之一中定義,因此在嘗試檢索Person
實例的card_id
值時會出錯,即使該實例也是Worker
。
但是,如果您知道您的Person
實例也是一個Worker
,您可以通過以下方式檢索它:
person = Person.objects.all().first()
worker = person.worker
這是因為 inheritance 關系在孩子和它的每個父母之間創建了一個OneToOneField
。 但是,請注意,如果person
實例實際上不是Worker
,這將給出錯誤。
一個可能有幫助的庫是django-model-utils
的InheritanceManager 。
通過將 InheritanceManager 附加到您的基礎 class model 例如:
from model_utils.managers import InheritanceManager
class Person(models.Model):
objects = InheritanceManager()
# ...
然后,您可以使用.select_subclasses
過濾器過濾父 model 的查詢集,以僅包含特定子 class 的對象。 例如,對於同時也是工人的人,您可以執行以下查詢:
persons_worker = Person.objects.select_subclasses(Worker)
並且在嘗試為persons_worker
中的任何實例檢索card_id
時,您永遠不應該遇到麻煩。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.