如何在Peewee中通过ForeignKeyField从子类调用父类方法?
看起来你遇到的问题主要来自三个地方:字段命名的误区、实例方法的调用方式错误,以及对自引用外键的误用。让我一步步帮你解决:
首先,字段名不要用双下划线开头。Python会对双下划线开头的变量进行名称修饰(name mangling),比如你定义的__A_reference会被Python自动改成_B__A_reference,这会导致Peewee无法正确将这个字段映射到数据库列,同时你在test_ping里访问self.__A_reference时,也无法正确获取到关联的A实例——因为Peewee的模型实例属性是基于你定义的字段名来生成的,而不是修饰后的名称。
其次,你可能用类而非实例调用了实例方法。test_ping是B类的实例方法,必须通过B的实例来调用,而不是直接调用B.test_ping()(这样调用会缺少self参数,要么报错,要么根本不会执行你预期的逻辑)。
最后,自引用外键用错了场景。你改成ForeignKeyField("self")是让B关联到自身的实例,这和A类完全无关,自然无法调用A的ping方法,这是方向上的错误。
下面是修正后的完整代码示例:
from peewee import Model, ForeignKeyField, SqliteDatabase # 补全Base_Model的基础定义(假设你是这样配置的) db = SqliteDatabase('your_db.db') class Base_Model(Model): class Meta: database = db class A(Base_Model): def ping(self): print("Ping!") class B(Base_Model): # 改用正常命名或单下划线开头,避免名称修饰问题 a_reference = ForeignKeyField(A, null=True, backref='bs') def test_ping(self): # 先判断关联是否存在,避免null时调用方法报错 if self.a_reference is not None: self.a_reference.ping() else: print("Warning: No A instance linked to this B!") # 初始化数据库并创建表 db.connect() db.create_tables([A, B]) # 创建关联实例 a_instance = A.create() b_instance = B.create(a_reference=a_instance) # 正确调用实例方法 b_instance.test_ping() # 此时会打印"Ping!"
几个关键注意点:
- 字段名使用正常命名(或单下划线开头表示内部),让Peewee能正确处理字段映射。
- 必须通过B的实例调用
test_ping,因为只有实例才持有具体的外键关联数据。 - 因为外键设置了
null=True,调用关联对象的方法前最好做非空判断,防止出现AttributeError。
内容的提问来源于stack exchange,提问作者A.L. Verminburger
相关产品推荐
相关产品推荐

