1

I have made an api for submitting a contact form in my application. Whenever the form gets submitted i want it to send that details to myself through email. Here is my code what i am using:

models.py

class Contact(models.Model):
    name = models.CharField(max_length=255)
    email = models.EmailField(max_length=254)
    phone = models.CharField(max_length=20)
    message = models.TextField()

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'contact'

views.py

from rest_framework.generics import (
    CreateAPIView,
)
from .serializers import (
    ContactCreateSerializer
)
class ContactCreateApiView(CreateAPIView):
    queryset = Contact.objects.all()
    serializer_class = ContactCreateSerializer

serializers.py

class ContactCreateSerializer(ModelSerializer):
class Meta:
    model = Contact
    fields = [
        'name',
        'email',
        'phone',
        'message',
    ]

def send_email(self):
    name = self.cleaned_data.get('name')
    from_email = self.cleaned_data.get('email')
    phone = self.cleaned_data.get('phone')
    subject = 'Contact Form Info from App'
    message = self.cleaned_data.get('message')
    to_email = settings.EMAIL_HOST_USER

    context = {
        'name': name,
        'email': from_email,
        'phone': phone,
        'message': message,
    }
    plaintext = get_template('emails/contact_form_email.txt')
    htmly = get_template('emails/contact_form_email.html')
    text_content = plaintext.render(context)
    html_content = htmly.render(context)

    message = EmailMultiAlternatives(
        subject=subject, 
        body=text_content, 
        from_email=from_email, 
        to=[to_email],
        cc=[],
        bcc=[]    
    )
    message.attach_alternative(html_content, "text/html")
    message.send()

def save(self, commit=True):
    instance = super().save(commit)
    self.send_email()  # there you send the email when then model is saved in db
    return instance

I tried this but it gives me error

save() takes 1 positional argument but 2 were given

What should i do?

3
  • Welcome to SO. While we're all happy to help with real problems, we're not here to to your job for free, and you are expected to do some research by yourself first. Sending mails from Django is quite extensively documented, with lot of example, so there's really no reason to ask such a question here. If you actually tried something and had issues, please edit your post to explain what you did and how exactly it didn't work (including error messages and the full traceback). Commented Jan 4, 2019 at 10:11
  • @brunodesthuilliers See i have updated the post Commented Jan 4, 2019 at 10:56
  • You forgot to include the full traceback - the error message by itself is not enough to know where the problem comes from. But from your code it seems like you've copy-pasted some code that was written for a ModelForm, while your cass is a drf ModelSerializer - and if you look are DRF source code, ModelSerializer.save doesn't take any positional argument indeed. Code snippets are useful examples, but you stil have to understand them and the context in which they are used, just copy-pasting some code out of context is only going to get you such problems. Commented Jan 4, 2019 at 14:22

1 Answer 1

3

There are many ways to do that. One of them is to override the create method of the ModelSerializer:

from django.core.mail import send_mail


class ContactCreateSerializer(ModelSerializer):
    class Meta:
        model = ContactForm
        fields = [
            'name',
            'email',
            'phone',
            'message',
        ]

     def create(self, validate_data):
        instance = super(ContactCreateSerializer, self).create(validate_data)
        send_mail(
            'Instance {} has been created'.format(instance.pk),
            'Here is the message. DATA: {}'.format(validate_data),
            '[email protected]',
            ['[email protected]'],
            fail_silently=False,
        )
        return instance
      

For more details on sending email, please check this documentation.

FYI: Please change your Model Name from ContactForm to Contact. Because its a model, not a form. And to be honest. You don't need to store contact information. You can do it like this:

from django.core.mail import send_mail
from rest_framework import serializers, status, views
from rest_framework.response import Response


class ContactSerializer(serializers.Serializer):
    name = serializers.CharField()
    email = serializers.EmailField()
    # add other fields


class ContactView(views.APIView):
    def post(self, request, *args, **kwargs):
        serializer = ContactSerializer(request.data)
        if serializer.is_valid():
            data = serializer.validated_data
            email = data.get('email')
            name = data.get('name')
            send_mail(
                'Sent email from {}'.format(name),
                'Here is the message. {}'.format(data.get('message')),
                email,
                ['[email protected]'],
                fail_silently=False,
            )
            return Response({"success": "Sent"})
        return Response({'success': "Failed"}, status=status.HTTP_400_BAD_REQUEST)
Sign up to request clarification or add additional context in comments.

6 Comments

the mail protocol is highly unreliable - the fact the mail was "sent" doesn't garantee it will actually reach it's destination - so saving contact forms data is always a good idea (if those are of any interest to you of course - but else why bother having a contact form ?)
I agree with you. But having both emails and storing data is kind of redundant, isn't it?
@ruddra The Answer worked for me, thanks and i know that it would be redundant to have both email and stored data. I am doing that because in future i would need that data, instead of searching those mails i will directly go to my database and and export.
@ruddra no it's not - the point is that there is absolutely NO garantee you will ever get the email, so storing the contact data ensure it won't get lost.
I am sorry this is an old question. But how do you pass data from serializer to email template?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.