gpt4 book ai didi

Django 的 post_save 信号对使用多表继承的模型表现得很奇怪

转载 作者:行者123 更新时间:2023-12-01 00:02:58 26 4
gpt4 key购买 nike

Django 的 post_save 信号对使用多表继承的模型表现得很奇怪

当使用具有多表继承的模型时,我注意到 Django 的 post_save 信号的工作方式有一个奇怪的行为。

我有这两个模型:

class Animal(models.Model):
category = models.CharField(max_length=20)

class Dog(Animal):
color = models.CharField(max_length=10)

我有一个名为 echo_category 的后期保存回调:
def echo_category(sender, **kwargs):
print "category: '%s'" % kwargs['instance'].category
post_save.connect(echo_category, sender=Dog)

我有这个夹具:
[
{
"pk": 1,
"model": "animal.animal",
"fields": {
"category": "omnivore"
}
},

{
"pk": 1,
"model": "animal.dog",
"fields": {
"color": "brown"
}
}
]

在程序的每个部分中,除了 post_save 回调中,以下都是正确的:
from animal.models import Dog
Dog.objects.get(pk=1).category == u'omnivore' # True

当我运行 syncdb 并安装了夹具时,就会运行 echo_category 函数。 syncdb 的输出是:
$ python manage.py syncdb --noinput
Installing json fixture 'initial_data' from '~/my_proj/animal/fixtures'.
category: ''
Installed 2 object(s) from 1 fixture(s)

这里奇怪的是狗对象的类别属性是一个空字符串。为什么它不像其他地方那样是“杂食动物”?

作为临时(希望如此)的解决方法,我在 post_save 回调中从数据库重新加载对象:
def echo_category(sender, **kwargs):
instance = kwargs['instance']
instance = sender.objects.get(pk=instance.pk)
print "category: '%s'" % instance.category
post_save.connect(echo_category, sender=Dog)

这有效,但不是我喜欢的,因为当模型从另一个模型继承并且必须再次访问数据库时,我必须记住这样做。另一个奇怪的事情是我必须执行 instance.pk 才能获取主键。正常的“id”属性不起作用(我不能使用 instance.id)。我不知道这是为什么。也许这与类别属性没有做正确事情的原因有关?

最佳答案

这是因为从夹具加载的数据 loaddata/syncdb命令在数据库中保存为原始数据:仅保存生成的模型表的字段,以避免为类层次结构中的所有模型访问数据库。

但是,当模型保存为原始模型时,您会得到一个额外的 raw信号中的关键字参数,因此您可以正确处理这种情况。你的信号最终会是这样:

def echo_category(sender, **kwargs):
if kwargs.get('raw', False):
instance = sender.objects.get(pk=kwargs['instance'].pk)
else:
instance = kwargs['instance']
print "category: '%s'" % instance.category

post_save.connect(echo_category, sender=Dog)

这样,您在处理设备时只会得到额外的数据库查询(我想这在您的情况下是可以接受的)。

关于你的另一个问题:

The other weird thing is that I must do instance.pk to get the primary key. The normal 'id' attribute does not work (I cannot use instance.id). I do not know why this is.


id pk 语义略有不同。在您的示例中, idDog对象是 AutoField在您的 Animal 中定义( automagically )类(class)。 pk然而,是 OneToOneField (再次, automagically defined )在 Dog 中类(class)。

实际上,这两个字段都有 一直以来的值(value)。但是,如 id是来自 Animal 的字段,它不会存在于 Dog保存为原始对象。

希望有帮助。

编辑 : 这个问题已经在 django 的 trac here 上报告了.

关于Django 的 post_save 信号对使用多表继承的模型表现得很奇怪,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2604800/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com