6

在我的 Django 模型中,我有两个字段,name(一个常规CharField)和slug一个自定义字段,它根据字段定义中传递的字段名称生成 slug,在本例中我name用于此。

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

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

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

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

谢谢!

顺便说一句:蛞蝓字段类确实定义了south_field_triple所以南方玩得很好。

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

4

2 回答 2

4

通常,您应该在迁移中尽可能地显式复制生成字段内容的代码(有目的的代码复制的罕见示例)。您的方法中的代码即使有效,也会按照执行迁移时定义的方式调用 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()
于 2012-11-13T09:12:02.107 回答
1

我通过获取模型字段实例并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()

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

于 2012-07-16T14:01:55.657 回答