簡體   English   中英

When using Generics types, how can I call an Attribute of an inherited class on the Base class instance with Python / Django?

[英]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-utilsInheritanceManager

通過將 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM