【问题标题】:Inheritance: class method not accessible through use of Foreign Key继承:无法通过使用外键访问类方法
【发布时间】:2021-10-16 01:40:45
【问题描述】:

继承:类方法不能通过使用外键访问

你好!

问题

我有多个类继承自同一个类。我需要存储在另一个类(关系)中的这些类的实例之间存在不同的关系。为了能够将这些不同的类链接在一起,我使用它们都继承自的“母”类作为 ForeignKey。

一切正常,除了当我通过关系表(外键)访问子类的实例时,我无法从子类访问类方法。

当使用“超类”作为外键时,有什么方法可以访问子类的类方法?

代码

我的代码如下:

models.py

class SuperClass(models.Model):
    random_attribute = models.CharField()


class A(SuperClass):
    some_attribute = models.CharField()


class B(SuperClass):
    some_other_attribute = models.CharField()
    
    def class_b_method(self):
        some_code = 'goes_here'
        return some_code


class Relationship(models.Model):
    parent = models.ForeignKey(
        'app.SuperClass',
        related_name='parent',
        on_delete=models.CASCADE
    )
    child = models.ForeignKey(
        'app.SuperClass',
        related_name='child',
        on_delete=models.CASCADE
    )

views.py

def do_stuff():
    a = A('a')
    b = B('b')
    relationship = Relationship(parent=a, child=b)
    relationship.child.class_b_method()

这会引发以下错误:

AttributeError at xxx
'SuperClass' object has no attribute 'class_b_method'

我了解错误存在的原因及其含义,但我不知道如何从关系表中访问 B 类方法。

任何帮助将不胜感激, 谢谢。

【问题讨论】:

  • 是否在Relationship中添加了B类外键???
  • @boyenec: 因为有从BSuperClass 的关系,这意味着有一个从ABSuperClass 的继承OneToOneField
  • 我看到了问题所在。您的孩子在使用 app.SuperClass 时无法区分 A 类和 B 类尝试使用模型名称作为外键而不是 app.SuperClass

标签: python django python-2.x django-1.8


【解决方案1】:

您将需要访问其B 模型,您可以这样做:

def do_stuff():
    a = A('a')
    b = B('b')
    relationship = Relationship(parent=a, child=b)
    
    relationship.child.b.class_b_method()

因此,这将需要一个额外的查询来获取相关的B 对象。

虽然非抽象父级支持模型继承。使用它通常不是一个好主意。这是由带有OneToOneField 的额外表建模的。因此,这意味着为了找出它是什么子类型,需要查询所有可能的子类。虽然这在某种程度上可以有效地完成,但它仍然会导致相当“繁重”的查询和大量带宽将子类传递给 Django/Python 层。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-15
    相关资源
    最近更新 更多