Django,如何在调用super()后更新save()方法中的模型?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django,如何在调用super()后更新save()方法中的模型?相关的知识,希望对你有一定的参考价值。

我有这样的问题。例如,我的模型类中有一个字段:

periodic_task = models.OneToOneField(PeriodicTask, null=True, blank=True)

我需要覆盖save()方法来设置此字段值:

def save(self, *args, **kwargs):
    super(PostTweetSet, self).save(*args, **kwargs)
    self.periodic_task = TaskScheduler.create(
        'tweets.tasks.post_next_tweet', self.interval.period,
        self.interval.every, args="[" + '"%s"' % str(self.pk) + "]")

你看到self.periodic_task在实际调用super()方法后被赋值。我这样做了,因为需要有一个pk字段(我在TaskScheduler创建方法中使用它)。另一方面,我需要在设置此新字段后更新此模型的db-table。如果我再次调用super(),我会收到有关复制id的错误。那么,我该怎么做才能使这个工作?或者我需要重建我的方法来完成这项任务?谢谢。

答案

我会用保存后的信号来做。

如果你不能或那个没有吸引力的话,你会将你的需求视为两条路径:

  • 如果你不是主键,你需要先保存它并获得pk
  • 如果您已经知道主键,则可以创建定期任务,然后调用super

所以像(伪代码):

def save(...):
    if self.pk is None:
        super(...)
        self.save(...)    # Call ourselves -- but this time, we'll have a primary key!
    else:
        ... create your periodic task
        super(...)
另一答案

通过在模型中的override save method中提供一些条件,我已经达到了相同的要求。

在这个问题中,要求是在保存模型后更新periodic_task字段,所以这里是我所遵循的sudo代码结构:

class MyModel(models.Model):
    periodic_task = models.OneToOneField(PeriodicTask, null=True, blank=True)
    def save(self):
        super(Asset, self).save()
        if not self.periodic_task: # Checking if the section is not updated.
            self.periodic_task = #code to update the field.
            self.save() #again call the save.
另一答案

您可能希望在post_save信号中执行此操作。

另一答案

您可以在super()覆盖结束时调用save()。以下是使用slugify()方法的示例。 slugify方法通过将所有字符转换为小写,将空格转换为破折号将字符串转换为slug。这是代码:

from django.template.defaultfilters import slugify

def save(self, *args, **kwargs):
    self.slug = slugify(self.title)
    super(Product, self).save(*args, **kwargs)

以上是关于Django,如何在调用super()后更新save()方法中的模型?的主要内容,如果未能解决你的问题,请参考以下文章

如何做到在子线程更新 UI?

Django:渲染视图后如何更新模型?

如何在 Django 中获取更新的类变量值

Django_信号

django-rest-framework:如何更新嵌套的外键?我的更新方法甚至没有被调用

上传文件后,如何在 Django 中使用 AJAX 更新表(与 JavaScript 链接)?