Search code examples
pythondjangosendgrid-api-v3

Error because object attribute does not exist, except it does


I am trying to send an email using the SendGrid python API. In order to do so I use this function:

def send_contact_us_email(sender=None, name=None, subject=None, message=None):
status_code = None
if sender and name and subject and message:
    to = "test@test.com"
    email = Email.objects.create(to=to, sender=sender, subject=subject, content=message)
    status_code = email.send()

return status_code

So I use an Email model to store emails for later potential reference and so that the code for sending an email can be put in the model. Here is the Email model:

from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import *

sg = SendGridAPIClient(apikey=getattr(settings, 'SENDGRID_API_KEY'))

class Email(models.Model):
    to = models.EmailField(max_length=100)
    sender = models.EmailField(max_length=100)
    subject = models.CharField(max_length=100)
    content = models.TextField()

    def __str__(self):
        return 'to: {to} from: {sender}'.format(to=self.to, sender=self.sender)

    def send(self):
        if self.to and self.sender and self.subject and self.content:
            to_email = Email(self.to)
            from_email = Email(self.sender)
            content = Content("text/html", self.content)
            mail = Mail(from_email, self.subject, to_email, content)
            response = sg.client.mail.send.post(request_body=mail.get())
            return response.status_code
        return 600 # incomplete information, cannot send email.

When I run this code I expect it to work fine; I create an email model object with all required data to send an email and then use the sendgrid helper classes to construct a JSON request body for the SendGrid API to handle.

However, I get the following error:

AttributeError at /contact-us/
'Email' object has no attribute 'get'
Request Method: POST
Request URL:    http://127.0.0.1:8000/contact-us/
Django Version: 1.11.13
Exception Type: AttributeError
Exception Value:    
'Email' object has no attribute 'get'
Exception Location: /Users/tomfinet/Desktop/royaleaccounts/env/lib/python2.7/site-packages/sendgrid/helpers/mail/personalization.py in add_to, line 39
Python Executable:  /Users/tomfinet/Desktop/royaleaccounts/env/bin/python
Python Version: 2.7.15
Python Path:    
['/Users/tomfinet/Desktop/royaleaccounts/env/source',
 '/Users/tomfinet/Desktop/royaleaccounts/env/lib/python27.zip',
 '/Users/tomfinet/Desktop/royaleaccounts/env/lib/python2.7',
 '/Users/tomfinet/Desktop/royaleaccounts/env/lib/python2.7/plat-darwin',
 '/Users/tomfinet/Desktop/royaleaccounts/env/lib/python2.7/plat-mac',
 '/Users/tomfinet/Desktop/royaleaccounts/env/lib/python2.7/plat-mac/lib-scriptpackages',
 '/Users/tomfinet/Desktop/royaleaccounts/env/lib/python2.7/lib-tk',
 '/Users/tomfinet/Desktop/royaleaccounts/env/lib/python2.7/lib-old',
 '/Users/tomfinet/Desktop/royaleaccounts/env/lib/python2.7/lib-dynload',
 '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7',
 '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-darwin',
 '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk',
 '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac',
 '/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/plat-mac/lib-scriptpackages',
 '/Users/tomfinet/Desktop/royaleaccounts/env/lib/python2.7/site-packages']
Server time:    Fri, 7 Sep 2018 23:04:16 +0000
Traceback Switch to copy-and-paste view
/Users/tomfinet/Desktop/royaleaccounts/env/lib/python2.7/site-packages/django/core/handlers/exception.py in inner
            response = get_response(request) ...
▶ Local vars
/Users/tomfinet/Desktop/royaleaccounts/env/lib/python2.7/site-packages/django/core/handlers/base.py in _get_response
                response = self.process_exception_by_middleware(e, request) ...
▶ Local vars
/Users/tomfinet/Desktop/royaleaccounts/env/lib/python2.7/site-packages/django/core/handlers/base.py in _get_response
                response = wrapped_callback(request, *callback_args, **callback_kwargs) ...
▶ Local vars
/Users/tomfinet/Desktop/royaleaccounts/env/source/royaleaccounts/views.py in contact_view
        status_code = send_contact_us_email(sender, name, subject, message) ...
▶ Local vars
/Users/tomfinet/Desktop/royaleaccounts/env/source/emails/utils.py in send_contact_us_email
        status_code = email.send() ...
▶ Local vars
/Users/tomfinet/Desktop/royaleaccounts/env/source/emails/models.py in send
            mail = Mail(from_email, self.subject, to_email, content) ...
▶ Local vars
/Users/tomfinet/Desktop/royaleaccounts/env/lib/python2.7/site-packages/sendgrid/helpers/mail/mail.py in __init__
            personalization.add_to(to_email) ...
▶ Local vars
/Users/tomfinet/Desktop/royaleaccounts/env/lib/python2.7/site-packages/sendgrid/helpers/mail/personalization.py in add_to
        self._tos.append(email.get()) ...
▶ Local vars

Email object has no attribute get

However, when I look at the sendgrid helper classes the email class does have a get attribute:

def get(self):
    """
    Get a JSON-ready representation of this Email.

    :returns: This Email, ready for use in a request body.
    :rtype: dict
    """
    email = {}
    if self.name is not None:
        email["name"] = self.name

    if self.email is not None:
        email["email"] = self.email
    return email

Therefore I am stuck unable to resolve this error, what am I missing?


Solution

  • Turns out when I wrote Email(self.sender) and stuff, it was using my model not the helper Email class written by sendgrid. So just import Email from sendgrid as Emaill or something different.

    from sendgrid.helpers.mail import Email as Emaill