如何重写Django模型保存方法?

时间:2018-01-09 07:21:42

标签: python django

如何重写Django模型保存方法?

class Message(models.Model):
    """
    message
    """
    message_num = models.CharField(default=getMessageNum, max_length=16)  

    title = models.CharField(max_length=64)
    content = models.CharField(max_length=1024)

    def save(self, force_insert=False, force_update=False, using=None,
         update_fields=None):
        # I want send email there
        pass

我的意思是,在Django模型中,如果我创建实例成功,我想调用一个函数,比如在函数中发送一封电子邮件。

我在Django模型中发现了一个save方法。我不确定是否应该编写其他代码,因为有很多参数。

我的意思是我是否应该关心我的发送电子邮件逻辑?

3 个答案:

答案 0 :(得分:3)

当您覆盖save方法时,您仍然必须确保它实际上保存了实例。您只需通过save

调用父类“super即可
class Message(models.Model): 
    # ...
    def save(self, *args, **kwargs):
        # this will take care of the saving
        super(Message, self).save(*args, **kwargs)
        # do email stuff  
        # better handle ecxeptions well or the saving might be rolled back

您还可以将邮件发送到post_save(或pre_save,具体取决于您的逻辑)信号。是否要以这种方式将一个或另一个分开,取决于这两个动作的联系程度,以及您的品味。

覆盖save可让您选择干预保存过程,例如您可以根据邮件发送是否成功来更改字段的值,或者根本不保存实例。

答案 1 :(得分:2)

您要执行的操作的解决方案是使用Django Signals。通过使用信号,您可以将代码挂钩到创建和保存模型时,而无需重写保存方法,从而以更好的方式保持代码和逻辑的分离,显然模型不需要知道电子邮件,例如

如何使用Signals的一个例子就是简单地执行以下操作:

from django.db.models.signals import pre_save
from django.dispatch import receiver
from myapp.models import MyModel

@receiver(pre_save, sender=MyModel)
def my_handler(sender, **kwargs):
    # Code to execute whenever MyModel is saved...

如果您仍想覆盖save()方法,可以使用Python super()方法执行此操作(docs)。

class MyModel(models.Model):
    def save(self, *args, **kwargs):
        # This will call the parent method that you are overriding
        # so it will save your instance with the default behavior.
        super(MyModel, self).save(*args, **kwargs)

        # Then we add whatever extra code we want, e.g. send email...
        Messenger.send_email()

答案 2 :(得分:1)

保存信息后,您需要激活信号。这意味着,当您的消息被保存时,django将发出如下信号:

from django.db.models.signals import post_save
from django.dispatch import receiver

class Message(models.Model):
    # fields...

# method for sending email
@receiver(post_save, sender=Message, dispatch_uid="send_email")
def send_email(sender, instance, **kwargs):
    # your email send logic here..

您可以将信号放在app文件夹中的signals.py文件中,并确保将其导入应用程序配置文件中,如下所示:

message/apps.py

from django.apps import AppConfig

class MyAppConfig(AppConfig):
    name = 'message'

    def ready(self):
        import message.signals

并按如下方式更新init文件:

message/__init__.py

default_app_config = 'message.apps.MyAppConfig'