hek*_*ran 4 django django-models
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)
Run Code Online (Sandbox Code Playgroud)
我有一个名为echo_category的帖子保存回调:
def echo_category(sender, **kwargs):
print "category: '%s'" % kwargs['instance'].category
post_save.connect(echo_category, sender=Dog)
Run Code Online (Sandbox Code Playgroud)
我有这个装置:
[
{
"pk": 1,
"model": "animal.animal",
"fields": {
"category": "omnivore"
}
},
{
"pk": 1,
"model": "animal.dog",
"fields": {
"color": "brown"
}
}
]
Run Code Online (Sandbox Code Playgroud)
在程序的每个部分中,除了post_save回调之外,以下情况都是如此:
from animal.models import Dog
Dog.objects.get(pk=1).category == u'omnivore' # True
Run Code Online (Sandbox Code Playgroud)
当我运行syncdb并安装fixture时,运行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)
Run Code Online (Sandbox Code Playgroud)
这里奇怪的是dog对象的category属性是一个空字符串.为什么它不像其他地方那样"杂食"?
作为临时(希望)解决方法,我在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)
Run Code Online (Sandbox Code Playgroud)
这有效,但它不是我喜欢的东西,因为当模型从另一个模型继承并且必须再次访问数据库时,我必须记住这样做.另一个奇怪的事情是我必须使用instance.pk来获取主键.普通的'id'属性不起作用(我不能使用instance.id).我不知道为什么会这样.也许这与category属性不正确的原因有关?
这是因为使用loaddata/ syncdbcommand 从fixture加载的数据在数据库中保存为raw:只保存生成的模型表的字段,以避免为类层次结构中的所有模型访问数据库.
但是,当模型保存为原始模型时,您会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)
Run Code Online (Sandbox Code Playgroud)
这样,在处理灯具时,您将只获得额外的数据库查询(我想这在您的情况下是可接受的).
关于你的另一个问题:
另一个奇怪的事情是我必须使用instance.pk来获取主键.普通的'id'属性不起作用(我不能使用instance.id).我不知道为什么会这样.
id并且pk语义略有不同.在实施例中,id一个的Dog对象的AutoField定义的(自动的)在你的Animal类.该pk然而,是OneToOneField(再次,自动地限定在)Dog类.
实际上,两个字段始终具有相同的值.但是,就像id来自的字段一样Animal,Dog对象保存为raw也不存在.
希望有所帮助.
编辑:这个问题已经在django的trac上报道了.
| 归档时间: |
|
| 查看次数: |
1333 次 |
| 最近记录: |