#5216 closed (fixed)
Lazy Translation label_tag in new forms
| Reported by: | anonymous | Owned by: | anonymous |
|---|---|---|---|
| Component: | Forms | Version: | dev |
| Severity: | Keywords: | ||
| Cc: | mocksoul@…, mauro@… | Triage Stage: | Accepted |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | yes | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
A call to {{field.label_tag}} in a newforms template returns <django.utils.functional.proxy object at 0x941fe6c>
I don't know if this is the right way to handle it, but converting contents to unicode works.
Attachments (5)
Change History (22)
comment:1 by , 18 years ago
by , 18 years ago
| Attachment: | label_tag.patch added |
|---|
by , 18 years ago
| Attachment: | label_tag.2.patch added |
|---|
comment:2 by , 18 years ago
This is only covering the symptom, not fixing the problem.
Can you provide some details of your setup, please? Does it happen with the dev server? Or only with mod_python or something like that? Do you have a very short example that exhibits the problem reliably?
I have a suspicion this might be a version of #4796, but I need more details to confirm that.
comment:3 by , 18 years ago
I'm using mod_python Apache 2.2.4. I haven't used the dev server at all so I don't know if it works with that. Here is an stripped down example:
from django import newforms as forms
from django.utils.translation import ugettext_lazy as _
class ContactForm(forms.Form):
name = forms.CharField(label=_("Name:"))
email = forms.EmailField(label=_("E-mail:"))
Then in a view:
form = ContactForm(auto_id=True) return render_to_response(template_name, context_instance = RequestContext(request, 'form':form))
The template is:
{% load i18n %}
{% if form %}
<form action="{{link}}" id="mainform" method="post">
{% if sent %}
<p>{{ sent }}</p>
{% endif %}
{% for field in form %}
<p>
{% if field.label %}{{field.label_tag}}<br/>{% endif %}
{{ field }}</p>
{% if field.errors %}{{ field.errors }}{% endif %}
{% endfor %}
<p class="button"><input type="submit" value="Send" /></p>
</form>
{% endif %}
If you need more info or if something still isn't clear lmk.
comment:5 by , 18 years ago
A further note on this. If the form is redisplayed after submission (ei: there is a validation error) the label comes out fine.
comment:7 by , 18 years ago
oops, #4958 just corrects the problem in admin interface - but it suggests taht the problem may be outside of the newforms code
comment:8 by , 18 years ago
| Cc: | added |
|---|---|
| Resolution: | duplicate |
| Status: | closed → reopened |
The problem IS in newforms code.
Small represent code:
from django import newforms as forms from django.utils.translation import ugettext_lazy as _ class TestForm(forms.Form): f1 = forms.CharField(label=_('f1 label')) f2 = forms.CharField(label=_('f2_label'), widget=forms.widgets.TextInput(attrs={'id': 'my_id_f2'})) f1 = TestForm() for field in f1: print field.label_tag()
Outputs:
(gaf-uni) mocksoul@home ~/workspace/gaf-uni/repos/trunk $ python t2.py <label for="id_f1">f1 label</label> <label for="my_id_f2"><django.utils.functional.__proxy__ object at 0xb787b0ec></label>
Deep explantation:
(line 308) id_ = widget.attrs.get('id') or self.auto_id
(line 309) if id_:
(line 310) attrs = attrs and flatatt(attrs) or ''
(line 311) contents = '<label for="%s"%s>%s</label>' % (widget.id_for_label(id_), attrs, contents)
Then we use automatic id ("self.auto_id") it is in unicode, so id_ also in unicode and in line 311 all substitution params (including attrs and contents) also converted to unicode. So it forces contents.__unicode__() calling.
If user supplies id as string then id_ will be simple str and thus then expanding arguments in line 311 unicode conversation does not perfomed.
So, I think it's better to force user's label to be unicode object:
-
newforms/forms.py
304 304 """ 305 305 contents = contents or escape(self.label) 306 306 widget = self.field.widget 307 id_ = widget.attrs.get('id') or self.auto_id307 id_ = smart_unicode(widget.attrs.get('id', '')) or self.auto_id 308 308 if id_: 309 309 attrs = attrs and flatatt(attrs) or '' 310 310 contents = '<label for="%s"%s>%s</label>' % (widget.id_for_label(id_), attrs, contents)
comment:9 by , 18 years ago
| Needs tests: | set |
|---|---|
| Triage Stage: | Unreviewed → Accepted |
comment:10 by , 18 years ago
I am not sure if this is related but the symptoms are very similar. Same scenario as comment8 but using the dev server. My forms fails with the following error:
DjangoUnicodeDecodeError at /board/post 'ascii' codec can't decode byte 0xe8 in position 0: ordinal not in range(128). You passed in <django.utils.functional.__proxy__ object at 0x87fc64c> (<class 'django.utils.functional.__proxy__'>)
Patch label_tag.3.patch did not fix the problem.
With the following changes to forms.py the form is displayed (and translated) correctly.
--- forms.py 2008-05-11 00:33:29.000000000 +0900
+++ forms.py.my.original 2008-05-11 00:33:57.000000000 +0900
@@ -135,7 +135,7 @@
if errors_on_separate_row and bf_errors:
output.append(error_row % force_unicode(bf_errors))
if bf.label:
- label = escape(force_unicode(bf.label))
+ label = escape(force_unicode(bf.label.__unicode__()))
# Only add the suffix if the label does not end in
# punctuation.
if self.label_suffix:
However still fails when submitting with following error:
Traceback (most recent call last):
File "/usr/lib/python2.5/site-packages/django/core/servers/basehttp.py", line 277, in run
self.result = application(self.environ, self.start_response)
File "/usr/lib/python2.5/site-packages/django/core/servers/basehttp.py", line 631, in __call__
return self.application(environ, start_response)
File "/usr/lib/python2.5/site-packages/django/core/handlers/wsgi.py", line 205, in __call__
response = self.get_response(request)
File "/usr/lib/python2.5/site-packages/django/core/handlers/base.py", line 120, in get_response
return debug.technical_500_response(request, *exc_info)
File "/usr/lib/python2.5/site-packages/django/views/debug.py", line 74, in technical_500_response
html = get_traceback_html(request, exc_type, exc_value, tb)
File "/usr/lib/python2.5/site-packages/django/views/debug.py", line 153, in get_traceback_html
'exception_value': smart_unicode(exc_value, errors='replace'),
File "/usr/lib/python2.5/site-packages/django/utils/encoding.py", line 37, in smart_unicode
return force_unicode(s, encoding, strings_only, errors)
File "/usr/lib/python2.5/site-packages/django/utils/encoding.py", line 60, in force_unicode
raise DjangoUnicodeDecodeError(s, *e.args)
DjangoUnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 0: ordinal not in range(128). You passed in DjangoUnicodeDecodeError('ascii', '\xe8\xa8\x80\xe8\xaa\x9e\xe3\x82\x92\xe9\x81\xb8\xe6\x8a\x9e', 0, 1, 'ordinal not in range(128)') (<class 'django.utils.encoding.DjangoUnicodeDecodeError'>)
comment:11 by , 18 years ago
| Cc: | added |
|---|---|
| Owner: | changed from to |
| Status: | reopened → new |
comment:12 by , 18 years ago
The following patch solved the issues for both labels and errors, now all gets displayed and translated. (not sure if this is the right fix but it works for me, need testing) (tested on dev server only)
--- /pkgs/django-0.96-7154/django/utils/encoding.py 2008-02-26 00:18:22.000000000 +0900
+++ encoding.py 2008-05-11 01:52:14.000000000 +0900
@@ -33,7 +33,7 @@
"""
if isinstance(s, Promise):
# The input is the result of a gettext_lazy() call.
- return s
+ return s.__unicode__()
return force_unicode(s, encoding, strings_only, errors)
def force_unicode(s, encoding='utf-8', strings_only=False, errors='strict'):
comment:13 by , 17 years ago
Mauro, your problem is not the same. My patch was for labels which are returned in html as lazy gettext proxies. But without errors :).
Anyway tests and some analysis needed against current trunk.
comment:14 by , 17 years ago
| milestone: | → 1.0 |
|---|
Hey, guys! The bug is still can be easily represented in latest django trunk with little code snipped shown in comment:8.
And my 8 month old (!!) patch attachment:label_tag.3.patch still works fine with latest trunk (no tests broken). The only difference is newforms/forms.py -> forms/forms.py :). Thus, I did updaded patch for latest trunk (attachment:label_tag.4.patch against [8752]).
Please review asap, I think such things should go into 1.0, so I'm forcing milestone to 1.0. Sorry, if I'm wrong.
by , 17 years ago
| Attachment: | label_tag.5.patch added |
|---|
Django patch against [8752] with regression test.
comment:15 by , 17 years ago
I did also included regression test in attachment:label_tag.5.patch.
Without patch, test fails with following error:
======================================================================
FAIL: Doctest: regressiontests.forms.tests.__test__.regression_tests
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/mocksoul/tmp/django-label-tag/trunk/django/test/_doctest.py", line 2180, in runTest
raise self.failureException(self.format_failure(new.getvalue()))
AssertionError: Failed doctest test for regressiontests.forms.tests.__test__.regression_tests
File "/home/mocksoul/tmp/django-label-tag/trunk/tests/regressiontests/forms/tests.py", line unknown line number, in regression_tests
----------------------------------------------------------------------
File "/home/mocksoul/tmp/django-label-tag/trunk/tests/regressiontests/forms/tests.py", line ?, in regressiontests.forms.tests.__test__.regression_tests
Failed example:
print f['field_2'].label_tag()
Expected:
<label for="field_2_id">field_2</label>
Got:
<label for="field_2_id"><django.utils.functional.__proxy__ object at 0x8a4c98c></label>
With patch, of course, no error occurs.
Hope, this helps.
comment:16 by , 17 years ago
| Resolution: | → fixed |
|---|---|
| Status: | new → closed |
Sry the indentation in that first patch screwed up. This one should be better.