【问题标题】:How can I determine if instance of class from Django model is subclass of another model?如何确定 Django 模型中的类实例是否是另一个模型的子类?
【发布时间】:2011-01-19 21:05:48
【问题描述】:

我有一个名为BankAccount 的类作为基类。我也有继承自 BankAccountCheckingAccountSavingsAccount 类。

BankAccount 不是抽象类,但我不会从它创建对象,只创建继承类。

然后,我执行如下查询:

account = BankAccount.objects.get(id=10)

我如何知道帐户是CheckingAccount 还是SavingsAccount

我现在这样做的方式是这样的:

checking_account = CheckingAccount.objects.get(id=account.id)

如果存在,则为CheckingAccount,否则为SavingsAccount

【问题讨论】:

标签: python django inheritance django-models subclass


【解决方案1】:

尝试使用checkingaccountsavingsaccount 属性。它是不会爆炸的。

【讨论】:

  • 如果属性名只在运行时知道怎么办?
  • 在运行时,假设您选择了一个名为account 的基础BankAccount 对象,变量属性名称为attr_name。运行hasattr(account, attr_name),如果存在该类型的子类,您将获得 True,否则,您将获得 False。
  • v1.9 链接描述了这种多表继承:docs.djangoproject.com/en/1.9/topics/db/models/…
【解决方案2】:

您可以使用@987654321@(account, SavingsAccount),但可以使用generally preferred to avoid it,并通过查看对象的属性来使用duck type inference,看看它是否像子类一样嘎嘎作响。

要查看是否为 object has an attribute,请使用恰当命名的 hasattr built-in function 或使用 getattr 并检查是否引发了 AttributeError 异常。

【讨论】:

  • 鸭式推理链接坏了
【解决方案3】:

将 GetAccountType() 方法添加到您的 Checking 和 Savings 帐户,当您从 BankAccount.objects.get() 获取对象时,然后调用该方法,如果从 BankAccount 派生的所有内容都具有该方法,那么您会没事的。

【讨论】:

  • BankAccount.objects.get() 返回一个 BankAccount 对象。总是。
  • 你说得对,我以为我在自己的代码中使用了类似的东西,但我检查了一下,我只是根据派生类进行查询。
【解决方案4】:

经过一番搜索,我找到了类似的解决方案: Django multi-table inheritance, how to know which is the child class of a model?

基本上,对此没有优雅的解决方案。你必须做一堆 try-except 语句并强制 django 使用你想要的类。

【讨论】:

    【解决方案5】:

    有点笨拙,但这会起作用:

    >>> class BankAccount(object): pass
    ...
    >>> class SavingsAccount(BankAccount): pass
    ...
    >>> class CheckingAccount(BankAccount): pass
    ...
    >>> x = SavingsAccount()
    >>> type(x) == type(SavingsAccount())
    True
    >>> type(x) == type(CheckingAccount())
    False
    

    【讨论】:

    • type(x) == SavingsAccount 在不创建新对象的情况下执行相同操作。
    • 如果您从 BankAccount 查询,这将非常失败。 Django 不会自动提升模型。
    猜你喜欢
    • 2014-01-30
    • 2010-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-30
    相关资源
    最近更新 更多