如何让Django Model在创建时运行一些功能

时间:2017-10-29 00:58:37

标签: python django django-models django-queryset

我想要什么

我在模特剧集中有一个“长度”列,另一个有一列“sum_length”。

我希望sum_length仅在剧集创建时更新,在我修改时不要更新。

我现在怎么做?

现在,我重写了保存功能,并添加了一个函数调用来更新它,就像这样。

def save(self, *args, **kwargs):
    if not self.excerpt:
        md = markdown.Markdown(extensions=[
            'markdown.extensions.extra',
            'markdown.extensions.codehilite',
        ])
        self.excerpt = strip_tags(md.convert(self.description))[:54]
        self.series.addlength(self.video_length)
    super(Episode, self).save(*args, **kwargs)

由于我的摘录是由降价内容生成的,所以我认为当摘录为空白时,它是保存,而不是更新

为什么我问这个问题?

  1. 我的解决方法是可用的,但我想找到更多的pythonic代码
  2. 当我真的需要更新时,我的解决方法不会更新。
  3. 你能给我什么?

    也许示例代码很好

    其他信息

    Django:1.11.6 Python:3.6.3 数据库:MySQL

    感谢您的回答

2 个答案:

答案 0 :(得分:0)

您可以将此功能移至模型表单中,而不是覆盖模型的保存。它会给你更多的灵活性。

在这种情况下,您可以创建两种不同的表单,让我们为普通用户说一个,其中摘录将在创建和管理表单上更新,如果有必要,将重写摘录。

class AdminForm(forms.ModelForm):

  class Meta:
    model = Episode

  def save(self, excerpt=None, force_insert=False, force_update=False, commit=True):

    object = super(Episode, self).save(commit=commit)

    if excerpt:
        object.excerpt = excerpt

class UserForm(forms.ModelForm):

  class Meta:
    model = Episode

  def save(self, excerpt=None, force_insert=False, force_update=False, commit=True):

    object = super(Episode, self).save(commit=commit)

    if not object.excerpt and excerpt:
        object.excerpt = excerpt

答案 1 :(得分:0)

有两种方法可以做到。

  1. 覆盖save()方法,就像你已经

    一样

    还有两种方法可以检查对象是否已经保存。

    一个。检查主键(pk)。

    我们可以简单地检查主要是否为None,因为只有在数据库中保存对象之后才设置主键。

    self.pk is None  
        #not saved
    else
        #already saved instance
    
    如果您在模型类中设置了(primary_key = True),则此解决方案将无法正常工作。

    湾Django还提供了另一种检查方法

    来自https://docs.djangoproject.com/en/2.0/ref/models/instances/#customizing-model-loading

    if self._state.adding == True 
       #not saved
    elif self._state.adding == False 
       #already saved instance
    
  2. 实施post_save信号 https://docs.djangoproject.com/en/1.11/ref/signals/#django.db.models.signals.post_save

    singal提供名为 created 的布尔属性。如果创建了新记录,则其值为true;如果已创建记录,则其值为。 这是最清洁的解决方案,如果要实现太多逻辑,必须使用

    按照这个简单的教程实现保存后信号https://simpleisbetterthancomplex.com/tutorial/2016/07/28/how-to-create-django-signals.html

  3. 如果逻辑很简单并且您希望该功能仅适用于一个型号,请选择第一个选项。

    根据代码的长度选择第二个选项,以及是否要为多个模型类扩展该功能。