Django, forms y ugettext: "TypeError: Lazy object returned unexpected type."

written by uve 7 January 2011

Estaba programando tranquilamente un formulario (ModelForm) y de repente deja de renderizarse. Reviso la vista, el código de retorno, el HTML de salida... pero todo está correctamente salvo que el formulario no se visualiza.

El código es el siguiente:

models.py

from django.db import models
from django.utils.translation import ugettext_lazy as _

class MiModelo(models.Model):
    ...
    campo = models.CharField(_(u''), ...)

forms.py:

from django import forms

class MiForm(forms.ModelForm):
    class Meta:
        model = MiModelo

Aparentemente todo está bien. Pero al ejecutar desde el shell (python manage.py shell) y tratar de renderizar el formulario me encuentro con el error:

TypeError: Lazy object returned unexpected type.

Aquí os dejo la traza, por si alguien está interesado:

In [1]: from forms import MiForm
In [2]: form = MiForm()
In [3]: form.as_table()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

/usr/lib/pymodules/python2.7/django/forms/forms.pyc in as_table(self)
    215             row_ender = u'</td></tr>',
    216             help_text_html = u'<br />%s',
--> 217             errors_on_separate_row = False)
    218
    219     def as_ul(self):

/usr/lib/pymodules/python2.7/django/forms/forms.pyc in _html_output(self, normal_row, error_row, row_ender, help_text_html, errors_on_separate_row)
    159                     output.append(error_row % force_unicode(bf_errors))
    160
--> 161                 if bf.label:
    162                     label = conditional_escape(force_unicode(bf.label))
    163                     # Only add the suffix if the label does not end in

/usr/lib/pymodules/python2.7/django/utils/functional.pyc in __wrapper__(self, *args, **kw)
    195                     if t in self.__dispatch:
    196                         return self.__dispatch[t][funcname](res, *args, **kw)
--> 197                 raise TypeError("Lazy object returned unexpected type.")
    198
    199             if klass not in cls.__dispatch:

TypeError: Lazy object returned unexpected type.

Bueno, ¿dónde está el error? Es simple, el problema viene derivado de utilizar ugettext_lazy y no haber especificado nombre al campo. Es decir, si cambiamos:

campo = models.CharField(_(u''),...)

por

campo = models.CharField(_(u'Mi campo'),...)

ó:

campo = models.CharField('',...)

Todo funciona perfectamente. No es la primera vez que tengo problemas con este tipo de cosas. Recomiendo a quien programe con Django, siempre que vea un problema con 'Lazy object' automáticamente piense en settings o ugettext_lazy :)

Tags

La teoría es cuando crees saber algo, pero no funciona.
La práctica es cuando algo funciona, pero no sabes por qué.
Los programadores combinan la teoría y la práctica:
Nada funciona y no saben por qué.