Opened 18 years ago
Closed 18 years ago
#3600 closed (fixed)
Newforms label translation fails
Reported by: | Timo | Owned by: | Adrian Holovaty |
---|---|---|---|
Component: | Forms | Version: | dev |
Severity: | Keywords: | newforms translation internationalization | |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | no |
Description
Newforms' labels can be translated with gettext during initialization.
class TestForm(forms.Form): name = forms.CharField(label=capfirst(_('name')), max_length=255)
But this works only at first time. If you want to change your language during session ('/i18n/setlang/') the labels are not translated to the new language you are requesting.
Attachments (2)
Change History (10)
comment:1 by , 18 years ago
comment:2 by , 18 years ago
views.py
from django.utils.translation import gettext_lazy from django.shortcuts import render_to_response from django.template import RequestContext from django import newforms as forms class TestForm(forms.Form): first_name = forms.CharField(label=gettext_lazy('First name'), help_text=_('First name')) last_name = forms.CharField(label=gettext_lazy('Last name'), help_text=_('Last name')) def test(request): form = TestForm() return render_to_response('test.html', RequestContext(request, { 'form': form,}))
test.html
{% load i18n %} <html> <head> <title>bug</title> </head> <body> <form action="/i18n/setlang/?next=." method="get"><b>{% trans "language"%}:</b> <select onchange="this.form.submit();" name="language"> <option value="">-------</option> <option value="en">{% trans "English" %}</option> <option value="fi">{% trans "Finnish" %}</option> </select> </form> <h1>{% trans "user" %}</h1> <table> {{ form }} </table> </body> </html>
settings.py
'django.middleware.locale.LocaleMiddleware',
urls.py
(r'^i18n/', include('django.conf.urls.i18n')),
by , 18 years ago
Attachment: | newforms_translation_fix.patch added |
---|
Newforms label and help_text translation patch
comment:3 by , 18 years ago
Has patch: | set |
---|---|
Needs tests: | set |
by , 18 years ago
Attachment: | newforms_translation_fix_tests.patch added |
---|
Test which fails before the above patch and succeeds with it
comment:4 by , 18 years ago
Needs tests: | unset |
---|
The tests patch above adds a single simple test case for forms field with translated labels.
comment:5 by , 18 years ago
Triage Stage: | Unreviewed → Ready for checkin |
---|
comment:6 by , 18 years ago
Patch needs improvement: | set |
---|---|
Triage Stage: | Ready for checkin → Accepted |
I'm not happy with this patch. It fixes the symptom, but not the cause of the problem. We want to be turning things into unicode as early as possible, so doing it in the Field class is the right thing. Moving the unicode conversion until later is inconsistent and leaves us with multiple encodings floating around internally -- something we are trying to slowly get rid of. A better fix is to work out why we aren't then translating that unicode value, which is, I suspect a deeper problem.
This is a genuine bug and the test case is good to have, but it isn't the right fix. I want to dig a bit deeper into this before committing anything.
comment:7 by , 18 years ago
It is good idea to put unicode to Field class!
I have tried to underestand that translation problem. I have noticed if I create new instance from SomeForm class only at first time it defines 'base_fields'. Now if you have some "dynamic" data in form class for example: translation, choices etc, all Fields datas will be generate to "static". Once a new instance from SomeForm is created base_fields are copied and their "old" data is used while generating data to create new form fields.
Test case for ChoiceField dymanic data
from django.db import models class City(models.Model): name = models.CharField(maxlength=100) form_tests = r""" >>> from django.newforms import * >>> def get_all_cities(): ... for i in City.objects.all(): ... yield (i.id, i.name) >>> c = City.objects.create(name="Helsinki") >>> c.save() >>> c = City.objects.create(name="Lahti") >>> c.save() >>> class CityForm(Form): ... cities = ChoiceField(choices=get_all_cities()) >>> f = CityForm() >>> print f.as_p() <p><label for="id_cities">Cities:</label> <select name="cities" id="id_cities"> <option value="1">Helsinki</option> <option value="2">Lahti</option> </select></p> >>> c = City.objects.create(name="London") >>> c.save() >>> print [(city) for city in get_all_cities()] [(1, 'Helsinki'), (2, 'Lahti'), (3, 'London')] >>> f = CityForm() >>> print f.as_p() <p><label for="id_cities">Cities:</label> <select name="cities" id="id_cities"> <option value="1">Helsinki</option> <option value="2">Lahti</option> <option value="3">London</option> </select></p> """ __test__ = { 'form_tests': form_tests, } if __name__ == "__main__": import doctest doctest.testmod()
comment:8 by , 18 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Problem is the same if you use gettext_lazy