my django app has a view where accounts can send out newsletter emails to its contacts and subscribers using Sendgrid's API. sending is working with a plaintext email:
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import (Mail, Subject, To, ReplyTo, SendAt, Content, From, CustomArg, Header)
def compose_email(request, send_to, *args, **kwargs):
...
if request.method == 'POST':
subject = request.POST.get('subject')
from_name = request.POST.get('from_name')
body = request.POST.get('body')
reply_to = request.POST.get('reply_to')
test_address = [request.POST.get('test_address')]
# send test email
if request.POST.get('do_test'):
if form.is_valid():
message = AccountEmailMessage(account=account, subject=subject,
from_name=from_name, destination=destination, body=body, reply_to=reply_to,
is_draft=True, is_sent=False)
message.save()
email = Mail(
subject=subject,
[email protected],
html_content=body,
to_emails=test_address,
)
email.reply_to = ReplyTo(reply_to)
try:
sendgrid_client = SendGridAPIClient(settings.SENDGRID_API_KEY)
response = sendgrid_client.send(email)
message.sendgrid_id = response.headers['X-Message-Id']
message.save()
except Exception as e:
log.error(e)
messages.success(request, 'Test message has been successfully sent')
else:
messages.error(request, 'Please, check for errors')
this works. but we want to render django object properties (model fields via template tags) in an html email template from Account (account) [assume it's just a vanilla obj req query account = Account.objects.get(id=selected_account) in the view], and I'm not clear what's the recommended docs approach.
the attempt:
if request.method == 'POST':
subject = request.POST.get('subject')
from_name = request.POST.get('from_name')
body = request.POST.get('body')
reply_to = request.POST.get('reply_to')
if request.POST.get('send'):
if form.is_valid():
message = AccountEmailMessage(account=account, subject=subject,
from_name=from_name, destination=destination, body=body, reply_to=reply_to,
is_draft=False, is_sent=True)
message.save()
rendered = render_to_string('email/newsletter.html', {
'account': account,
'protocol': settings.DEFAULT_PROTOCOL,
'domain': settings.DOMAIN,
'message_body': body
})
email = Mail(
subject=subject,
[email protected],
html_content=rendered,
to_emails=recipients,
mime_type='text/html'
)
email.reply_to = ReplyTo(reply_to)
try:
sendgrid_client = SendGridAPIClient(settings.SENDGRID_API_KEY)
response = sendgrid_client.send(email)
message.sendgrid_id = response.headers['X-Message-Id']
message.save()
except Exception as e:
log.error(e)
but on submit, this throws an err: NoReverseMatch: Reverse for 'account' not found. 'account' is not a valid view function or pattern name when I try to pass account as a kwarg to the context and render it as a string.
looking at the docs (https://github.com/sendgrid/sendgrid-python#use-cases) I see Mail() has a .dynamic_template_data property. that's very inefficient to process a large number of fields from the same obj, as well as attributes like image urls, and also requires use of legacy transactional templates (https://sendgrid.com/docs/ui/sending-email/create-and-edit-legacy-transactional-templates/). I see Sendgrid has a Personalization obj (https://sendgrid.com/docs/for-developers/sending-email/personalizations/) - is that the recommended way to implement this?
email/newsletter.html? Do you have any{% url %}tags? - Iain Shelvington