#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 , 17 years ago
by , 17 years ago
Attachment: | label_tag.patch added |
---|
by , 17 years ago
Attachment: | label_tag.2.patch added |
---|
comment:2 by , 17 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 , 17 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 , 17 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 , 17 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 , 17 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 , 17 years ago
Needs tests: | set |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:10 by , 17 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 , 17 years ago
Cc: | added |
---|---|
Owner: | changed from | to
Status: | reopened → new |
comment:12 by , 17 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 , 16 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 , 16 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 , 16 years ago
Attachment: | label_tag.5.patch added |
---|
Django patch against [8752] with regression test.
comment:15 by , 16 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 , 16 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Sry the indentation in that first patch screwed up. This one should be better.