Reputation: 13
I got to know that we can override create method in order to send email but it's not working with my code.
views.py:
class FileUploadView(APIView):
parser_class = (MultiPartParser,)
def post(self, request, *args, **kwargs):
file_serializer = FileSerializer(data=request.data)
if file_serializer.is_valid():
file_serializer.save()
return Response(file_serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(file_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def create(self, request, *args, **kwargs):
response = super(FileUploadView, self).create(request, *args, **kwargs)
send_email() # sending mail
return response
def send_email(request):
email = EmailMessage(
'Title',
(FileSerializer.Fullname, FileSerializer.Email, FileSerializer.Contact),
'[email protected]',
['[email protected]']
)
email.attach_file(FileSerializer.Upload)
email.send()
Help me in figuring out what's the problem here
Edit: APIView
doesn't support create method, above code doesn't work
. I want to send the contents received from post method from rest API through a mail. Suggest me a proper method in order to do it with respect to above code.
Upvotes: 0
Views: 355
Reputation: 659
APIView
does not supportcreate
You have got this part right. You want to send an email after the model object has been saved to database. Actually there are several ways to do that. You can do it from view, you can do it from your serializer, you can do it from your model, you can do it from a post_save
signal hooked to your model. I am going to show you what was wrong with your code and then some of the other ways -
send_email
function just after file_serializer.save()
in your FileUploadView.post
class FileUploadView(APIView):
parser_class = (MultiPartParser,)
def post(self, request, *args, **kwargs):
file_serializer = FileSerializer(data=request.data)
if file_serializer.is_valid():
file_serializer.save()
send_email() #sending Email
return Response(file_serializer.data, status=status.HTTP_201_CREATED)
else:
return Response(file_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def send_email(request):
email = EmailMessage(
'Title',
(FileSerializer.Fullname, FileSerializer.Email, FileSerializer.Contact),
'[email protected]',
['[email protected]']
)
email.attach_file(FileSerializer.Upload)
email.send()
send_email
function from view, but this view is a bit different. This view inherits from generics.CreateAPIView
from rest_framework import generics
class FileUploadView(generics.CreateAPIView):
serializer_class = FileUploadSerializer
parser_class = [MultiParser, ]
queryset = FileUploadModel.objects.all()
def perform_create(self, serializer):
serializer.save()
send_email()
send_email
function from the create
method of your seiralizer. You can override serializer.create
methodclass FileUploadSerializer(serializers.ModelSerializer):
class Meta:
model = FileUploadModel
fields = ['your', 'model', 'fields']
def create(self, validated_data):
instance = super(FileUploadSerializer, self).create(validated_data)
send_email()
return instance
FileUploadModel
model class. Here you override the save
method of the modelclass FileUploadModel(models.Model):
...your model fields definition...
def save(self, *args, **kwargs):
if not self.pk: #assuming we want to send email only when object is created first time in database
send_email()
super(FileUploadModel, self).save(*args, **kwargs)
On catch about overriding model.save
method is that, it will not be called when you're performing bulk operations. Also it will be called every time you save the model i.e. both create and update that's why we added the pk
check. This logic will send email before the object is inserted in your database if you want to send email only when the object is completely saved in database then do the following way with signals
post_save
signal to your model. In this way you send an email only after the object is saved in databasefrom django.db.models.signals import post_save
from django.dispatch import receiver
@receiver(post_save, sender=FileUploadModel)
def file_upload_post_save(sender, instance, **kwargs):
send_email()
Catch with using signals is that it will not be called when you do bulk operation.
I am assuming you're fairly new to the django enviornment. You should also have a look on celery to perform long running background tasks such as - sending emails.
Upvotes: 2