[Django]-Django: Odd mark_safe behaviour?

7👍

The render method of your widget is called by the BoundField.__unicode__ function, which returns SafeString instead (of a subclass of unicode.)

Many places in Django (e.g. django.template.VariableNode.render) will actually call force_unicode on the field instance itself. This will have the effect of doing unicode(instance.__unicode__()), so even though instance.__unicode__() returns a SafeString object, it will become a regular unicode object.

To illustrate, have a look at the snippet below:

from django.utils.encoding import force_unicode
from django.utils.safestring import mark_safe

class Foo(object):
    def __unicode__(self):
        return mark_safe("foo")

foo = Foo()
print "foo =", type(foo)

ufoo = unicode(foo)
print "ufoo =", type(ufoo)

forced_foo = force_unicode(foo)
print "forced_foo =", type(forced_foo)


bar = mark_safe("bar")
print "bar =", type(bar)

forced_bar = force_unicode(bar)
print "forced_bar =", type(forced_bar)

Output:

foo = <class 'testt.Foo'>
ufoo = <type 'unicode'>
forced_foo = <type 'unicode'>
bar = <class 'django.utils.safestring.SafeString'>
forced_bar = <class 'django.utils.safestring.SafeUnicode'>
👤dready

Leave a comment