django model save - 在迁移期间未调用的覆盖方法

Raj*_*thi 7 python migration django

我的模型类中有一个保存覆盖方法,每次保存一个对象时都会生成一个新的slug.

def save(self, *args, **kwargs):
    if self.column2:
        self.slug = slugify(self.column1 + " " + self.column2)
    else:
        self.slug = slugify(self.column1)
    print slug
    super(MyModel, self).save(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

当我尝试通过登录python shell创建一个新对象时,我看到正在调用save方法.

python manage.py shell

>>> MyModel(column1="test",column2="2015").save()
slug is test-2015
Run Code Online (Sandbox Code Playgroud)

但是,当我运行迁移时,不会调用此保存覆盖方法.这是我的迁移脚本的一部分..

...
def add_myModel_details(apps, schema_editor):
    x = apps.get_model("myapp","myModel")
    MyModel(column1 = "test", column2="2015" ).save()
.....
Run Code Online (Sandbox Code Playgroud)

slug为空,因为没有调用保存覆盖.

Fli*_*imm 10

自定义模型方法在迁移期间不可用。

相反,您可以在RunPython函数中运行 put 代码,以自定义方式修改模型实例save()

参考:


Kir*_*lov 2

发生这种情况是因为迁移不会调用您的save方法。

我认为 save 方法不是生成 slug 的最佳位置。使用AutoSlugFieldSignals会更好。

1. 信号:

在您的情况下,您可以使用信号pre_save

例子:

@receiver(pre_save, sender=MyModel)
def my_handler(sender, **kwargs):
    my_model = kwargs.get('instance')
    if my_model.column2:
        my_model.slug = slugify(my_model.column1 + " " + my_model.column2)
    else:
        my_model.slug = slugify(my_model.column1)
    print my_model.slug
Run Code Online (Sandbox Code Playgroud)

2. AutoSlugField:

它不是一个标准字段,但很多库都实现了它。我使用django-extensions中的AutoSlugField。该字段也使用信号

例子:

slug = AutoSlugField(populate_from=("column1", "column2"))
Run Code Online (Sandbox Code Playgroud)

3.save方法和迁移

但如果您仍然想使用save生成 slug 的方法,我建议您创建数据迁移并手动添加 slug。

数据迁移 django >= 1.7

数据向南迁移

  • 恕我直言,slug 字段应该在“save()”函数中分配,如果发生更改,应该在迁移后手动调用它。例如 `./manage.py shell -> for x in x.objects.all(): x.save()` 因为这允许与保存相关的代码出现在正确的函数中,并且显式应用更改(如果出现错误等,可以检测并解决) (3认同)
  • 第一种信号方法实际上不适用于数据迁移。我尝试了这个(Django 1.10),并且信号也没有被调用。有关详细信息,请参阅http://stackoverflow.com/questions/26542617/how-can-i-send-signals-from-within-django-migrations (2认同)