python 2.7 - Django Model __unicode__ raising exception when logging -
i have model class looks following:
class address(models.model): # taking length of address/city fields existing userprofile model address_1 = models.charfield(max_length=128, blank=false, null=false) address_2 = models.charfield(max_length=128, blank=true, null=true) address_3 = models.charfield(max_length=128, blank=true, null=true) unit = models.charfield(max_length=10, blank=true, null=true) city = models.charfield(max_length=128, blank=false, null=false) state_or_province = models.foreignkey(stateorprovince) postal_code = models.charfield(max_length=20, blank=false, null=false) phone = models.charfield(max_length=20, blank=true, null=true) is_deleted = models.booleanfield(default=false, null=false) def __unicode__(self): return u"{}, {} {}, {}".format( self.city, self.state_or_province.postal_abbrev, self.postal_code, self.address_1)
the key being __unicode__
method. have customer model has foreign key field table, , doing following logging:
log.debug(u'generated customer [{}]'.format(vars(customer)))
this works fine, if address_1 field value contains non ascii value,
57562 vån ness hwy
the system throwing following exception:
unicodedecodeerror: 'ascii' codec can't decode byte 0xc3 in position 345: ordinal not in range(128)
i tracked down strange method in django/db/models/base.py:
def __repr__(self): try: u = six.text_type(self) except (unicodeencodeerror, unicodedecodeerror): u = '[bad unicode data]' return force_str('<%s: %s>' % (self.__class__.__name__, u))
as can see, method getting called force_str, doesn't handled correctly. bug? if unicode getting called on object, shouldn't in unicode?
according docs, when python object passed argument '{}'.format(obj)
,
a general convention empty format string ("") [within "{}"] produces same result if had called str() on value.
this means you're calling str(vars(customer))
, , vars(customer)
returns dict
.
calling str()
on dict
call repr()
on keys , values because otherwise you'd ambiguous output (eg str(1) == str('1') == '1'
repr(1) == '1' , repr('1') == '"1"'
(see difference between __str__ , __repr__ in python)
therefore repr()
still being called on address
, returns string.
now returning unicode repr()
not allowed in python 2 - https://stackoverflow.com/a/3627835/648176, you'll need either override __str__()
in model make handle decoding ascii (django docs), or like:
string_dict = {str(k): str(v) (k, v) in vars(customer).items()} log.debug(u'generated customer [{}]'.format(string_dict))
Comments
Post a Comment