You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Peewee v2.7.4中,支持外键引用直接传模型实例的特性是什么?

解答:Peewee中外键直接传入模型实例的特性

你遇到的这个情况,核心是Peewee的ForeignKeyField自带的实例到主键的隐式转换特性,不过在v2.7.4这个版本里有一些需要注意的细节,我给你梳理清楚:

为什么直接传实例有时候可行?

当你的模型通过ForeignKeyField定义外键关联时(比如ModelB里的model_a = ForeignKeyField(ModelA)),Peewee会自动处理两种传参方式:

  • model_a_id(自动生成的主键存储字段)传主键值(比如model_a.get_id()的结果)
  • model_a(外键字段本身)传ModelA的实例——此时Peewee会自动提取实例的主键值,填充到model_a_id字段中

这是ForeignKeyField为了简化开发而设计的特性,避免你每次都要手动取主键。

为什么你的代码里model_a_id=model_a会失效?

在Peewee v2.7.4这个较早的版本中,直接给_id后缀的字段传模型实例是不被支持的。这个版本的字段处理逻辑里,只有外键字段本身(也就是不带_id的那个字段名)才会触发实例到主键的转换。

所以你应该把代码改成这样:

Model_b.get_or_create(name='foo', model_a=model_a)

这样就能正常工作,不需要手动调用get_id()

额外排查点

如果改了字段名还是不行,那你要检查ModelB的定义:是不是没有用ForeignKeyField,而是手动定义了model_a_id = IntegerField()?如果是普通的IntegerField,Peewee不知道这是外键关联,自然不会帮你转换实例,必须传主键值才行。

举个正确的模型定义例子:

from peewee import Model, CharField, ForeignKeyField, SqliteDatabase

db = SqliteDatabase('test.db')

class ModelA(Model):
    name = CharField()
    class Meta:
        database = db

class ModelB(Model):
    name = CharField()
    model_a = ForeignKeyField(ModelA)  # 这里是关键,用ForeignKeyField定义外键
    class Meta:
        database = db

用这个定义的话,Model_b.get_or_create(name='foo', model_a=model_a)就会正常触发实例转换。

内容的提问来源于stack exchange,提问作者Ritmo2k

火山引擎 最新活动