【问题标题】:Django & South: Custom field methods are not executed when doing obj.save() in a data migrationDjango & South:在数据迁移中执行 obj.save() 时不执行自定义字段方法
【发布时间】:2012-07-15 08:55:55
【问题描述】:

在我的 Django 模型中,我有两个字段,name(常规的 CharField)和 slug,这是一个自定义字段,它根据字段定义中传递的字段名称生成 slug,在这种情况下我使用name 这个。

首先,模型只有 name 字段,以及相应的迁移和所有内容。然后我需要添加 slug 字段,因此按照 South 约定,我添加了带有 unique=False 的 slug 字段,创建架构迁移,然后创建数据迁移,设置 unique=True 并为最后一次更改创建另一个迁移.

由于 slug 的值是在模型保存时生成的,因此在数据迁移的 forwards 方法中,我所做的是遍历 orm['myapp.MyModel'].objects.all() 返回的查询集并在每个实例上调用 save() 方法。

但是 slug 字段的值永远不会生成。在 IPython 会话下,我做了同样的事情,但将模型引用为 from myapp.models import MyModel,并且工作正常。使用一些调试语句,打印 South 的 orm dict 返回的模型的 type 显示了真实的类,它似乎不是 South 即时构建的假模型。

slug 字段在 pre_save 方法时创建它的值。如何在数据迁移期间强制调用它?我需要确保值的唯一性,以便在以后的架构迁移中应用索引时,列不包含重复值。

谢谢!

顺便说一句:slug 字段类确实定义了south_field_triple,所以 South 很适合它。

编辑:请参阅my answer。但更像是一个答案,感觉更像是一个黑客。有没有更好/正确的方法来做到这一点?

【问题讨论】:

  • 您的内容类型一切正常吗?
  • 是的,我没有添加或删除任何模型,也没有更改任何模型的名称。刚刚添加了新字段。

标签: django migration custom-fields django-south unique-key


【解决方案1】:

通常,您应该在迁移中尽可能地显式复制生成字段内容的代码(故意重复代码的罕见示例)。您的方法中的代码,即使它有效,也会调用在 执行 迁移时定义的 pre_save,这可能在创建迁移时更改甚至失败,模型状态(这可能取决于在更早的时间不存在的其他字段等)。

因此,您示例中的正确方法是直接使用 slugify(),就像在 SlugField 的 pre_save 方法中所做的那样:

from django.template.defaultfilters import slugify

class Migration(DataMigration):

    def forwards(self, orm):
        "Write your forwards methods here."

        for myobj in orm['myapp.MyModel'].objects.all():
            myobj.slug = slugify(myobj.otherfield)
            myobj.save()

【讨论】:

    【解决方案2】:

    我通过获取模型字段实例并直接调用它为pre_save暂时解决了这个问题:

    class Migration(DataMigration):
    
        def forwards(self, orm):
            "Write your forwards methods here."
            # Note: Remember to use orm['appname.ModelName'] rather than "from appname.models..."
            for myobj in orm['myapp.MyModel'].objects.all():
                slug_field = myobj._meta.get_field_by_name('slug')[0]
                myobj.slug = slug_field.pre_save(myobj, add=False)
                myobj.save()
    

    但是将这一点考虑到自定义字段感觉很麻烦...

    【讨论】:

      猜你喜欢
      • 2018-11-03
      • 2012-10-04
      • 2013-01-16
      • 1970-01-01
      • 2014-01-29
      • 1970-01-01
      • 2014-05-01
      • 2012-05-19
      • 2013-02-15
      相关资源
      最近更新 更多