如何重写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
方法。我不确定是否应该编写其他代码,因为有很多参数。
我的意思是我是否应该关心我的发送电子邮件逻辑?
答案 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'