【问题标题】:Django model.save() not working with loaddataDjango model.save() 不使用 loaddata
【发布时间】:2011-09-22 00:25:27
【问题描述】:

我有一个模型覆盖 save() 来对字段进行 slugify:

class MyModel(models.Model):
    name = models.CharField(max_length=200)
    slug = models.SlugField(max_length=200)

    def save(self, *args, **kwargs):
        self.slug = slugify(self.name)
        super(MyModel, self).save(*args, **kwargs)

当我运行 load data 来加载夹具时,这个 save() 似乎没有被调用,因为数据库中的 slug 字段为空。我错过了什么吗?

我可以通过 pre_save 钩子信号让它工作,但这有点小技巧,让save() 工作会很好。

def mymodel_pre_save(sender, **kwargs):
    instance = kwargs['instance']
    instance.slug = slugify(instance.name)

pre_save.connect(mymodel_pre_save, sender=MyModel)

提前致谢。

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    我现在正在做类似的事情 - 我需要第二个模型来为夹具中的第一个模型中的每个模型提供一个并行条目。第二个模型可以启用/禁用,并且必须在 loaddata 调用中保留该值。不幸的是,拥有一个具有默认值的字段(并将该字段排除在夹具之外)似乎不起作用 - 在加载夹具时它会重置为默认值(否则这两个模型可以组合在一起)。

    所以我使用的是 Django 1.4,这是我目前发现的:

    • save() 未被调用是正确的。有一个特殊的 DeserializedObject 可以执行插入操作,方法是在模型 class 上调用 save_base() - 覆盖模型上的 save_base() 不会做任何事情,因为它无论如何都会被绕过。
    • @Dave 也是正确的:当前文档仍然说未调用预保存信号,但确实如此。这是一个条件:if origin and not meta.auto_created
      • origin 是要保存的模型的类,所以我不明白为什么它会是假的。
      • meta.auto_created 到目前为止我所尝试的一切都是 False,所以我还不确定它的用途。查看Options对象,似乎与abstract models有关。
      • 是的,pre_save 信号确实正在发送。
    • 再往下,有一个post_save 信号在同样的条件后面也被发送。

    使用 post_save 信号有效。我的模型更复杂,包括“启用”模型上的 ManyToMany,但基本上我是这样使用它的:

    from django.db.models.signals import post_save
    
    class Info(models.Model):
       name = models.TextField()
    
    class Enabled(models.Model):
       info = models.ForeignKey(Info)
    
    def create_enabled(sender, instance, *args, **kwards):
       if Info == sender:
          Enabled.objects.get_or_create(id=instance.id, info=instance)
    
    post_save.connect(create_enabled)
    

    当然,initial_data.json 只定义了 Info 的实例。

    【讨论】:

      【解决方案2】:

      不,你不是。 save() 不是由 loaddata 调用的,设计上是这样(我想它的方式更耗费资源)。对不起。

      编辑:根据文档,也不调用 pre-save(即使显然是这样?)。

      根据https://docs.djangoproject.com/en/dev/ref/django-admin/#what-s-a-fixture,数据按原样保存到数据库中

      【讨论】:

      • 嗨@Dave,感谢您提供的信息。它似乎目前正在使用预保存。上面的第二段代码确实会导致模型实例的 slug 字段填充到数据库中。
      • 你知道这也是我的印象......但是文档却说不然。但是我和你在同一个地方,从来没有让 save() 工作。
      • 嗯,文档确实说 pre_save 没有被调用。但我只是调试了代码,它确实调用了 pre_save。从code.djangoproject.com/browser/django/trunk/django/core/… 跟踪到code.djangoproject.com/browser/django/trunk/django/db/models/… 运行。文档是错误的还是错误的?
      • 你绝对应该提交一个错误。
      猜你喜欢
      • 1970-01-01
      • 2015-09-18
      • 2011-05-25
      • 2012-06-30
      • 2010-10-27
      • 2010-12-10
      • 2014-05-23
      • 2016-12-05
      • 2014-04-24
      相关资源
      最近更新 更多