Reputation: 385
How to rewrite the Django model save method?
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
I mean, in the Django model, if I create instance success, I want to call a function, such as send a email in the function.
I find in the Django model have a save
method. I am not sure whether should write other code, because there are so many params.
I mean whether I only should care about my send email logic?
Upvotes: 0
Views: 3225
Reputation: 3061
You need to activate signal once your message is saved. That means, when your message is saved, django will issue signal as follows:
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..
You can put your signals in signals.py
file inside your app folder and make sure to import that in your application config file as follows:
message/apps.py
from django.apps import AppConfig
class MyAppConfig(AppConfig):
name = 'message'
def ready(self):
import message.signals
And update init file as follows:
message/__init__.py
default_app_config = 'message.apps.MyAppConfig'
Upvotes: 2
Reputation: 73498
When you override the save
method, you still have to make sure that the it actually saves the instance. You can do that by simply calling the parent class' save
via 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
You can also connect the mail sending to the post_save
(or pre_save
, depending on your logic) signal. Whether you want to separate one orm the other in that way depends on how closely the two actions are linked and a bit on your taste.
Overriding save
gives you the option to intervene in the saving process, e.g. you can change the value of fields based on whether the mail sending was successful or not save the instance at all.
Upvotes: 6
Reputation: 11470
The solution to what you want to do is to use Django Signals. By using Signals you can hook code to when a model is created and saved without having to rewrite the save method, that keep the separation of code and logic in a much nicer way, obviously the model does not need to know about the emails for example.
An example of how to use Signals would be to simply do the following:
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...
If you still want to override the save()
method you can use the Python super()
method to do so (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()
Upvotes: 4