Django

Code

Ticket #8566 (closed: fixed)

Opened 3 months ago

Last modified 3 months ago

mark_safe not propagating from widgets to templates

Reported by: agirman Assigned to: nobody
Milestone: 1.0 Component: Core framework
Version: SVN Keywords: mark_safe, safe string, escape, escaping, widgets
Cc: Triage Stage: Unreviewed
Has patch: 0 Needs documentation: 0
Needs tests: 0 Patch needs improvement: 0

Description (Last modified by jacob)

I submitted the below to Django Users and Malcolm Tredinnick suggested I open a ticket. Essentially, when making custom widgets, I encountered a problem wherein despite marking things as safe strings, when I tried to render my forms in a template, they were beings escaped. Turning off auto escaping and piping to the safe filter weren't working, and I found that they were being escaped at a very low level. Namely, there is a call in the Widget.render function to django.forms.util.flatatt that is escaping everything. I don't know if this by design or not, but given the number of calls to mark_safe in the Widget module, I suspect not. It is preventing me from, for example, making JS function calls in widgets that require string arguments. I hope this helps.

Regards,

Alex.

====

Hi there,

I have been trying to get a function call into a widget argument, but have not been able to at the template level, because it would appear that my safe_strings are being escaped somewhere down in the framework. I have created a widget and mark_safe'd an attribute value, but no matter what, since it's pre-escaped by the time it bubbles up to the template level, I can't not escape it (well... I could use an html library to de-escape it, but that seems kludgy).

I've traced the execution and found the culprit to be the django.forms.util.flatatt function. That is:

from django import forms
from django.utils.safestring import mark_safe

class MyWidget(forms.TextInput):
    def __init__(self, *args, **kwargs):
        attrs = kwargs.setdefault('attrs', {})
        attrs['safe_string'] = mark_safe("will o' the wisp")
        attrs['normal_string'] = "cat o' nine tails"
        super(MyWidget, self).__init__(*args, **kwargs)

w = MyWidget()
w.render("field_name", "")

#=> u'<input normal_string="cat o&#39; nine tails" type="text"
name="field_name" safe_string="will o&#39; the wisp" />'

You can see that both the unsafe and safe strings were escaped. I don't know if this is intentional or not, but it prevents me from making something like:

<input type="text" onBlur="myFunction('string_arg')">

because it is always escaping my single-quotes. Is this the desired behavior? Anyway, like I said, the culprit is:

# django.forms.util

def flatatt(attrs):

"""
    Convert a dictionary of attributes to a single
string.
    The returned string will contain a leading space followed by
key="value",
    XML-style pairs.  It is assumed that the keys do not need to be
XML-
escaped.
    If the passed dictionary is empty, then return an empty
string.
    """
    return u''.join([u' %s="%s"' % (k, escape(v)) for k, v in
attrs.items()])  # <-- right there, the escape(v) call... should this
be conditional_escape?

Since there are a lot of calls to mark_safe scattered through the widget and form-level calls used in rendering, I assume you're meant to be able to mark something as safe down here and have it get to the top level unaltered... no?

Attachments

Change History

08/26/08 14:37:45 changed by agirman

  • needs_better_patch changed.
  • needs_tests changed.
  • needs_docs changed.

Alright, I should have previewed. Here is the code in a code block:

class MyWidget(forms.TextInput):
    def __init__(self, *args, **kwargs):
        attrs = kwargs.setdefault('attrs', {})
        attrs['safe_string'] = mark_safe("will o' the wisp")
        attrs['normal_string'] = "cat o' nine tails"
        super(MyWidget, self).__init__(*args, **kwargs)

w = MyWidget()
w.render("field_name", "")
#=> u'<input normal_string="cat o&#39; nine tails" type="text"
name="field_name" safe_string="will o&#39; the wisp" />'

08/26/08 16:14:00 changed by jacob

  • description changed.

(fixed formatting)

08/26/08 16:32:18 changed by mtredinnick

  • status changed from new to closed.
  • resolution set to fixed.

(In [8601]) Fixed #8566 -- Allow safe-strings in the "attrs" parameter to form widgets.


Add/Change #8566 (mark_safe not propagating from widgets to templates)




Change Properties
Action