Reputation: 3288
I have to send out letters to certain clients and I have a standard letter that I need to use. I want to replace some of the text inside the body of the message with variables.
Here is my maturity_letter models.py
class MaturityLetter(models.Model):
default = models.BooleanField(default=False, blank=True)
body = models.TextField(blank=True)
footer = models.TextField(blank=True)
Now the body has a value of this:
Dear [primary-firstname],
AN IMPORTANT REMINDER…
You have a [product] that is maturing on [maturity_date] with [financial institution].
etc
Now I would like to replace everything in brackets with my template variables.
This is what I have in my views.py so far:
context = {}
if request.POST:
start_form = MaturityLetterSetupForm(request.POST)
if start_form.is_valid():
agent = request.session['agent']
start_date = start_form.cleaned_data['start_date']
end_date = start_form.cleaned_data['end_date']
investments = Investment.objects.all().filter(maturity_date__range=(start_date, end_date), plan__profile__agent=agent).order_by('maturity_date')
inv_form = MaturityLetterInvestments(investments, request.POST)
if inv_form.is_valid():
sel_inv = inv_form.cleaned_data['investments']
context['sel_inv'] = sel_inv
maturity_letter = MaturityLetter.objects.get(id=1)
context['mat_letter'] = maturity_letter
context['inv_form'] = inv_form
context['agent'] = agent
context['show_report'] = True
Now if I loop through the sel_inv
I get access to sel_inv.maturity_date
, etc but I am lost in how to replace the text.
On my template, all I have so far is:
{% if show_letter %}
{{ mat_letter.body }} <br/>
{{ mat_letter.footer }}
{% endif %}
Much appreciated.
Upvotes: 0
Views: 461
Reputation: 24921
I think this is the best way to do it. First, you have a file with your template, something like:
Dear {{primary-firstname}},
AN IMPORTANT REMINDER…
You have a {{product}} that is maturing on {{maturity_date}} with {{financial institution}}.
etc ...
So, your view will go something like:
from django.template.loader import render_to_string
# previous code ...
template_file = 'where/is/my/template.txt'
context_data = {'primary-firstname': 'Mr. Johnson',
'product': 'banana',
'maturity_date': '11-17-2011',
'financial institution': 'something else'}
message = render_to_string(template_file, context_data)
# here you send the message to the user ...
So if you print message
you'll get:
Dear Mr. Johnson,
AN IMPORTANT REMINDER…
You have a banana that is maturing on 11-17-2011 with something else.
etc ...
Upvotes: 2
Reputation: 41
You can use regular expression substitution with a callback. The advantage of this over a simple string replace or using django's template engine is that you also know when undefined variables are used (since you might not want to send out letters/emails like that :)
import re
body = """
Dear [primary-firstname],
AN IMPORTANT REMINDER...
You have a [product] that is maturing on [maturity_date]
with [financial institution].
etc
"""
def replace_cb(m):
replacements = {'primary-firstname': 'Gary',
'product': 'Awesome-o-tron2k',
'maturity_date': '1-1-2012',
'financial institution': 'The bank'}
r = replacements.get(m.groups()[0])
if not r:
raise Exception('Unknown variable')
return r
new_body = re.sub('\[([a-zA-Z-_ ]+)\]', replace_cb, body)
Upvotes: -1
Reputation: 8147
use format strings:
>>> print "today is %(date)s, im %(age)d years old!" % {"date":"my birthday!","age":100}
today is my birthday!, im 100 years old!
Upvotes: 4
Reputation: 32497
One solution is to use Django's template engine on the body itself (as you do when rendering the page). I am sure there are security implications if the text is editable by users etc.
A simpler solution would be simple string replacement. For example, given what you have above:
for var, value in sel_inv.items:
body = body.replace('[%s]' % var, value)
It's not the prettiest solution, but if your body template is fixed you need to do something like this.
Upvotes: 0