home / django_tickets / tickets

tickets: 8566

This data as json

id created changetime last_pulled_from_trac stage status component type severity version resolution summary description owner reporter keywords easy has_patch needs_better_patch needs_tests needs_docs ui_ux
8566 2008-08-26 19:35:10 2011-09-28 16:12:17 2022-03-06 03:42:35.681539 Unreviewed closed Core (Other)     dev fixed mark_safe not propagating from widgets to templates 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? nobody agirman mark_safe, safe string, escape, escaping, widgets 0 0 0 0 0 0
Powered by Datasette · Queries took 1.25ms