Django覆盖保存

Posted

技术标签:

【中文标题】Django覆盖保存【英文标题】:Django overwrite save 【发布时间】:2011-08-17 21:49:03 【问题描述】:

我想在我的模型中覆盖 save 方法以创建适当的 slug 并创建图像域的副本,并在其中进行少量修改。我该如何处理?

def save(self, *args, **kwargs):
            super(MyModel, self).save(*args, **kwargs) #to get id

            #slug
            self.slug = '%s-%i' % (self.topic, self.id)

            #create copy of img
            cp_path = dirname(self.image.path)+'/copies_'+basename(self.image.path)
            shutil.copy2(self.image.path, cp_path)

            file = open(cp_path)
            django_file = File(file)
            django_file.name = basename(cp_path) #otherwise path will be duplicated
            self.cp_image = django_file

            super(MyModel, self).save(*args, **kwargs) #to save my new ImageField

            create_watermark(self.cp_image, self.topic, self.text, 500, 45)

因为我使用了 super(MyModel, self).save() 两次,所以我有一个 self.image 文件的副本。如您所见,我对 django 和 python 不是很熟悉。我怎样才能做得更好?

【问题讨论】:

【参考方案1】:

这可能不是最优雅的方式,但您可以尝试将save()post_save signal 结合使用。可能看起来像:

class MyModel(Model):
    ## Stuff
    def save(self, *args, **kwargs):
        #create copy of img.  Fixed up to use string formatting.
        cp_path = "%s/copies_%s" % 
            (dirname(self.image.path), basename(self.image.path))
        shutil.copy2(self.image.path, cp_path)
        file = open(cp_path)
        django_file = File(file)
        django_file.name = basename(cp_path)
        self.cp_image = django_file
        create_watermark(self.cp_image, self.topic, self.text, 500, 45)
        super(MyModel, self).save(*args, **kwargs) #to save my new ImageField

from django.dispatch import receiver
from django.db.models.signals import post_save
@receiver(post_save, sender=MyModel)
def mymodel_slug_handler(sender, instance=None, **kwargs):
    if instance is not None:
        new_slug = '%s-%i' % (instance.topic, instance.id)
        if instance.slug != new_slug: # Stops recursion.
            instance.slug = new_slug
            instance.save()

【讨论】:

不幸的是,如果我在尝试操作文件之前不使用 save() 方法,会导致“没有这样的文件或目录:”错误。 哦,然后将整个保存移动到 post_save 处理程序。这也将允许您检查 created=True 是否只执行一次。

以上是关于Django覆盖保存的主要内容,如果未能解决你的问题,请参考以下文章

Django - 覆盖模型保存()

如何以 django 模型形式覆盖保存方法

django保存表单 - 覆盖旧行

Django 抽象父模型保存覆盖

Django 信号与覆盖保存方法

Django Admin Cookbook-40如何为Django Admin覆盖保存操作