I will look into this, something that should be <utf8 appears to be unicode. Meanwhile make sure the page layout has a head meta encoding set to utf8
On 15 Ago, 17:33, Luis Díaz <diazluis2...@gmail.com> wrote: > failure > > I have the following model: > > db.define_table('race', > Field('name', 'string', length=32, default='', unique=True, > ondelete='CASCADE', label='Race'), > format='%(name)s' > ) > db.race.name.requires = [ > IS_NOT_IN_DB(db, db.race.name), > IS_LENGTH(maxsize=32, minsize=3) > ] > > when I try to add a race where the word this asentuada. gives me error > web2py commented that I am running in local mode and EAG > > details of the problem: > > Error traceback > > 1. > 2. > 3. > 4. > 5. > 6. > 7. > 8. > 9. > 10. > 11. > 12. > 13. > 14. > 15. > 16. > 17. > 18. > 19. > 20. > 21. > 22. > 23. > 24. > 25. > 26. > 27. > 28. > 29. > 30. > 31. > > Traceback (most recent call last): > File "C:\google_appengine\web2py\gluon\restricted.py", line 186, in > restricted > exec ccode in environment > File > "C:\google_appengine\web2py\applications\welcome2/controllers/appadmin.py:insert", > line 410, in <module> > File "C:\google_appengine\web2py\gluon\globals.py", line 96, in <lambda> > self._caller = lambda f: f() > File > "C:\google_appengine\web2py\applications\welcome2/controllers/appadmin.py:insert", > line 125, in insert > File "C:\google_appengine\web2py\gluon\sqlhtml.py", line 905, in accepts > hideerror=hideerror, > File "C:\google_appengine\web2py\gluon\html.py", line 1512, in accepts > status = self._traverse(status,hideerror) > File "C:\google_appengine\web2py\gluon\html.py", line 522, in _traverse > newstatus = c._traverse(status,hideerror) and newstatus > File "C:\google_appengine\web2py\gluon\html.py", line 522, in _traverse > newstatus = c._traverse(status,hideerror) and newstatus > File "C:\google_appengine\web2py\gluon\html.py", line 522, in _traverse > newstatus = c._traverse(status,hideerror) and newstatus > File "C:\google_appengine\web2py\gluon\html.py", line 522, in _traverse > newstatus = c._traverse(status,hideerror) and newstatus > File "C:\google_appengine\web2py\gluon\html.py", line 529, in _traverse > newstatus = self._validate() > File "C:\google_appengine\web2py\gluon\html.py", line 1300, in _validate > (value, errors) = validator(value) > File "C:\google_appengine\web2py\gluon\validators.py", line 493, in __call__ > rows = self.dbset(field == value).select(limitby=(0, 1)) > File "C:\google_appengine\web2py\gluon\contrib\gql.py", line 732, in select > self._db['_lastsql'] = 'SELECT WHERE %s' % self.where > File "C:\google_appengine\web2py\gluon\contrib\gql.py", line 611, in __str__ > return ' AND '.join([str(filter) for filter in self.filters]) > UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in > position 12: ordinal not in range(128) > > Error snapshot *Detailed traceback description* > > - Exception: <type 'exceptions.UnicodeEncodeError'>('ascii' codec can't > encode character u'\xe9' in position 12: ordinal not in range(128)) > *Exception instance attributes* > - __getslice__: <method-wrapper '__getslice__' of > exceptions.UnicodeEncodeError object at 0x03909D88> > - encoding: 'ascii' > - __str__: <method-wrapper '__str__' of exceptions.UnicodeEncodeError > object at 0x03909D88> > - __getattribute__: <method-wrapper '__getattribute__' of > exceptions.UnicodeEncodeError object at 0x03909D88> > - __dict__: {} > - __sizeof__: <built-in method __sizeof__ of > exceptions.UnicodeEncodeError object at 0x03909D88> > - __init__: <method-wrapper '__init__' of > exceptions.UnicodeEncodeError object at 0x03909D88> > - __setattr__: <method-wrapper '__setattr__' of > exceptions.UnicodeEncodeError object at 0x03909D88> > - __reduce_ex__: <built-in method __reduce_ex__ of > exceptions.UnicodeEncodeError object at 0x03909D88> > - end: 13 > - __new__: <built-in method __new__ of type object at 0x1E1F6A08> > - __format__: <built-in method __format__ of > exceptions.UnicodeEncodeError object at 0x03909D88> > - __class__: <type 'exceptions.UnicodeEncodeError'> > - start: 12 > - __doc__: 'Unicode encoding error.' > - object: u'nombre = caf\xe9' > - __getitem__: <method-wrapper '__getitem__' of > exceptions.UnicodeEncodeError object at 0x03909D88> > - __setstate__: <built-in method __setstate__ of > exceptions.UnicodeEncodeError object at 0x03909D88> > - __reduce__: <built-in method __reduce__ of > exceptions.UnicodeEncodeError object at 0x03909D88> > - args: ('ascii', u'nombre = caf\xe9', 12, 13, 'ordinal not in > range(128)') > - reason: 'ordinal not in range(128)' > - __subclasshook__: <built-in method __subclasshook__ of type object > at 0x1E1F6A08> > - __unicode__: <built-in method __unicode__ of > exceptions.UnicodeEncodeError object at 0x03909D88> > - __delattr__: <method-wrapper '__delattr__' of > exceptions.UnicodeEncodeError object at 0x03909D88> > - __repr__: <method-wrapper '__repr__' of > exceptions.UnicodeEncodeError object at 0x03909D88> > - __hash__: <method-wrapper '__hash__' of > exceptions.UnicodeEncodeError object at 0x03909D88> > - Python 2.6.4: C:\Python26\python.exe > > File C:\google_appengine\web2py\gluon\restricted.py in restricted at line > 186 [ code | arguments | variables ] > *Function argument list: (code=<code object <module> at 037B1D10, file > "C:\goog...welcome2/controllers/appadmin.py:insert", line 7>, > environment={'A': <class 'gluon.html.A'>, 'Auth': <class > 'gluon.tools.Auth'>, 'B': <class 'gluon.html.B'>, 'BEAUTIFY': <class > 'gluon.html.BEAUTIFY'>, 'BODY': <class 'gluon.html.BODY'>, 'BR': <class ' > gluon.html.BR'>, 'CENTER': <class 'gluon.html.CENTER'>, 'CLEANUP': <class > 'gluon.validators.CLEANUP'>, 'CODE': <class 'gluon.html.CODE'>, 'CRYPT': > <class 'gluon.validators.CRYPT'>, ...}, > layer=r'C:\google_appengine\web2py\applications\welcome2/controllers/appadmin.py') > * > > 181. > 182. > 183. > 184. > 185. > 186. > > 187. > 188. > 189. > 190. > > if type(code) == types.CodeType: > ccode = code > else: > ccode = compile2(code,layer) > > exec ccode in environment > > except HTTP: > raise > except Exception: > # XXX Show exception in Wing IDE if running in debugger > > - environment: {'A': <class 'gluon.html.A'>, 'Auth': <class > 'gluon.tools.Auth'>, 'B': <class 'gluon.html.B'>, 'BEAUTIFY': <class > 'gluon.html.BEAUTIFY'>, 'BODY': <class 'gluon.html.BODY'>, 'BR': <class ' > gluon.html.BR'>, 'CENTER': <class 'gluon.html.CENTER'>, 'CLEANUP': <class > 'gluon.validators.CLEANUP'>, 'CODE': <class 'gluon.html.CODE'>, 'CRYPT': > <class 'gluon.validators.CRYPT'>, ...} > - ccode: <code object <module> at 037B1D10, file > "C:\goog...welcome2/controllers/appadmin.py:insert", line 7> > > File > C:\google_appengine\web2py\applications\welcome2\controllers\appadmin.py:insert > in <module> at line 410 [ code | arguments | variables ] > *Function argument list: ()* > File C:\google_appengine\web2py\gluon\globals.py in <lambda> at line 96 [ > code | arguments | variables ] > *Function argument list: (f=<function insert at 0x03920430>)* > > 91. > 92. > 93. > 94. > 95. > 96. > > 97. > 98. > 99. > 100. > > self.flash = '' # used by the default view layout > self.meta = Storage() # used by web2py_ajax.html > self.menu = [] # used by the default view layout > self.files = [] # used by web2py_ajax.html > self._vars = None > self._caller = lambda f: f() > > self._view_environment = None > self._custom_commit = None > self._custom_rollback = None > > - self: undefined > - f: <function insert at 0x03920430> > > File > C:\google_appengine\web2py\applications\welcome2\controllers\appadmin.py:insert > in insert at line 125 [ code | arguments | variables ] > *Function argument list: ()* > File C:\google_appengine\web2py\gluon\sqlhtml.py in accepts at line 905 [ > code | arguments | variables ] > *Function argument list: (self=<gluon.sqlhtml.SQLFORM object at 0x0391FCD0>, > request_vars=<Storage {'nombre': 'caf\xc3\xa9', '_formkey': > '...67-5eaba8467eb6', '_formname': 'carrera_create'}>, session=<Storage > {'_formkey[pais_create]': '44d0efc5-698...reate]': > 'dc2d6d30-5dd3-4235-9267-5eaba8467eb6'}>, formname='carrera_create', > keepvalues=False, onvalidation=None, dbio=True, hideerror=False)* > > 900. > 901. > 902. > 903. > 904. > 905. > > 906. > 907. > 908. > 909. > > request_vars, > session, > formname, > keepvalues, > onvalidation, > hideerror=hideerror, > > ) > > if not ret and self.record and self.errors: > for key in self.errors.keys(): > > - hideerror: False > > File C:\google_appengine\web2py\gluon\html.py in accepts at line 1512 [ > code | arguments | variables ] > *Function argument list: (self=<gluon.sqlhtml.SQLFORM object at 0x0391FCD0>, > vars=<Storage {'nombre': 'caf\xc3\xa9', '_formkey': '...67-5eaba8467eb6', > '_formname': 'carrera_create'}>, session=<Storage {'_formkey[pais_create]': > '44d0efc5-698...reate]': 'dc2d6d30-5dd3-4235-9267-5eaba8467eb6'}>, > formname='carrera_create', keepvalues=False, onvalidation=None, > hideerror=False)* > > 1507. > 1508. > 1509. > 1510. > 1511. > 1512. > > 1513. > 1514. > 1515. > 1516. > > if self.session and self.session.get('_formkey[%s]' > % self.formname, None) != self.request_vars._formkey: > status = False > if self.formname != self.request_vars._formname: > status = False > status = self._traverse(status,hideerror) > > if status and onvalidation: > if isinstance(onvalidation, (list, tuple)): > [f(self) for f in onvalidation] > else: > > - status: True > - self: <gluon.sqlhtml.SQLFORM object at 0x0391FCD0> > - self._traverse: <bound method SQLFORM._traverse of > <gluon.sqlhtml.SQLFORM object at 0x0391FCD0>> > - hideerror: False > > File C:\google_appengine\web2py\gluon\html.py in _traverse at line 522 [ > code | arguments | variables ] > *Function argument list: (self=<gluon.sqlhtml.SQLFORM object at 0x0391FCD0>, > status=True, hideerror=False)* > > 517. > 518. > 519. > 520. > 521. > 522. > > 523. > 524. > 525. > 526. > > c.errors = self.errors > c.latest = self.latest > c.session = self.session > c.formname = self.formname > c['hideerror']=hideerror > newstatus = c._traverse(status,hideerror) and newstatus > > # for input, textarea, select, option > # deal with 'value' and 'validation' > > - status: True > - newstatus: True > - c: <gluon.html.TABLE object at 0x03923BB0> > - hideerror: False > - c._traverse: <bound method TABLE._traverse of <gluon.html.TABLE object > at 0x03923BB0>> > > File C:\google_appengine\web2py\gluon\html.py in _traverse at line 522 [ > code | arguments | variables ] > *Function argument list: (self=<gluon.html.TABLE object at 0x03923BB0>, > status=True, hideerror=False)* > > 517. > 518. > 519. > 520. > 521. > 522. > > 523. > 524. > 525. > 526. > > c.errors = self.errors > c.latest = self.latest > c.session = self.session > c.formname = self.formname > c['hideerror']=hideerror > newstatus = c._traverse(status,hideerror) and newstatus > > # for input, textarea, select, option > # deal with 'value' and 'validation' > > - status: True > - newstatus: True > - c: <gluon.html.TR object at 0x03923C50> > - hideerror: False > - c._traverse: <bound method TR._traverse of <gluon.html.TR object at > 0x03923C50>> > > File C:\google_appengine\web2py\gluon\html.py in _traverse at line 522 [ > code | arguments | variables ] > *Function argument list: (self=<gluon.html.TR object at 0x03923C50>, > status=True, hideerror=False)* > > 517. > 518. > 519. > 520. > 521. > 522. > > 523. > 524. > 525. > 526. > > c.errors = self.errors > c.latest = self.latest > c.session = self.session > c.formname = self.formname > c['hideerror']=hideerror > newstatus = c._traverse(status,hideerror) and newstatus > > # for input, textarea, select, option > # deal with 'value' and 'validation' > > - status: True > - newstatus: True > - c: <gluon.html.TD object at 0x03923BF0> > - hideerror: False > - c._traverse: <bound method TD._traverse of <gluon.html.TD object at > 0x03923BF0>> > > File C:\google_appengine\web2py\gluon\html.py in _traverse at line 522 [ > code | arguments | variables ] > *Function argument list: (self=<gluon.html.TD object at 0x03923BF0>, > status=True, hideerror=False)* > > 517. > 518. > 519. > 520. > 521. > 522. > > 523. > 524. > 525. > 526. > > c.errors = self.errors > c.latest = self.latest > c.session = self.session > c.formname = self.formname > c['hideerror']=hideerror > newstatus = c._traverse(status,hideerror) and newstatus > > # for input, textarea, select, option > # deal with 'value' and 'validation' > > - status: True > - newstatus: True > - c: <gluon.html.INPUT object at 0x0391FE30> > - hideerror: False > - c._traverse: <bound method INPUT._traverse of <gluon.html.INPUT object > at 0x0391FE30>> > > File C:\google_appengine\web2py\gluon\html.py in _traverse at line 529 [ > code | arguments | variables ] > *Function argument list: (self=<gluon.html.INPUT object at 0x0391FE30>, > status=True, hideerror=False)* > > 524. > 525. > 526. > 527. > 528. > 529. > > 530. > 531. > 532. > 533. > > # for input, textarea, select, option > # deal with 'value' and 'validation' > > name = self['_name'] > if newstatus: > newstatus = self._validate() > > self._postprocessing() > elif 'old_value' in self.attributes: > self['value'] = self['old_value'] > self._postprocessing() > > - newstatus: True > - self: <gluon.html.INPUT object at 0x0391FE30> > - self._validate: <bound method INPUT._validate of <gluon.html.INPUT > object at 0x0391FE30>> > > File C:\google_appengine\web2py\gluon\html.py in _validate at line 1300 [ > code | arguments | variables ] > *Function argument list: (self=<gluon.html.INPUT object at 0x0391FE30>)* > > 1295. > 1296. > 1297. > 1298. > 1299. > 1300. > > 1301. > 1302. > 1303. > 1304. > > requires = self['requires'] > if requires: > if not isinstance(requires, (list, tuple)): > requires = [requires] > for validator in requires: > (value, errors) = validator(value) > > if errors != None: > self.vars[name] = value > self.errors[name] = errors > break > > - errors: undefined > - value: 'caf\xc3\xa9' > - validator: <gluon.validators.IS_NOT_IN_DB object at 0x0391DC70> > > File C:\google_appengine\web2py\gluon\validators.py in __call__ at line 493[ > code | arguments | variables ] > *Function argument list: (self=<gluon.validators.IS_NOT_IN_DB object at > 0x0391DC70>, value='caf\xc3\xa9')* > > 488. > 489. > 490. > 491. > 492. > 493. > > 494. > 495. > 496. > 497. > > return (value, self.error_message) > if value in self.allowed_override: > return (value, None) > (tablename, fieldname) = str(self.field).split('.') > field = self.dbset._db[tablename][fieldname] > rows = self.dbset(field == value).select(limitby=(0, 1)) > > if len(rows) > 0: > if isinstance(self.record_id, dict): > for f in self.record_id: > if str(getattr(rows[0], f)) != str(self.record_id[f]): > > - rows: undefined > - self.dbset: <gluon.contrib.gql.Set object at 0x0391DE30> > - self: <gluon.validators.IS_NOT_IN_DB object at 0x0391DC70> > - ).select: undefined > - value: 'caf\xc3\xa9' > - limitby: undefined > - field: <gluon.contrib.gql.Field object at 0x0391DDB0> > > File C:\google_appengine\web2py\gluon\contrib\gql.py in select at line 732[ > code | arguments | variables ] > *Function argument list: (self=<gluon.contrib.gql.Set object at 0x03923DD0>, > *fields=['id', 'nombre'], **attributes={'limitby': (0, 1)})* > > 727. > 728. > 729. > 730. > 731. > 732. > > 733. > 734. > 735. > 736. > > Always returns a Rows object, even if it may be empty > cache attribute ignored on GAE > """ > > (items, tablename, fields) = self._select(*fields, **attributes) > self._db['_lastsql'] = 'SELECT WHERE %s' % self.where > > rows = [] > for item in items: > new_item = [] > for t in fields: > > - self: <gluon.contrib.gql.Set object at 0x03923DD0> > - self._db: <SQLDB {'auth_permission': <Table {'ALL': > <gluon...gluon.contrib.gql.Field object at 0x0391DB10>}>}> > - self.where: <gluon.contrib.gql.Query object at 0x03923DB0> > > File C:\google_appengine\web2py\gluon\contrib\gql.py in __str__ at line 611[ > code | arguments | variables ] > *Function argument list: (self=<gluon.contrib.gql.Query object at > 0x03923DB0>)* > > 606. > 607. > 608. > 609. > 610. > 611. > > 612. > 613. > 614. > 615. > > raise RuntimeError, 'NOT (... IN ...) is not supported on GAE' > new_op = > {'<':'>','>':'<','=':'!=','!=':'=','<=':'>=','>=':'<='}[filter.op] > return Query(filter.left, new_op, filter.right) > > def __str__(self): > return ' AND '.join([str(filter) for filter in self.filters]) > > class Set(gluon.sql.Set): > > - builtinstr: <type 'str'> > - filter: <gluon.contrib.gql.Filter instance at 0x0391AC38> > - self: <gluon.contrib.gql.Query object at 0x03923DB0> > - self.filters: [<gluon.contrib.gql.Filter instance at 0x0391AC38>] > > -- > Díaz Luis > TSU Analisis de Sistemas > Universidad de Carabobo