代码之家  ›  专栏  ›  技术社区  ›  hekevintran

Django的post\u save信号在使用多表继承的模型中表现得很奇怪

  •  4
  • hekevintran  · 技术社区  · 16 年前

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

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

    我有一个名为echo\u 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"
            }
        }
    ]
    

    from animal.models import Dog
    Dog.objects.get(pk=1).category == u'omnivore' # True
    

    当我运行syncdb并安装了fixture时,echo\u 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\u 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)
    

    1 回复  |  直到 16 年前
        1
  •  6
  •   Clément    16 年前

    这是因为从夹具加载的数据 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)
    

    关于你的另一个问题:

    另一件奇怪的事情是,我必须执行instance.pk来获取主键。普通的'id'属性不起作用(我不能使用instance.id)。我不知道这是为什么。

    id pk 语义稍有不同。在你的例子中 的 Dog AutoField automagically )在你的 Animal 主键 然而,这是一个 OneToOneField (再一次, automagically defined )在 班级。

    相同的 一直重视。然而,作为 身份证件 一块田是从哪里来的 动物 ,它将不存在 狗 对象另存为 .

    希望有帮助。

    编辑 here .

    推荐文章