用变量替换文本

时间:2011-11-16 18:07:38

标签: python django django-models django-views

我必须向某些客户发送信件,我有一份标准信件,我需要使用。我想用变量替换消息正文中的一些文本。

这是我的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)

现在身体的价值是:

  

亲爱的[primary-firstname],

     

重要的提醒......

     

你[产品]在[maturity_date]与[金融机构]成熟。

     

现在我想用模板变量替换括号中的所有内容。

到目前为止,这是我在views.py中的内容:

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

现在如果我循环浏览sel_inv我可以访问sel_inv.maturity_date等,但我对如何替换文本感到迷茫。

在我的模板上,到目前为止我只有:

{% if show_letter %}
{{ mat_letter.body }} <br/>
{{ mat_letter.footer }}
{% endif %}

非常感谢。

4 个答案:

答案 0 :(得分:4)

使用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!

答案 1 :(得分:2)

我认为这是最好的方法。首先,您有一个包含模板的文件,例如:

Dear {{primary-firstname}},
AN IMPORTANT REMINDER…
You have a {{product}} that is maturing on {{maturity_date}} with {{financial institution}}.
etc ...

因此,您的观点将类似于:

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 ...

所以如果你print message,你会得到:

Dear Mr. Johnson,
AN IMPORTANT REMINDER…
You have a banana that is maturing on 11-17-2011 with something else.
etc ...

答案 2 :(得分:0)

一种解决方案是在主体上使用Django的模板引擎(就像渲染页面时一样)。如果文本可由用户等编辑,我确信存在安全隐患。

更简单的解决方案是简单的字符串替换。例如,鉴于您的上述内容:

for var, value in sel_inv.items:
    body = body.replace('[%s]' % var, value)

这不是最漂亮的解决方案,但如果您的身体模板已修复,则需要执行此类操作。

答案 3 :(得分:-1)

您可以使用回调使用正则表达式替换。这个优于简单的字符串替换或使用django的模板引擎的优点是你也知道何时使用未定义的变量(因为你可能不想发送这样的字母/电子邮件:)

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)