Trey Hunner
Trey Hunner

Reputation: 11814

HTML-escaping replacement fields when using str.format() in Python

I am using the string .format() function to format my strings with keyword arguments. I pass in some basic objects to the strings and use attributes of these objects in the strings. For example:

"Hello, {user.first_name}!".format(user=my_user)

These strings may be used in HTML e-mails, so the replacement fields should be HTML-escaped (using django.utils.html.escape).

What is the best way to use an escape function for string replacement fields when formatting a string? If this is not reasonably possible, what is an appropriate alternative to string formatting? My strings are being stored in a database and modified through the Django admin interface.

Upvotes: 1

Views: 1594

Answers (2)

milkypostman
milkypostman

Reputation: 3043

Well, the question is why you are using format to begin with. Aren't you going to push this to a template? I mean, if you escape something in your template (using a template tag) you're pretty much just passing a string through this escape function.

Maybe this isn't what you're looking for but would't you just do,

"Hello, {user.first_name}!".format(user=django.utils.html.escape(my_user))

?

If you wanted to escape all your arguments and you were sure they would be strings,

def foo(**kwargs):
    for key,val in kwargs.iteritems():
        kwargs[key] = django.utils.html.escape(val)

    ...

You could also probably do something a little more crazy like,

def foo(**kwargs):
    kwargs = dict((key, val) for key,val in izip(kwargs.iterkeys(), \
    map(django.utils.htmls.escape, kwargs.itervalues())))

    # OR if you use Python 3
    kwargs = {key:django.utils.htmls.escape(val) for key, val in kwargs.items()}

if you wanted stuff to get CRAZY!

Upvotes: 1

Trey Hunner
Trey Hunner

Reputation: 11814

As a temporary solution before I move to using Django templates, I subclassed string.Formatter as mentioned in the documentation.

import string
from django.utils.html import escape

class EscapingFormatter(string.Formatter):
    def format_field(self, value, format_spec):
        return escape(super(EscapingFormatter, self).format_field(value, format_spec))

formatter = EscapingFormatter()
formatter.format("Hello, {user.first_name}!", user=my_user)

This solution should work outside of Django as well (the escape function will obviously need to be replaced though).

Upvotes: 0

Related Questions